-         

Seite 1 von 3 123 LetzteLetzte
Ergebnis 1 bis 10 von 26

Thema: Serial Daten bei Komma trennen

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    15.05.2012
    Beiträge
    19

    Beitrag Serial Daten bei Komma trennen

    Anzeige

    Hallo RN,
    ich will von einen Arduino A zum anderen Arduino 4 Messwerte übergeben.

    Diese kommen so beim Arduino B an: "000,111,222,333". Anzahl der Zeichen zwischen 0 und 3. Aber jeder Messwert ist mit einem Komma getrennt.

    Ich will diese nacher möglichst so auswerten können:
    Sensor[0] = 000
    Sensor[1] = 111
    Sensor[2] = 222
    Sensor[3] = 333

    Bis jetzt hab ich nicht viel mehr geschafft außer das Komma zu finden^^

    Code:
    #include <SoftwareSerial.h>
    
    SoftwareSerial mySerial(10, 11); 
    
    void setup() {
      Serial.begin(9600);
      mySerial.begin(9600);
    }
    
    
    
    void loop() {
    
      if(mySerial.available()) {
         char c = mySerial.read();
         if(c==',' ) {
    Serial.println("komma gefunden");
          
         } 
      }
    }


    Kann mir jemand auf die Sprünge helfen





    Hier geht's... aber ist schmuddelig^^


    Code:
    unsigned long data;
    char buffer[40];
    int index = 0;
    int counter = 0;
    int Sensor[4];
    
    void loop() {
      //wenn serielle Daten vorhanden, dann einlesen
      if(mySerial.available()) {
         //einzelnes Zeichen lesen
         char c = mySerial.read();
    
         if(c==',' ) {
    
           buffer[index] = 0;
    
           counter++;
    
           index=0;
     
           data = atol(buffer);
           
         Sensor[counter]=data;
    if(counter == 4){counter=0;}
      
        
         } else {
       
           buffer[index++] = c;
         }
      }
    
           Serial.println(Sensor[1]);
           Serial.println(Sensor[2]);
           Serial.println(Sensor[3]);
           Serial.println(Sensor[4]);
     Serial.println();
    }
    Geändert von Sinnloserknopf (07.10.2017 um 18:30 Uhr)

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    22.06.2009
    Beiträge
    1.266
    Ich verstehe deine Frage nicht ganz. Du hast doch schon eine Lösung ?

    Wenn ich die mir anschaue würde ih aber spontan behaupten die funktioniert so nicht.

    Mal zur Logik:



    Pseudocode:

    Code:
    int index = 0;
    char buffer[4];
    
    loop()
    {
      char c = mySerial.read();
      buffer[index] = c;
      index++;
      if(c == ',')
      {
          //Buffer verarbeiten
          index = 0;
      }
    
    }
    Geändert von shedepe (07.10.2017 um 18:56 Uhr) Grund: index++ vergessen

  3. #3
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    07.03.2011
    Beiträge
    1.401
    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 !

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    22.06.2009
    Beiträge
    1.266
    @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.

  5. #5
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    07.03.2011
    Beiträge
    1.401
    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 !

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    22.06.2009
    Beiträge
    1.266
    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.

  7. #7
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    07.03.2011
    Beiträge
    1.401
    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 14:19 Uhr)
    Strom fließt auch durch krumme Drähte !

  8. #8
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    2.452
    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 20:09 Uhr)
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

  9. #9
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    22.06.2009
    Beiträge
    1.266
    @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.

  10. #10
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    59
    Beiträge
    2.435
    Kennt das Arduino-C kein scanf(); oder sscanf(); ?

    Code:
    sscanf(buffer, "%d,%d,%d,%d", &sensor[0], &sensor[1], &sensor[2], &sensor[3]);
    MfG Peter(TOO)
    Manchmal frage ich mich, wieso meine Generation Geräte ohne Simulation entwickeln konnte?

Seite 1 von 3 123 LetzteLetzte

Ähnliche Themen

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

Berechtigungen

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