Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
SerialPort Event löst manchmal nicht aus
Häuptling
myCSharp.de - Member



Dabei seit:
Beiträge: 4
Herkunft: Deutschland

Themenstarter:

SerialPort Event löst manchmal nicht aus

beantworten | zitieren | melden

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!
private Nachricht | Beiträge des Benutzers
123thomas
myCSharp.de - Member



Dabei seit:
Beiträge: 125

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
chilic
myCSharp.de - Experte



Dabei seit:
Beiträge: 2143

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
pinki
myCSharp.de - Member

Avatar #avatar-4072.jpg


Dabei seit:
Beiträge: 706
Herkunft: OWL

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
Häuptling
myCSharp.de - Member



Dabei seit:
Beiträge: 4
Herkunft: Deutschland

Themenstarter:

beantworten | zitieren | melden

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!
private Nachricht | Beiträge des Benutzers
Deaktiviertes Profil
myCSharp.de - Member



Dabei seit:
Beiträge: 996

beantworten | zitieren | melden

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.
Dieser Beitrag wurde 3 mal editiert, zum letzten Mal von Deaktiviertes Profil am .
private Nachricht | Beiträge des Benutzers
Joetempes
myCSharp.de - Member

Avatar #avatar-3309.jpg


Dabei seit:
Beiträge: 914
Herkunft: Germany

beantworten | zitieren | melden

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

Template SerialPort
private Nachricht | Beiträge des Benutzers
Cat
myCSharp.de - Member

Avatar #avatar-3070.jpg


Dabei seit:
Beiträge: 790

beantworten | zitieren | melden

@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)?
private Nachricht | Beiträge des Benutzers