Serielle COM Daten auswerten?

  • VB.NET

Es gibt 31 Antworten in diesem Thema. Der letzte Beitrag () ist von grisu74.

    Serielle COM Daten auswerten?

    Hallo zusammen.

    Ich bekomme Daten von einem Gerät über eine Serielle COM-Schnittstelle.
    Die Daten würde ich gerne auswerten.
    Leider weis ich nicht wie ich die Daten trennen soll.
    Kommen 2 Befehle über die Schnittstelle kurz hintereinander macht das Probleme.

    Ich habe schon versucht im Internet zu stöbern. Leider kein Erfolg.

    Sendet die COM-Schnittstelle einen Befehl oder Bit den ich abfragen muss wenn ein Befehl fertig ist?

    Momentan probiere ich mit ReadLine und ReadExisting.

    Oder kennt jemand ein gutes Tutorial?

    Gruß Udo

    grisu74 schrieb:

    Leider weis ich nicht wie ich die Daten trennen soll.
    Da musst Du schon mal ein wenig weiter ausholen.
    Werden Strings gesendet / empfangen oder werden Bytes gesendet / empfangen?
    Haben die Befehle eine eindeutige Ende-Kennung?
    Bei strings und Endekennung kannst Du die Property .NewLine des SerialPorts auf diesen Wert setzen und dann mit .ReadLine und .WriteLine arbeiten.
    Was steht dazu in der Beschreibung der Gegenstelle?
    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!
    Hallo.

    Hier mal mein Code.
    Das Problem ist, das DataReceived feuert, bevor alle Daten da sind.
    Das macht es aber nicht immer.

    +CTSDSR: 141,262100105560571,1,262100103102049,1,16 8005 Das ist O.K. so!!!!!

    +CTSDSR: 141,262100105560571,
    1,262100103102049,1,16 8005
    Hier wurde DataReceived 2 mal ausgeführt.

    VB.NET-Quellcode

    1. Private Sub SerialPort1_DataReceived(sender As System.Object, e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
    2. ReceivedText(SerialPort1.ReadExisting())
    3. End Sub
    4. Private Sub ReceivedText(ByVal [text] As String) 'input from ReadExisting
    5. If Me.RichTextBox2.InvokeRequired Then
    6. Dim x As New SetTextCallback(AddressOf ReceivedText)
    7. Me.Invoke(x, New Object() {(text)})
    8. Else
    9. Me.RichTextBox2.Text &= [text] 'append text
    10. End If
    11. End Sub

    RodFromGermany schrieb:

    Haben die Befehle eine eindeutige Ende-Kennung?
    ...
    Was steht dazu in der Beschreibung der Gegenstelle?
    Ersetz mal das ReadExisting durch ReadLine.
    Und beantworte bitte meine Fragen.
    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!
    Hallo.

    Leider haben die Befehle keine eindeutige Ende-Kennung.
    Baudrate und Parameter habe ich laut Gerätehersteller eingestelt.
    Bei ReadLine zerhackt es mir die Daten noch mehr.

    UPDATE:
    Bei ReadLine funktioniert es besser. Leider wird beim 2. Befehl ein Teil verschluckt. am ende des Codes.
    Bei ​+CTSDSR: 141,262100105560571,1,262100103102049,1,16 8005
    Wird nur noch ​+CTSDSR: 141,262100105560571,1,262100103102049,1,16 ausgegeben.

    Gruß Udo

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „grisu74“ ()

    grisu74 schrieb:

    keine eindeutige Ende-Kennung
    Was sendest Du als Zeilen-Ende-Kennung?
    Was wird als Zeilen-Ende-Kennung erwartet?
    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!
    @grisu74 Schreib vor .Open() dies rein:

    VB.NET-Quellcode

    1. SerialPort1.NewLine = vbCrLf
    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!
    ​vbCrLf & "+CTSDSR: 141,262100105560571,1,262100103102049,1,16" & vbCrLf & "8003" & vbCrLf
    Das ist der gesammte String von der Schnittstelle.
    Leider wird er immernoch zerhackt.
    Und zwar irgendwo!!​vbCrLf & "+CTSDSR: 141,262100105560571,1,​262100103102049,1,16" & vbCrLf & "8003" & vbCrLf

    Gibt es eine externe Klasse eines Fremdanbieters?
    Der Gerätehersteller kann er sich das auch nicht erklären.

    Gruß

    grisu74 schrieb:

    zerhackt
    Nimmst Du .ReadLine?
    Da müssten die Zeilen einzeln kommen.
    =====
    Hast Du vom Gerätehersteller einen Demo-Code bekommen?
    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!
    Hallo.

    Danke erst mal für deine Hilfe.
    Ich benutze ReadLine.

    Da bekomme ich einmal den korrekten Code.
    Beim 2mal bekomme ich nur den ersten Teil.
    Die "8003" schneidet er einfach weg.

    Beim 3mal bekomme ich nur die 8003.
    Dann geht alles wieder von vorne los.

    Gruß

    Quellcode

    1. vbCrLf & "+CTSDSR: 141,262100105560571,1,262100103102049,1,16" & vbCrLf & "8003" & vbCrLf

    Da bekomme ich einmal den korrekten Code.


    Korrekt, bei deinem Beispielstring, wäre:

    Nach 1. ReadLine ---> 'Leerzeile'
    Nach 2. ReadLine ---> +CTSDSR: 141,262100105560571,1,262100103102049,1,16
    Nach 3. ReadLine ---> 8003
    @Eierlein Jou.

    grisu74 schrieb:

    Dann geht alles wieder von vorne los.
    Ich hoffe, Du hast inzwischen begriffen, dass die Datenübertragung über die RS232 sehr strukturiert abläuft.
    Was erwartet denn die Gegenstelle von Dir?
    Was liefert Dir die Gegenstelle?
    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!
    Hallo.

    Ich habe das Problem gefunden.
    Nur noch keine Lösung.
    So funktioniert es!!!
    Wenn ich die Daten zum weiterverrbeiten an eine Funktion übergebe ​ Me.txtEmpfangeneDaten.Text &= 'vbCrLf & test.replaceBreak([text]) übergebe
    kommt es zu den Fehlern.

    Hat jemand eine Lösung wie ich die Daten übergeben und dann auswerten kann?

    VB.NET-Quellcode

    1. Private Sub SerialPort1_DataReceived(sender As System.Object, e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
    2. ReceivedText(SerialPort1.ReadExisting())
    3. End Sub
    4. Private Sub ReceivedText(ByVal [text] As String) 'input from ReadExisting
    5. If Me.txtEmpfangeneDaten.InvokeRequired Then
    6. Dim x As New SetTextCallback(AddressOf ReceivedText)
    7. Me.Invoke(x, New Object() {(text)})
    8. Else
    9. Me.txtEmpfangeneDaten.Text &= [text] 'append text
    10. End If
    11. End Sub

    grisu74 schrieb:

    an eine Funktion
    ist völlig korrekt.
    Vielleicht machst Du aus Invoke() ==> BeginInvoke() und ein Return:

    VB.NET-Quellcode

    1. Private Sub SerialPort1_DataReceived(sender As System.Object, e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
    2. Me.ReceivedText(SerialPort1.ReadExisting())
    3. End Sub
    4. Private Sub ReceivedText(ByVal text As String) 'input from ReadExisting
    5. If Me.InvokeRequired Then
    6. Dim x As New SetTextCallback(AddressOf ReceivedText)
    7. Me.BeginInvoke(x, New Object() {text})
    8. Return
    9. End If
    10. Me.txtEmpfangeneDaten.Text &= text 'append text
    11. End Sub
    In welchem Takt kommen die Daten?
    Welche Baudrate hat die COM?
    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!
    Hallo.

    Kannst du mir da helfen.

    Die Daten kommen unregelmäßig. Wenn der Benutzer das Gerät bedient.
    Baudrate 38400

    Wie mache ich das mit dem Return?
    Das gehört natürlich noch dazu.
    ​Delegate Sub SetTextCallback(ByVal [text] As String)

    Wo fange ich die Daten ab?

    Gruß

    grisu74 schrieb:

    Wie mache ich das mit dem Return?
    Du hast da ein If - Else - End If stehen, ich habe den Else-Zweig rausgetan und dafür ein Return reingeschrieben, das ist identrisch der selbe Ablauf, die Form ist Geschmackssache.

    grisu74 schrieb:

    Wo fange ich die Daten ab?
    Was meinst Du damit?
    Die werden im DataReceived-Event empfangen und dann in die Prozedur ReceivedText() "rein-invoked".
    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!

    grisu74 schrieb:

    als Invoked
    werden alle GUI-Zugriffe ausgeführt, die in meinem Code unter

    VB.NET-Quellcode

    1. Me.BeginInvoke(x, New Object() {text})
    2. Return
    3. End If
    4. ' die hier
    stehen.
    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!
    Hallo nochmal.

    Leider hat sich das Problem doch nicht behoben.

    VB.NET-Quellcode

    1. Private Sub SerialPort1_DataReceived(sender As System.Object, e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
    2. ReceivedText(SerialPort1.ReadExisting())
    3. End Sub
    4. Private Sub ReceivedText(ByVal [text] As String) 'input from ReadExisting
    5. If Me.RichTextBox2.InvokeRequired Then
    6. Dim x As New SetTextCallback(AddressOf ReceivedText)
    7. Me.Invoke(x, New Object() {(text)})
    8. Else
    9. Me.RichTextBox2.Text &= [text] 'append text Das hier funktioniert!!!
    10. Debug.Print([text]) ' Das einfache Debug.Print funktioniert schon nicht mehr.
    11. End If
    12. End Sub


    Beim Debuggen und auch OHNE wird die Variable [text] gesplittet??
    Kann jemand sagen warum das so ist?

    Gruß Udo