- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 2 von 3 ErsteErste 123 LetzteLetzte
Ergebnis 11 bis 20 von 26

Thema: Serial Daten bei Komma trennen

  1. #11
    HaWe
    Gast
    Anzeige

    Praxistest und DIY Projekte
    Zitat Zitat von Peter(TOO) Beitrag anzeigen
    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)
    prinzipiell schon - aber erstmal müsstest du zeigen, wie dein "buffer" erzeugt wird, und dann - probier's aus!

  2. #12
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    707
    Zitat Zitat von HaWe Beitrag anzeigen
    prinzipiell schon - aber erstmal müsstest du zeigen, wie dein "buffer" erzeugt wird, und dann - probier's aus!
    Ich habe mir gerade mal erlaubt das hier auf dem Uno zu testen
    Code:
    void setup() {
      // put your setup code here, to run once:
    
      Serial.begin(9600);
    
      int a,b,c;  
      String test = "1 2 3";
      sscanf(test.c_str(), "%d %d %d",&a, &b, &c);
    
      Serial.print("a = ");
      Serial.println(a);
      Serial.print("b = ");
      Serial.println(b);
      Serial.print("c = ");
      Serial.println(c);
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
    
    }
    ergibt auch brav
    a = 1
    b = 2
    c = 3
    Nachteil: Der kleine Sketch belegt bereits 4780 Bytes Flash und 228 Bytes RAM.

    Normalerweise nehme ich sprintf usw. nur auf dem Teensy. Da gehen aber auch C++ strings und die Konvertierungsfunktionen aus C++14.

  3. #13
    HaWe
    Gast
    Zitat Zitat von Mxt Beitrag anzeigen
    Ich habe mir gerade mal erlaubt das hier auf dem Uno zu testen
    Code:
    void setup() {
      // put your setup code here, to run once:
    
      Serial.begin(9600);
    
      int a,b,c;  
      String test = "1 2 3";
      sscanf(test.c_str(), "%d %d %d",&a, &b, &c);
    
      Serial.print("a = ");
      Serial.println(a);
      Serial.print("b = ");
      Serial.println(b);
      Serial.print("c = ");
      Serial.println(c);
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
    
    }
    ergibt auch brav


    Nachteil: Der kleine Sketch belegt bereits 4780 Bytes Flash und 228 Bytes RAM.

    Normalerweise nehme ich sprintf usw. nur auf dem Teensy. Da gehen aber auch C++ strings und die Konvertierungsfunktionen aus C++14.
    dass das so funktioniert, ist schon klar, die Frage war, wie der OP seinen buffer string generieren soll (bei dir ist er ja fix und heißt test, also kein kontinuierlicher Serial stream).
    Das Konvertieren der Einzel-Tokens zu Zahlen dann wäre das geringere Problem.
    Ich hatte dazu ja \n als Trennzeichen der Gruppen vorgeschlagen - dann müsste man in Tokens aufteilen und umwandeln, wie ich ebenfalls bereits schrieb
    - wie auch immer man das tun will, entweder über Arduino Funktionen oder meinetwegen auch über sscanf.
    Aber ohne eindeutige Gruppen-Trennung wird das kaum zuverlässig funktionieren.

  4. #14
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    707
    Zitat Zitat von HaWe Beitrag anzeigen
    Aber ohne eindeutige Gruppen-Trennung wird das kaum zuverlässig funktionieren.
    Das stimmt, die Gruppentrennung kann aber auch am Anfang der Daten stehen.

    Ich hatte schon mal industrielle Sensoren wo das so aussah:

    - Paketanfang mit Steuerzeichen STX (Start of Text oder Start of Transmission, siehe ASCII-Tabelle)
    - Zeichen das Pakettyp beschreibt
    - Je nach Pakettyp unterschiedlich viele Daten

    Wahrscheinlich stammt das noch aus Zeiten wo Speicher sehr knapp war. Sowas kann man in der Tat auch "on the fly" parsen, ohne alle Daten im Arbeitspeicher zu behalten.

  5. #15
    HaWe
    Gast
    also warum dann nicht
    String buffer=Serial.ReadStringUntil('\n');
    und dann den String teilen und umwandeln?
    Geändert von HaWe (15.10.2017 um 08:23 Uhr)

  6. #16
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    707
    Ich bevorzuge eigentlich das Lesen einzelner Zeichen, die ich dann selbst in Array oder string hinzufüge.

    + Man kann da einen Timeout einbauen
    + Falls die Gegenseite mal das \n vergisst, kann man aufhören wenn es zuviel wird (die Teensy Implementierung von readStringUntil hat im Gegensatz zu Arduino eine einstellbare Maximallänge)
    + Man kann auch Zeilenenden wie \r\n beachten
    + Steuerzeichen kann man ignorieren, z.B. Falls da jemand auf der Gegenseite von Hand tippt
    + Spezialprotokolle wie das obige mit STX kann man gut behandeln, einfach erst mit dem Lesen anfangen, wenn man ein Startzeichen gesehen hat

    - - - Aktualisiert - - -

    Ok, immerhin einen Timeout haben sie bei Arduino
    Code:
    String Stream::readStringUntil(char terminator)
    {
      String ret;
      int c = timedRead();
      while (c >= 0 && c != terminator)
      {
        ret += (char)c;
        c = timedRead();
      }
      return ret;
    }
    beim Teensy sieht die Funktion so aus
    Code:
    String Stream::readStringUntil(char terminator, size_t max)
    {
    	String str;
    	size_t length = 0;
    	while (length < max) {
    		int c = timedRead();
    		if (c < 0) {
    			setReadError();
    			break;	// timeout
    		}
    		if (c == 0 || c == terminator) break;
    		str += (char)c;
    		length++;
    	}
    	return str;
    }
    Das ist ist ja fast wie bei dem Bug in der Arduino map Funktion ...

  7. #17
    HaWe
    Gast
    Zitat Zitat von Mxt Beitrag anzeigen
    Ich bevorzuge eigentlich das Lesen einzelner Zeichen, die ich dann selbst in Array oder string hinzufüge.

    + Man kann da einen Timeout einbauen
    + Falls die Gegenseite mal das \n vergisst, kann man aufhören wenn es zuviel wird (die Teensy Implementierung von readStringUntil hat im Gegensatz zu Arduino eine einstellbare Maximallänge)
    + Man kann auch Zeilenenden wie \r\n beachten
    + Steuerzeichen kann man ignorieren, z.B. Falls da jemand auf der Gegenseite von Hand tippt
    + Spezialprotokolle wie das obige mit STX kann man gut behandeln, einfach erst mit dem Lesen anfangen, wenn man ein Startzeichen gesehen hat
    man kann vieles tun, auch ein eigenes TCP programmieren, aber hier heißt es doch: KISS, und trotzdem halbwegs sicher!
    Problem bei Serial/UART sind Datenübertragungsfehler, und kaum ist mal 1 Trennzeichen falsch übertragen/gelesen, sind die ganzen Daten async.
    Also ein definiertes Ende, was auch dann den neuen Start synced!
    Also was ist einfacher als

    String buffer=Serial.ReadStringUntil('\n');
    und dann den String teilen und umwandeln?
    Geändert von HaWe (15.10.2017 um 08:22 Uhr)

  8. #18
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    707
    Das Problem sind eigentlich nicht falsche Endzeichen. Eher Gegenseiten, z.B. ein Raspi, die mal unbedacht einen zu langen Text, z.B. eine Fehlermeldung schicken. Auf einem kleinen Arduino geht dann schnell nichts mehr, weil gelesen wird bis der Speicher voll ist.

  9. #19
    HaWe
    Gast
    Zitat Zitat von Mxt Beitrag anzeigen
    Das Problem sind eigentlich nicht falsche Endzeichen. Eher Gegenseiten, z.B. ein Raspi, die mal unbedacht einen zu langen Text, z.B. eine Fehlermeldung schicken. Auf einem kleinen Arduino geht dann schnell nichts mehr, weil gelesen wird bis der Speicher voll ist.
    ja, oder einfach zu schnell sendet, so dass der Empfänger nicht nachkommt. Ich selber schicke daher immer mindestes 1 ack zurück, bevor neue Daten geschickt werden (handshake).
    Aber wenn man die Gegenseite per delays etwas verlangsamt, geht es auch so.

    Übrigens:
    Transmission Fehler passieren häufig, das merkt man, wenn man checksums einführt. Je nach Bedingungen (UART speed, msg Länge, Kabel oder drahtlos, timeouts, Störfelder) durchaus jede 50.- jede 1000. msg fehlerhaft. Und wenn dabei 1 Trennzeichen verlorengeht und man ohne feste Paket-Grenzen arbeitet, ist spätestens ab dann Schluss mit lustig. Mit Paket-Trennzeichen aber synced es sich anschließend automatisch wieder ganz von selbst.

    Daher sehe ich immer noch mein Modell ganz vorn:
    String buffer=Serial.readStringUntil('\n');
    und dann den String teilen und umwandeln
    Geändert von HaWe (15.10.2017 um 08:22 Uhr) Grund: typo ReadStringUntil

  10. #20
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    66
    Beiträge
    2.435
    Zitat Zitat von Mxt Beitrag anzeigen
    Eher Gegenseiten, z.B. ein Raspi, die mal unbedacht einen zu langen Text, z.B. eine Fehlermeldung schicken. Auf einem kleinen Arduino geht dann schnell nichts mehr, weil gelesen wird bis der Speicher voll ist.
    Dafür gibt es seit ewigen Zeiten Hand-Shake-Protokolle.

    Das verbreitetste Software-Protokoll ist XON/XOFF, dies verstehen die meisten Geräte mit RS-232 Schnittstelle und es funktioniert mit einer 3-Draht-Verbindung.

    Wenn eine komplette RS-232-Schnittstelle vorhanden ist, kann man auch Hardware-Handshake verwenden.

    Die meisten Betriebssysteme lesen die Zeichen per Interrupt in einen Ringbuffer ein. Einige Bytes bevor der Ringbuffer überläuft sendet man ein XOFF. Dadurch darf der Sender noch ein paar weitere Zeichen senden ohne, dass diese verloren gehen. Ist dann wieder genügend Platz im Ringbuffer sendet man ein XON. Die Applikation liest dann seine Daten aus dem Ringbuffer.

    Beim Senden mach man es auch so. Die Applikation schreibt in einen Buffer. gesendet wird dann per Interrupt. Der Vorteil des Buffers liegt darin, dass die Applikation direkt weiter arbeiten kann nachdem die Daten in den Buffer geschrieben wurden, zumindest so lange noch Platz im Buffer ist.
    Beim direkten Schreiben auf die Hardware, muss die Applikation oft warten, bis das letzte Zeichen gesendet ist. Dies verlansamt dann die Rechenzeit für die Anwendung ganz erheblich, wenn niedrige Baudraten verwendet werden.

    Typische Programme berechnen zuerst eine Menge (CPU-Zeit) um dann einige Zeichen (Textzeile) auszugeben. Durch die Verwendung von Interrupts bekommt man eine einfache Art von Multitasking hin. Senden, Empfangen und Berechnen sind dann eigene Tasks, welche parallel ablaufen können.

    MfG Peter(TOO)
    Manchmal frage ich mich, wieso meine Generation Geräte ohne Simulation entwickeln konnte?

Seite 2 von 3 ErsteErste 123 LetzteLetzte

Ä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