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!
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.
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.
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.
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!
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.
Und das hier könnte man auch mal probieren...
@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)?