Wann wird DataReceived-Ereignis ausgelöst? Problem beim Datenempfang

  • VB.NET

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von peterfido.

    Wann wird DataReceived-Ereignis ausgelöst? Problem beim Datenempfang

    Hallo, ich tüftele nun schon seit einiger Zeit an einem kleinen Programm herum, das auf den seriellen Port zugreift.

    Ich verwende Windows 7, Visual Basic 2010 Express und einen RS232-USB-Konverter.

    Alles konzentriert sich momentan auf die Frage, wann denn nun genau ein "DataReceived"-Ereignis ausgelöst wird.

    Die Microsoft-Hilfe ist hier auch nicht besonders aussagekräftig, da heißt es: "DataReceived event is not guaranteed to be raised for every byte received.">Das DataReceived-Ereignis wird nicht unbedingt für jedes empfangene Byte ausgelöst."

    Tja, wann denn nun? :) Mir gehen immer Daten verloren, wenn ich versuche, einen String einzulesen, dessen Ende aus einer ASCII-000 besteht.

    Danke im Voraus...

    Der Stille Beobachter.

    Visual Basic-Quellcode

    1. Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
    2. ' Alle verfügbaren Bytes aus dem seriellen Eingabepuffer lesen
    3. For i = 0 To SerialPort1.BytesToRead
    4. Try
    5. StringBuffer &= SerialPort1.ReadByte
    6. StringBuffer &= ", "
    7. Catch ex As Exception
    8. MsgBox("Error receiving data", vbExclamation, "Error")
    9. End Try
    10. Next
    11. ' Stringende anhängen
    12. StringBuffer &= vbNull
    13. ' Neue Daten vorhanden
    14. NewSerialFrameReceived = 1
    15. End Sub
    Willkommen im Forum. :thumbup:

    stillerbeobachter schrieb:

    Mir gehen immer Daten verloren
    Dann solltest Du nicht mit Interrupt, sontern pollend mit Deiner Gegenstelle kommunizieren:

    VB.NET-Quellcode

    1. Me.SerialPort1.Write("bla")
    2. ' oder
    3. Me.SerialPort1.WriteLine("bla") ' Hier wird das bei der Initialisierung vorgegebene Zeilenende mit angehängt
    4. System.Threading.Thread.Sleep(100)
    5. Dim answer = Me.SerialPort1.ReadExisting()
    Kannst Du der Gegebstelle sagen, dass sie ein <CR> oder ein <CR><LF> als Ende senden soll?
    Ein angehängtes 0-Byte ist als Ende einer seriell übertragenen Message eher unüblich.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    stillerbeobachter schrieb:

    ist nicht änderbar.
    Liegt's vielleicht genau daran?
    Weiß ich nicht, so nen Fall hatte ich noch nicht.
    Probier mal, bei der Initialisierung diese 0 als Zeilenende vorzugeben (vor .Open()):

    VB.NET-Quellcode

    1. SerialPort1.NewLine = ChrW(0).ToString
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    stillerbeobachter schrieb:

    Das DataReceived-Ereignis wird nicht unbedingt für jedes empfangene Byte ausgelöst.
    ...
    Mir gehen immer Daten verloren
    Die beiden Dinge haben nichts miteinander zu tun.
    Die erste Aussage meint lediglich, dass das Event auch Blöcke von Daten liefern kann und nicht bei jedem einzelnen Byte geworfen wird.
    So kann es passieren, dass ein Event auch mal mehrere Bytes zusammenfasst.

    Wenn zwischendrin Daten verloren gehen, stimmt etwas mit dem Handshake nicht.
    Evtl. sogar falsch verkabelt.

    Unschönheiten:
    1) Du sprichst hart codiert Serialport1 an, anstatt den Parameter sender zu verwenden.
    2) StringBuffer &= SerialPort1.ReadByte Du kennst den Unterschied zwischen Byte und Char?
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    stillerbeobachter schrieb:

    Wie müsste ich da vorgehen?
    Bringt bei Deinem Problem nix, konzentriere Dich zunächst auf das eigentliche Problem.
    Hast Du dies mal probiert:

    VB.NET-Quellcode

    1. Me.SerialPort1.NewLine = ChrW(0)
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    data Received wird m.E. nach Threshold ausgelöst.

    Ich frage immer per Timer ab, ob was im Puffer ist und lese das dann aus. So habe ich im Endeffekt 2 Puffer. Einmal den "normalen" und einen selbst programmierten, wo ich erstmal alle ablege, was im "normalen" Puffer ist. Ist CR/LF vorhanden, dann wird von "meinem" alles bis CR/LF (in Deinem Fall dann chr(0)) in die Variable "Eingang" verschoben und abgearbeitet. Fehlt das ZeilenendeZeichen, dann wird einfach weitergemacht, bis es irgendwann eintrudelt.
    Gruß
    Peterfido

    Keine Unterstützung per PN!