Forum: Mikrocontroller und Digitale Elektronik Serielle Eingabge "verschluckt" relativ häufig das letzte Zeichen


von Stefan S. (sschultewolter)


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.

von Karl H. (kbuchegg)


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
    }

: Bearbeitet durch User
von Stefan S. (sschultewolter)


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!

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.