Serielle Eingabge "verschluckt" relativ häufig das letzte Zeichen

OP #3571930
Lesenswert?
• ▲
▼
Hallo,

ich habe ein Problem mit dem Arduino und der UART Schnittstelle. An der 
UART Schnittstelle ist ein HC-05 Modul angeschlossen, welche genauso wie 
der Sketch mit einer Baudrate von 115200 betrieben werden (Kleinere 
Baudraten 57600, 19200, 9600 konnten das Problem nicht beheben).

Ich lese über die Schnittstelle zuerst einfach nur den String Zeichen 
für Zeichen ein, bis ein CR bzw NL kommt.

Die Eingabe erwartet einen String, der einem Zahlenwert entspricht von 0 
- 999.

1
  while (1) {
2
    const unsigned char MaxChars = 3;    // 3-stellige Zahl
3
    static char strValue[MaxChars + 1];
4
    static int index;
5

6
    if (Serial.available())
7
    {
8
      char c = Serial.read();
9
      if (index < MaxChars && c >= '0' && c <= '9')
10
      {
11
        strValue[index++] = c;    // ASCII-Zeichen hinzufuegen
12
      }
13
      else if ((c == '\r' || c == '\n') && index != 0)
14
      {
15
        strValue[index] = 0;
16
        printf("\n%i\t", atoi(strValue));
17
        index = 0;
18
      }
19
    }

Bei der Eingabe über das Termina kommt es immer wieder vor, dass nur das 
letzte Zeichen (0-9) nicht erkannt wird.
#3571947
Lesenswert?
• ▲
▼
Stefan S. schrieb:

>         printf("\n%i\t", atoi(strValue));


Ho, ho, ho.

Wenn du atoi benutzt, solltest du auch sicher stellen, dass du einen 
C-String hast.
Ein C-String ist eine Zeichenkette, deren letztes Zeichen ein '\0' 
Character ist.
Wo genau stellst du das in deinem Code sicher, dass das immer so ist?


PS:
Das äussert sich zb so, dass du um eine Zeichenkette der Länge 3 zu 
speichern, ein Array der Größe 4 brauchst. Denn das letzte Zeichen, das 
'\0' muss ja auch irgendwo gespeichert werden.

Aber alles in allem machst du das viel zu kompliziert
1
  while (1) {
2
    static int zahl;
3

4
    if (Serial.available())
5
    {
6
      char c = Serial.read();
7
      if (c >= '0' && c <= '9')
8
      {
9
        zahl = 10*zahl + ( c - '0' );
10
      }
11
      else if (c == '\r' || c == '\n')
12
      {
13
        printf("\n%i\t", zahl);
14
        zahl = 0;
15
      }
16
    }
OP #3571964
Lesenswert?
• ▲
▼
Hallo Karl Heinz,

danke für deine Antwort.

Ich ging eigentlich davon aus, dass
1
strValue[index] = 0;
 zum setzen des '\0' reicht.

Das mein CharArray größer der Digits sein muss, ist mir bewusst, deshalb 
habe ich oben auch das Array mit +1 deklariert. Die dann reseviert für 
das '\0' ist.


Ich hatte bereits mehrere Lösung geschrieben und auf Fehler überprüft. 
Eines kommt deinen Vorschlag nahe, jedoch habe ich da nicht nach CR 
und/oder NL abgefragt, sonder einfach mit else gearbeitet, was zur folge 
hatte, dass ich dauerhaft nach der Eingabe den Zahlenwert bekam sowie 
eine 0.

Danke, so geht es!

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.