Hallo, Mir ist für folgendes Problem leider kein besserer Titel eingefallen. Ich kommuniziere über die serielle Schnittstelle mit einem angeschlossenen Gerät. Die eingehenenden Daten werden wie in dem Beispiel hier auf der Seite [1] eingelesen. Nach Absenden eines Befehls an das Gerät wird dieser immer mit einer Antwort quitiert. Funktioniert auch alles eigentlich wie es soll. Nur bekomme ich meine Antowrt mal in zwei Paketen, mal in einem Paket. Mit Paket meine ich dass der Eventhandler für DATA_AVAILABLE wohl zweimal aufgerufen wird. Manchmal werden dann die 10 Bytes die als Antwort kommen im ersten Aufruf gelesen, aber macnhmal 2 Byte im ersten und die restlichen 8 im zweiten. Oder 8 im ersten und die restlichen 2 im zweiten. Hat jemand spontan eine Idee woran das liegen könnte? [1] http://www.mikrocontroller.net/articles/Serielle_Schnittstelle_unter_Java Gruß Frank
Bei read kann man doch angeben, wie viele Byte er lesen soll. Möglicherweise muss man noch irgendwo Timeouts anpassen.
> Hat jemand spontan eine Idee woran das liegen könnte?
Vermutlich, weil das eben einfach so ist. Das System weiß ja nicht, daß
deine Antwort genau 10 Bytes groß ist. Du bekommst halt Daten, wenn es
meint, seinen Puffer leeren zu müssen.
> Bei read kann man doch angeben, wie viele Byte er lesen soll. Also meine Lesebuffer ist 255 Byte gross. Habe jetzt testweise einfach mal diese Grösse verwendet, da keine Antwort gröser sein wird als 255. Diese Anzahl von Bytes versuche ich dann zu lesen. byte[] receiveBuffer = new byte[255]; while (inputStream.available() > 0) { numBytes = inputStream.read(receiveBuffer, 0, receiveBuffer.length); } } > Möglicherweise muss man noch irgendwo Timeouts anpassen. Kurioserweise scheint eine "Warteschleife" vor dem Lesen das Problem zu beheben. Finde ich jetzt aber irgendwie ziemlich unschön und verschafft nicht gerade ein gutes Gefühl. An welcher Stelle können denn "irgendwo Timeouts angepasst" werden. for (int i = 0; i < 100000; i++){ for (int j = 0; j < 1000; j++){} } > Vermutlich, weil das eben einfach so ist. Ich weiss jetzt in dem speziellen Fall eben dass die Antwort 10 Byte gross sein muss. WIe oben zu lesen ist, ist der Buffer schon grösser.
Du solltes Dir mal Gedanken über ein (einfaches) Übertragungs-Protokoll machen. Einfach nur irgendwelche Bytes über die Leitung übertragen funktioniert schon. Aber wie Rolf schreibt, für das System sind das einfach nur Bytes, die es in beliebigen Portionen dem Aufrufer zur Verfügung stellt. Es würde Dir schon helfen, wenn zu zunächst ein definierte Start-Zeichen und am Ende ein Stop-Zeichen sendest. Die empfangenen Daten pufferst Du über Deinen SerialPort-Event-Handler zwischen und erzeugtst ein eigenes Event, wenn eine Nachricht vollständig empfangen wurde. Alles ziemlich simpel... Gruß Markus
Wenn Du Dir übrigens mal die Doku zu InputStream.Read aus Java-Doc zu Gemüte führst, wirst Du auf eine Antwort zu Deiner Eingangsfrage stoßen. Die "Lösung" mit einer Warteschleife (mir rollt es die Fußnägel auf!!!) ist keine. Das klappt mehr oder weniger zufällig. Die einzige saubere Lösung ist das Zwischenpuffern im Receive-Event-Handler, weil die serielle Übertragung so langsam ist, daß die ComPort-Software nicht weiß, ob Dein Paket schon übertragen ist und halt mal das zur Verfügung stellt, was sie bereits empfangen hat. Gruß Markus
Erstmal Danke für deine ausführlichen Antworten. Die "Lösung" mit der Schleife soll ja keine Lösung darstellen, sondern war nur ein Test um rauszubekommen was da vor sich geht. Ich werde mir das Ganze mal nochmal durch den Kopf gehen lassen. Aber ich ging auch irgendwie davon aus dass InputStream.Read mir die Antwort durchgehend in "einem Fluss" liefert. Wenn das natürlich nicht der Fall ist, dann macht ja im Prinzip wirklich nur ein einfaches Protokoll Sinn, in dem dann definierte Anfangs- und Endzustände herrschen, bzw. ich diese dann auch überprüfen kann. Ich denke ihr habt mir aufjedenfall einen Weg in die richtige Richtung gezeigt. Werde mir mal wieder ein paar Gedanken zu dem Thema machen. Vorerst Danke euch beiden.
Musst Du auf Geschwindigkeit optimieren? Falls ja: Du kommst um das Puffern wohl nicht herum. Falls nein: Mach Dir die Sache doch einfach! Rechne aus, wie lange die 10 Bytes brauchen, um übertragen zu werden. Verdopple die Zeit. Und warte solange, bevor Du read aufrufst...
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.