PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [Java] RXTX Problem


Stormscud
2011-06-14, 14:52:56
Hallo liebe Community!

Ich schreibe zur Zeit an einem Programm, dass die Messdaten eines Messverstärkers aufbereitet. Mit dem PC verbunden wird das ganze per RS232 und USB-RS232-Konverter.

Als Schnittstellenbibliothek nutze ich RXTX (2.1.7), Betriebssystem ist Windows XP. Entwicklungsumgebung NetBeans 7.

Nun u meinem Problem. Der Messverstärker wird mit ASCII Codes angesprochen. Zum Testen nehme ich immer "ID", damit erhalte ich die Gerätekennung des Messverstärkers. Allerdings bekomme ich immer nur nach ca. 5 bis 10 Anfragen eine Antwort vom Messverstärker. Auch zu sehen am USB-RS232-Konverter (eine Leuchte für Input, eine für Output).

Testweise hab ich auch mal das Programm "Advanced Serial Port Monitor" probiert. Dort klappt die Sache in ca. 95% der Anfragen, zufriedenstellend erstmal. Nur eben bei meinen Programmen nicht. Ich versteh nicht wo das Problem liegen könnte. Die Schnittstelleneinstellungen passen so wie sie standardmäßig auch im Messverstärker eingestellt sind (ebenso im Gerätemanager).

Hierfür habe ich 2 verschiedene Quelltexte verwendet:
1.: http://rxtx.qbang.org/wiki/index.php/Two_way_communcation_with_the_serial_port
(nur zum Testen)
Anmerkung zur Quelltextänderung:

public void run ()
{
try
{
int c = 1000;
String s = "ID";
byte[] byteArray new byte[128];
byteArray = s.getBytes();
while ( ( c > -1 )
{
this.out.write(byteArray);
//this.out.flush(); auch keine Verbesserung
c--;
//try { Datenanfrage alle 20ms, keine Änderung des Ergebnis
// Thread.sleep(20);
//} catch (InterruptedException ex) {
// Logger.getLogger(Rs232.class.getName()).log(Level.SEVERE, null, ex);
//}
}
}
catch ( IOException e )
{
e.printStackTrace();
}
}


2.: http://www.mikrocontroller.net/articles/Serielle_Schnittstelle_unter_Java
Dieser Quelltext wird abgewandelt in einer GUI verwendet.

Also egal, ob ich eventbasiert (nur 1 Hauptthread, auch wenn man das nicht macht ;)) oder threadbasiert arbeite, beide Quelltexte liefern das gleiche Ergebnis.

Der Messverstärker ist übrigens nur mit den Kabeln für die Daten (Rx, Tx) und der Masse verbunden.

Ist es mögliche, dass die Byte-Konvertierung des Strings ("ID") hier dazwischenfunkt? Oder gibt es andere Lösungsvorschläge.

Vielen Dank schon mal im Voraus :)

Gast
2011-06-14, 20:01:38
Erst was kosmetisches:
Du initialisierst ein neues Byte-Array mit der Länge 128 und überschreibst es gleich in der nächsten Zeile mit der Ausgabe von getBytes().
Java ist nicht C. :) Du musst nicht einen Speicherbereich allokieren, um ihn zu verwenden, du kannst direkt den Rückgabewert benutzen.

Dann:
flush() sollte auf jeden Fall drinbleiben, denn nur dieser Aufruf garantiert, dass das Kommando auch an dieser Stelle übertragen wird.


Aber leider kann ich dir nicht sagen, ob und wo jetzt ein Fehler ist. Evtl. sind die 20ms zu kurz!?
Evtl. musst du noch eine Art Stoppzeichen an den Befehl hängen (z.B. "\r\n")?

Die Bytekonvertierung verlässt sich auf das Default-Encoding, welches auch immer das sein mag. Du fährst hier sicherer, indem du das korrekte fest angibst.
http://download.oracle.com/javase/1,5.0/docs/api/java/lang/String.html#getBytes(java.lang.String)
Falls hier aber das Problem wäre, dürfte deine Anfrage nie Erfolg haben. Dass du "nur manchmal" Probleme hast, deutet eher auf ein Problem in der Übertragung hin.

Gast
2011-06-14, 20:06:06
ÄÄhhh das sehe ich jetzt erst:
Wo fragst du denn das Ergebnis ab?
Dein Programm hat nur eine Ausgabe bei einer InterruptedException, die dürfte aber so gut wie nie fliegen. (Falls diese fliegt sollte aber auch die Schleife nicht weiterlaufen, besser du machst sie zur IOException dazu).

Gast
2011-06-14, 21:35:30
Erst was kosmetisches:
Aber leider kann ich dir nicht sagen, ob und wo jetzt ein Fehler ist. Evtl. sind die 20ms zu kurz!?

Würde ich als Erstes auch von ausgehen.

Stormscud
2011-06-14, 23:03:52
1. Also der Quellcode den ich oben mit reingeschrieben habe ist nur die Änderung, welche ich im Quellcode vom ersten Link gemacht hab. Der rest ist identisch. Sprich die Daten werden auch abgefangen.

2. Dass die Pause zu kurz ist kann leider ausgeschlossen werden, da ich bereit ständiges senden, sowie Pausenabstände von 10, 20, 30, 40, 50, 60 ,70, 80, 90, 100, 200, 300, 400, 500 und 1000ms getestet habe bei jeweils 100 Anfragen. Hab dann nachgezählt wieviele Antworten ich erhalten habe und welche davon verwertbar waren. Im Mittel schwankt hier Erfolgsrate eben zwischen 5 und 15 Antworten auf 100 Anfragen.

3. Ich hab auch schon direkt dezimal nach ASCII Tabelle den Code gesendet. sprich byte[] b = {73, 68};
Da hat sich leider auch nix geändert.

4. Diese Interrupted Exception hat NetBeans hinzugefügt, da Thread.sleep hier in eine Try-Catch Anweisung eingebettet werden muss. Also das war der Vorschlag von NetBeans wie ich den Fehler beheben könnte. Die Ergebnisabfrage erfolgt woanders, siehe Quelltext vom ersten Link.

5. Das mit dem Byte Array wusste ich nicht^^ danke.

Falls gewünscht kann ich morgen nochmal den ganzen Quelltext hochladen. Aber große Änderungen sind halt wie gesagt nicht drin.

Stormscud
2011-06-15, 11:37:55
Also es war tatsächlich \r\n :freak: In der Doku vom Messverstärker wird auch nach jeder Eingabe ein Entersymbol mit angehangen. Oh man, das hab ich wohl bisher immer schön ignoriert. Aber jetzt gehts :biggrin:

Gast
2011-06-15, 20:24:33
3. Ich hab auch schon direkt dezimal nach ASCII Tabelle den Code gesendet. sprich byte[] b = {73, 68};
Da hat sich leider auch nix geändert.
Wie geschrieben, das habe ich auch nicht als Problem erwartet. Es geht hier mehr um saubere Programmierung.
Wenn du dich vom System-Default-Encoding abhängig machst, nimmst du in Kauf, dass es auf bestimmten Systemen eben nicht geht.

4. Diese Interrupted Exception hat NetBeans hinzugefügt, da Thread.sleep hier in eine Try-Catch Anweisung eingebettet werden muss. Also das war der Vorschlag von NetBeans wie ich den Fehler beheben könnte. Die Ergebnisabfrage erfolgt woanders, siehe Quelltext vom ersten Link.
Die Exception wird üblicherweise geworfen, falls man von außen versucht das Programm zu beenden. Daher wäre es besser, den catch-Block zu der IOException dazuzupacken, damit man aus der Schleife draussen ist.
Ist mir klar, dass du die Schleife jetzt nicht mehr brauchst, aber es war evtl. nicht deine letzte InterruptedException. :)