Forum: PC-Programmierung Java RS232 Probleme bei Datenauswertung


von Stefan T. (stefan90)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe zur Datenauswertung von einem µC ein Java-Programm geschrieben, 
dass Daten über die serielle Schnittstelle einliest.

Hierfür habe ich eine Klasse SerialInterface und einen Thread, der mit 
dem µC kommuniziert (beide Klassen sind im Anhang).

Der µC sendet einen String gefolgt von einem '\r', sobald ich über RS232 
das Zeichen 'D' (für Data) gesendet habe. Im Konstuktor des Threads 
öffne ich den übergebenen Com-Port und starte dann den Thread, der das 
'D' an den µC schickt und den empfangenen String ausgibt.

Das Ganze funktioniert auch einwandfrei (zum Testen hab ich eine kleine 
main im Thread geschrieben) solange meine Platine mit dem µC an RS232 
angeschlossen ist. Ich verwende an meinem Notebook einen USB-RS232 
Wandler, da ich keine serielle Schnittstelle habe. Stecke ich die 
Platine ab, kommt nach 3s ein ReceiveTimeout (das ist gewollt, Thread 
läuft weiter und liefert wieder Werte, sobald Platine wieder 
angeschlossen ist.) Ein Problem ist es nur, wenn ich den USB-RS232 
Wandler abstecke, denn dann hängt sich der Thread auf.

Ich habe herausgefunden, dass der Thread in der Methode write() in 
SerialInterface hängen bleibt. Es passiert nun folgendes in der Methode 
write():
bw.write(s) wird normal ausgeführt, doch dann bei bw.flush() wird beim 
1. Durchlauf (sobald Wandler abgesteckt ist) eine IO-Exception geworfen. 
Beim nächsten Aufruf von write("D") wird bw.write(s) ausgeführt, doch 
bei bw.flush() bleibt das Programm hängen (keine Exception).

Das ist deshalb ein Problem, da ich den Thread nun nicht mehr beenden 
kann (sowhohl nicht mit setQuit() als auch nicht mit 
auswerteThread.interrupt(). In einer GUI habe ich aber einen Button 
"Auswertung Beenden", der quit setzt und mit join() wartet, bis sich der 
Thread beendet hat und somit auch den COM-Port wieder schließt. Doch 
join() bewirkt eine Endlosschleife, da sich der Thread ja nie beenden 
kann.

Gibt es eine andere Möglichkeit, einen Thread zu beenden oder wie kann 
ich dieses Problem vermeiden (außer Wanlder einfach nicht abstecken)?
Denn es ist nicht schön, wenn sich das Programm nicht mehr bedienen 
lässt sobald man den Wandler (etwa aus Unachtsamkeit) absteckt.

Danke für eure Antworten

mfg Stefan

von df311 (Gast)


Lesenswert?

da du ja eine io-exception bekommst, wenn der wandler abgesteckt ist 
kannst du ja im exception-handler die auswertung beenden bzw. 
unterbrechen.
sonst wird es nicht viele möglichketien geben, da du 
höchstwahrscheinlich keine möglichkeit hat, zu erfahren ob der wandler 
abgesteckt wurde oder ein andere io-fehler aufgetreten ist.

von Stefan T. (stefan90)


Lesenswert?

ja das wär schon möglich, aber toll wäre auch, wenn das Programm 
weiterlauft sobald der Wandler wieder angesteckt ist (falls das 
überhaupt machbar ist)

Den Thread auf eine andere Weise zu beenden (die immer funktioniert, 
egal ob Thread hängen bleibt) gibt es wohl nicht? Oder kann ich 
irgendwie den BufferedWriter so einstellen, dass der ein Timeout bekommt 
oder irgendwas damit sich da nix aufhängt?

mfg Stefan

von Markus V. (valvestino)


Lesenswert?

Hallo Stefan!

Das Behandeln der IO-Exception beim Flush ist aber die einzig (saubere) 
Möglichkeit, die Du hast.

Dazu solltest Du aber das Öffnen des COM-Ports vom Thread-Konstruktor in 
dessen run-Methode verlagern. Wenn eine IO-Exception auftritt, solltst 
Du im Exception-Handler den COM-Port wieder schließen, und dann per 
Schleife vor das Öffnen des COM-Ports springen. Dann versuchen, den 
COM-Port wieder zu öffnen. Wenn es hier wieder eine Exception gibt, 
entweder Thread.sleep und das Öffnen wiederholen oder irgendwann 
abbrechen.

So ganz allgemein solltest Du Dich mal mit dem Thema Exceptions 
auseinander setzen. Diese sind nämlich nicht da, um die Programmierer zu 
ärgern. Sie sollen diesen vielmehr eine Möglichkeit bieten, gezielt auf 
bestimmte Ausnahmezustände zu reagieren. Wie eben zum Beispiel das 
Abziehen eines USB-Gerätes.

Grüße aus Karlsruhe
Markus

von Stefan T. (stefan90)


Lesenswert?

Hallo,

ok das werde ich mal probieren. Ich habe aber auch festgestellt, dass 
sich bei Übergabe von COM4/COM5 (ist bei meinem Laptop ein Bluetooth- 
Kommunikationsanschluss) für den Thread sich zwar der COM-Port mit 
open() öffnen lässt, jedoch beim write() bzw flush() keine Exception 
kommt und somit das Programm sofort hängen bleibt. Das könnte evtl ein 
Treiberproblem sein, jedoch geht hier das Exception Handling auch nicht 
mehr. Was kann ich nun in diesem Fall machen?

Kann ich die IO-Exception hier immer als Abstecken des Wandlers 
interpretieren? Wie schon im Beitrag von df311 erwähnt wird mir wohl 
nicht viel anders übrig bleiben...

mfg Stefan

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.