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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren