- fchao-Sinus-Wechselrichter AliExpress         
Ergebnis 1 bis 10 von 26

Thema: Serial Daten bei Komma trennen

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    So, wie du das beschreibst, kannst du das gar nicht zuverlässig dekodieren. Was kommt nach der 333 in deinem Beispiel? Die 000 von der nächsten Messung? Kommt dazwischen auch ein Komma? Wie kannst du entscheiden, welche Zahl die erste deiner vier Messwerte ist?

    Ich gehe mal davon aus, daß deine "Zeilen" durch ein Newline getrennt sind. Ich würd also erstmal eine ganze Zeile empfangen. Dazu braucht man einen Buffer mit einer maximalen Länge von 4*3 Ziffern, 3 Kommas und dem abschließenden Null-Byte (für einen C-String), also 16 Zeichen.

    Man wartet, bis von der seriellen ein Newline kommt. Ab da füllt man die empfangenen Zeichen in den Buffer, bis ein weiteres Newline kommt. Hier schließt man den Buffer mit einem Nullbyte ab. Jetzt kann man den Buffer mit all den Funktionen, die die Stringlibrary von C so her gibt, bearbeiten. Das Auswerten eines Records, coma separated, ist ja kein neues Problem. strchr() oder strtok() kommen mir dabei in den Sinn. Wenn man den Record erstmal in seine Felder zerlegt hat, kann man sie z.B. mit atoi() in Integer wandeln.

    Testen tut man das Ganze am besten auf dem PC, C-Code ist halt C-Code. Die Debugtools auf dem PC sind mächtiger und es geht viel schneller. Den Inputbuffer kann man leicht mit gets() füllen, das Ergebniss mit printf() ausgeben. Da kann man dann auch leicht verifizieren, wie robust der Code ist, wie er auf verstümmelte oder gestörte Nachrichten reagiert. Wenn man mit dem Ergebnis zufrieden ist, macht man mit dem Arduino weiter.

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  2. #2
    shedepe
    Gast
    @Klebwax. Wenn eine Zahl immer aus 3 Ziffern besteht ist das ohne weiteres machbar. Dann braucht es kein Newline, man muss es nicht zwischenspeichern sondern nur bis 3 zählen. Die erste Zahl kann man daran erkennen, dass nach 3 Ziffern kein Komma gekommen ist.

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Zitat Zitat von shedepe Beitrag anzeigen
    @Klebwax. Wenn eine Zahl immer aus 3 Ziffern besteht ist das ohne weiteres machbar. Dann braucht es kein Newline, man muss es nicht zwischenspeichern sondern nur bis 3 zählen. Die erste Zahl kann man daran erkennen, dass nach 3 Ziffern kein Komma gekommen ist.
    Anzahl der Zeichen zwischen 0 und 3. Aber jeder Messwert ist mit einem Komma getrennt.
    Das Format mit dem Komma entspricht ja dem üblichen csv-Format. Und da gibts, wie eigentlich bei jedem Textformat üblich, einen eindeutigen Zeilentrenner. Es wäre auch nicht schlau, sich auf feste Feldlängen zu verlassen, schon nächste Woche braucht man ein anderes (längeres) Format.

    Und warum soll man nicht zwischenspeichern? Den Buffer kann man leicht aus dem Interrupt heraus füllen und die eigentliche Anwendung bleibt responsiv. Außerdem wird man flexibel, ob der Buffer von der seriellen gefüllt wird, aus einem Netzwerkstack kommt oder vom Massenspeicher gelesen wird, ändert an der Dekodierung nichts.

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  4. #4
    shedepe
    Gast
    Ob es schlau ist oder nicht habe ich nicht gesagt, nur dass es machbar ist. Und da wir uns auf einem Mikrocontroller befinden will man häufig so effizient wie mögich mit seiner Rechenzeit umgehen. Das ist bei komplexeren Datenformaten + den damit komplexeren Parsern nicht unbedingt gegeben.

    Aber auch wenn man ein Newline zeichen hat, würde ich nicht hingehen, die Daten zuerst speichern und dann Parsen, sondern on the fly parsen. Stringoperationen sind nämlich nicht wirklich Rechenzeit optimal.

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Zitat Zitat von shedepe Beitrag anzeigen
    Ob es schlau ist oder nicht habe ich nicht gesagt, nur dass es machbar ist.
    Wenn du drauf bestehst, es ist nicht machbar, da ein Feld, wie geschrieben, 0 bis 3 Zeichen lang sein kann.
    Und da wir uns auf einem Mikrocontroller befinden will man häufig so effizient wie mögich mit seiner Rechenzeit umgehen. Das ist bei komplexeren Datenformaten + den damit komplexeren Parsern nicht unbedingt gegeben.
    Der Code muß so schnell sein, wie nötig und keine bisschen schneller.
    Aber auch wenn man ein Newline zeichen hat, würde ich nicht hingehen, die Daten zuerst speichern und dann Parsen, sondern on the fly parsen.
    Ich dagegen würde nie einzelne Zeichen abholen sondern einen Buffer im Interrupt füllen. Und erst wenn der Buffer dann geparst ist und nur gültige Werte enthält, würde ich die Daten weiterverabeiten.
    Stringoperationen sind nämlich nicht wirklich Rechenzeit optimal.
    Na dann sollte man den ganzen C++ Overhead des Arduino über Board werfen. Aber für nicht benutzte Prozessorzyklen gibts kein Geld zurück. Es ist also Unsinn, auf erprobte und tausendfach getestete Libraries zu verzichten. So ein moderner µC hat eine mit dem original IBM-XT vergleichbare oder sogar höhere Rechenleistung. Da wurde kaufmännische Buchhaltung oder Textverarbeitung mit gemacht, nur so zur Einordnung der Rechenleistung. Solange nicht ganz spezielle Gründe dagegen sprechen ( so als Lehrling muß man mal einen Würfel feilen bevor man an die Fräse darf ) würd ich immer Funktionen aus der C-Library verwenden. Da muß man zwischen 8-Bit µC, einem 32-Bit µC und dem PC nicht umlernen, ist alles C bzw C++.

    MfG Klebwax
    Geändert von Klebwax (08.10.2017 um 13:19 Uhr)
    Strom fließt auch durch krumme Drähte !

  6. #6
    HaWe
    Gast
    da die Daten als Text-String im ASCII- bzw. csv-Format per Serial() gesendet und empfangen werden , ist es sinnvoll, die Arduino Serial + String-class Funktionen zu verwenden, zusammen mit einem eindeutigen Trennzeichen, z.B. LineFeed:

    HTML-Code:
    char termbyte = '\n';
    String ReadBuffer = "";
    while ( !Serial.available() );
    if ( Serial.available() ) {
       ReadBuffer = Serial.readStringUntil(termbyte);
    }
    Dann muss man den Puffer noch an den Kommas in Einzelstrings ("Tokens") aufteilen und die einzelnen Tokens in echte Zahen umwandeln.

    https://www.arduino.cc/en/Reference/Serial
    https://www.arduino.cc/en/Reference/StringObject

    edit:
    alternativ kann man die Daten auch einzeln jeweils bis zum termbyte ',' lesen, dann sofort in eine Zahl umwandeln, und fortsetzen bis das termbyte '\n' ist, damit man wieder eindeutigere Start- und Stoppbedingungen hat, und dann wieder von vorn - ist aber wschl etwas schwieriger zu programmieren mit den Arduino-Methoden.
    Geändert von HaWe (09.10.2017 um 19:09 Uhr)

  7. #7
    shedepe
    Gast
    @Klebwax. Sorry. Lese Kompetenz
    Über die anderen Punkte kann man sich streiten. Auf einem Desktop würde ich dir sofort recht geben, auf einem Mikrocontroller nicht.

Ähnliche Themen

  1. serial daten übertragen
    Von foobar123 im Forum Arduino -Plattform
    Antworten: 0
    Letzter Beitrag: 04.02.2014, 23:24
  2. Serial USB Daten
    Von Ripper121 im Forum AVR Hardwarethemen
    Antworten: 4
    Letzter Beitrag: 15.06.2011, 07:33
  3. komma verschieben in zahl
    Von puci123 im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 12.10.2009, 13:09
  4. Aufrunden nach dem komma!
    Von grillfisch im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 26.01.2009, 19:35
  5. Variablen und Komma ??
    Von Roberto im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 5
    Letzter Beitrag: 26.08.2005, 03:54

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen