Laden...

SerialPort Event löst manchmal nicht aus

Erstellt von Häuptling vor 7 Jahren Letzter Beitrag vor 7 Jahren 2.586 Views
H
Häuptling Themenstarter:in
4 Beiträge seit 2016
vor 7 Jahren
SerialPort Event löst manchmal nicht aus

HI Leute,

ich verzweifle an der serial.Read() Methode.
Ich habe einen Event erstellt, um ankommende 16 Bytes in ein Buffer-Array zu überführen.
Diese 16 Bytes stehen jeweils für eine Messung eines EvalBoards. Sie sind binär codiert und werden anschließend in weiterverarbeitet.
Leider löst das Event manchmal für die letzten Messwerte nicht aus, weshalb einige Messdaten fehlen. Manchmal nur einer, öfter auch mal mehr.
Sende ich dem Eval anschließend ein Reset Befehl und starte die Messung erneut, werden mir als erstes die Bytes der vorherigen Messung gesendet.
Am Eval kann es nicht liegen, da es reseted wurde. Ich gehe eher davon aus, dass die ankommenden Bytes von dem Event übersehen wurden.

Hier der betreffende Programmausschnitt:

serialPort1.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);

 private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)// Routine, if data is received
        {
            SerialPort sp = (SerialPort)sender;            
            byte[] indata = new byte[16];
            sp.Read(indata, 0, 16);
......
         }

Ich hoffe mir kann zu dem Thema jemand helfen.

Vielen Dank und Grüße

Das Gegenteil von gut ist gut gemeint!

1
124 Beiträge seit 2012
vor 7 Jahren

Hallo,

ich hatte das gleiche Problem. Mich würde eine gute Lösung auch interessieren falls es die gibt.

Ich habe es für ein kleine Projekt so gemacht, dass ich am ende vom Event abgefragt habe ob im Puffer(serialPort.BytesToRead()) noch etwas ist und dann nochmal das Event aufgerufen. Aber das ist glaube ich ehr die unschöne Lösung.

C
2.121 Beiträge seit 2010
vor 7 Jahren

Du liest immer 16 Byte, weißt aber nicht ob gerade 16 da sind. Entweder du liest weniger und hast dann eine unvollständige Nachricht, oder es sind mehr Bytes da die du dann ignorierst.
Read sollte eigentlich die Anzahl tatsächlich gelesener Bytes zurückgeben, damit kannts du entscheiden wie es weitergeht.

709 Beiträge seit 2008
vor 7 Jahren

Hi!
Das Event löst nicht jedes Mal für die 16 Byte aus, da (wenn ich das richtig in Erinnerung habe) die eingehenden Daten intern gepuffert werden.
Dadurch ist dann auch nicht sichergestellt, dass jedes Mal deine 16 Byte im Event ankommen. Es können mal mehr und mal weniger sein.

H
Häuptling Themenstarter:in
4 Beiträge seit 2016
vor 7 Jahren

Vielen vielen Dank.

Ich lese jetzt erst mal alle anstehenden Bytes in einen Buffer, bevor ich diesen wieder in 16 Bytestücke zerteile.

Viele Grüße 8) 😁 👍

Das Gegenteil von gut ist gut gemeint!

D
985 Beiträge seit 2014
vor 7 Jahren

Es würde schon reichen, wenn du einfach so lange den Buffer abfragst, bis weniger als 16 Bytes im Buffer enthalten sind.


while ( port.BytesToRead >= 16 )
{
    var buffer = new byte[16]();
    port.Read( buffer, 0, 16 );

    // Daten sind jetzt komplett im Buffer    
    // und können behandelt werden
}

Weiterhin kann man auch SerialPort.ReceivedBytesThreshold auf 16 setzen, dann wird der DataReceived Event nur gefeuert, wenn mindestens 16 Bytes im Buffer vorhanden sind.

Generell würde ich mir eine Klasse/Interface bauen, die intern dann mit einem SerialPort arbeitet und über ein Event nur komplette Nachrichten rausgibt. So eine Klasse kann man für den Test dann auch gut mocken ohne den SerialPort direkt bemühen zu müssen.

888 Beiträge seit 2007
vor 7 Jahren

Und das hier könnte man auch mal probieren...

Template SerialPort

771 Beiträge seit 2009
vor 7 Jahren

@JoeTempes: Vllt. könntest du bei deinem Link noch mal eine kurze Beschreibung voranstellen (denn alleine aus dem Thread Titel und der Auflistung geht das nicht so hervor)?