Wiederholte serielle Übertragung scheitert

  • VB.NET

Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Wiederholte serielle Übertragung scheitert

    Hallo,
    aktuell versuche ich Werte von meinem Arduino Uno über den SerialPort an den PC zu senden und dort zu verarbeiten.

    Bei der Übertragung tritt das Problem auf, dass der erste Schub an Daten problemlos in einer Übertragung läuft. Die anschließenden Schübe werden in einem regelmäßigen Muster (wobei auch hier gilt, dass jede Regel ihre Außnahme hat) in 2-3 Übertragungen unterteilt. Es handelt sich ungefähr um 90 bis 110 Byte an Werten pro Schub. Dies führt leider zu einem Problem in der weiteren Verarbeitung der übertragenen Daten in meinem VB.Net Programm.

    Bisher ausgeschlossen habe ich, dass es am Arduino liegt, die Daten im seriellen Monitor der Arduino Software jedesmal ohne Probleme im selben Schub übertragen werden. Ebenso habe ich die Verarbeitung bereits mal ausgelagert in einen externen Thread, aber auch damit keinen Erfolg erziehlt. An der Baudrate habe ich ebenfalls gearbeitet, aber bei der Menge sollte es kein Problem sein und es führt auch zu keiner Änderung im Verhalten. Wenn ich das Programm beim Debuggen kurz anhalte und mir die einzelnen werde anschaue, dann schafft es das Programm auch ohne Probleme alle Schübe abzuarbeiten, aber ohne die Unterbrechung treten die oben beschriebenen Verhaltensweisen auf.

    Meine Verarbeitung in VB sieht wie folgt aus:

    VB.NET-Quellcode

    1. Private Sub DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
    2. Dim cntByte As Integer = SerialPort1.BytesToRead - 1
    3. Dim inByte(cntByte) As Byte
    4. Dim outByte As New List(Of String)
    5. Dim start As Integer = 0
    6. Dim count As Integer = 0
    7. Dim Position As Integer = 0
    8. SerialPort1.Read(inByte, 0, cntByte + 1)
    9. Do
    10. Position = Array.FindIndex(inByte, Function(x) x = 13)
    11. count = If(Position = -1, cntByte - start, Position - start)
    12. If Position = -1 Then
    13. If count > 0 Then
    14. outByte.Add(System.Text.Encoding.Default.GetString(inByte, start, count))
    15. End If
    16. Else
    17. outByte.Add(System.Text.Encoding.Default.GetString(inByte, start, count))
    18. inByte(Position) = 0
    19. start = Position + 1
    20. End If
    21. Loop Until Position = -1
    22. End Sub


    Testweise setzte ich folgenden Code auf dem Arduino ein:

    C-Quellcode

    1. void setup()
    2. {
    3. Serial.begin(115200);
    4. while(!Serial);
    5. delay(5000);
    6. for(int j = 1; j <= 4; j++)
    7. {
    8. for(int i = 1; i <= 15; i++) //Bei 13 und weniger Werten funktioniert es ohne Probleme
    9. {
    10. Serial.print(30600 + i);
    11. Serial.write(0xD);
    12. }
    13. delay(1000);
    14. }
    15. }


    Das Ergebnisse nach einem Durchlauf sieht dann so aus: (Bitte entschuldigt meine Zeichenfähigkeiten)


    Ich hoffe, dass jemand eine Idee bzw. einen Ansatz hat. Danke im Voraus für eure Mühe.

    Edit:
    Ich habe es jetzt einfach mal mit 100+ Werten versucht und auch da klappt die erste Übertragung ohne Probleme

    Gruß K4RTOFF3L

    Das Problem zu erkennen ist wichtiger, als die Lösung zu erkennen, denn die genaue Darstellung des Problems führt zur Lösung. - Albert Einstein

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

    @mausekeks Guter Hinweis.

    K4RTOFF3L schrieb:

    VB.NET-Quellcode

    1. Dim cntByte As Integer = SerialPort1.BytesToRead - 1
    Verfolge diese Variable und überprüfe bei jedem Vorkommen, ob da ein - 1 tatsächlich hingehört.
    Mein Rat:

    VB.NET-Quellcode

    1. Dim cntByte As Integer = SerialPort1.BytesToRead
    2. Dim inByte(cntByte - 1) As Byte
    und dann nur noch cntByte verwenden.
    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!
    Mein ReadBufferSize war 4096 Byte groß. Habe es testweise auf 16384 Byte angehoben, aber es führt zu keinem Erfolg. Da ich ungefähr 2400 Byte (= 6 Byte * 100 * 4) sende, sollte es eigentlich passen, sogar im Falle eines Rückstaus.

    Edit:
    @RodFromGermany
    Ich habe jetzt für die 4 Schübe an Daten alle cntByte im Debugger angeschaut. Die Werte sind soweit alle im richtigen Bereich und es wird nirgends etwas vergessen oder zu viel gemacht. Mir ist zudem aufgefallen, dass 6 Bytes (= erster Schleifendurchlauf auf dem Arduino) meistens als erstes übertragen werden und danach meist der Rest des Schubes folgt.

    Es sieht für mich danach aus, dass das DataReceived-Event aufgerufen wird nach dem Eingang des ersten Schleifendurchlaufes (= 6 Byte) und dann in der dafür benötigten Verarbeitungszeit folgen die restlichen gesendeten Bytes. Wobei es interessant ist, dass dies beim ersten Durchlauf nicht passiert.
    Gruß K4RTOFF3L

    Das Problem zu erkennen ist wichtiger, als die Lösung zu erkennen, denn die genaue Darstellung des Problems führt zur Lösung. - Albert Einstein

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „K4RTOFF3L“ ()

    K4RTOFF3L schrieb:

    Wobei es interessant ist, dass dies beim ersten Durchlauf nicht passiert.
    Da müsstest Du Dich intensiv mit dem Timing im Arduino befassen, allerdings weiß ich nicht, wie man an solch Information rankommt.
    Aus Deinem Code ist mir da nichts ersichtlich.
    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!