Forum: Mikrocontroller und Digitale Elektronik Char-Array parsen


von Manuel B. (modellbahner)


Lesenswert?

Hallo zusammen,

ich habe schon lange gegoogelt, aber keine passende Lösung gefunden.
Ich habe nämlich folgendes Problem:

Ich empfange über den UART eines ATmega8 mehrere Chars, welche in einem 
Char-Array (= Buffer) zwischengespeichert werden. Dies funktioniert 
schon hervoragend in Verbindung mit HyperTerminal. Doch nun komme ich 
einfach nicht weiter: Ich muss nun den Char-Array im Ascii-Format parsen 
und dort Zahlen herauslesen.

Mein Protokoll:

         8 Bit             8 Bit   8 Bit

         Befehlsbuchstabe  Nummer  Wert

Beispiel 'p'               235     054

Die Strings von HyperTerminal sehen so aus:
p235054

Ich programmiere in C mit AVR-gcc.

Ich hoffe ihr könnt mir helfen.

Gruß Manuel

von Karl H. (kbuchegg)


Lesenswert?

Manuel Bentele schrieb:

> Die Strings von HyperTerminal sehen so aus:
> p235054


Also musst du diesen String erst mal in 3 Teile zerlegen.
1 char      Kommandobuchstabe
3 char      erste Zahl
3 char      zweite Zahl

damit hast du dann 2 Strings die du zb mittels atoi in richtige Zahlen 
umwandeln lassen kannst.

http://www.mikrocontroller.net/articles/String-Verarbeitung_in_C


PS. meistens ist es keine so gute Idee Zahlen direkt aufeinanderfolgen 
zulassen. Denn irgendwann macht wer beim zählen einen Fehler. Einfacher 
ist es oft zwischen die Einzelteile einen 'Trenner' einzubauen. Mach wir 
ja auch: zwischen 2 Wörter steht ein Leerraum.

p 235 54
oder

p 235,54
oder

p 235,54;
oder ....

ist um einiges fehlerunanfälliger, wenn ein Mensch die Steuerkommandos 
eingeben muss. Erzeugt ein Programm die Steuerkommandos, dann ist es 
allerdings egal, denn das erzeugt die Kommandos immer gleich und nur in 
Ausnahmefällen fehlerhaft (zb wenn die Ausgangszahlen zu groß sind)

von Oliver J. (skriptkiddy)


Lesenswert?

Dein String hat dieses format.
> p235054
Das erste Zeichen ist der Befehl
die Zeichen 2-4 sind eine Zahl
und die Zeichen 5-7 ebenfalls eine Zahl.
Du sammelst also immer 7 Zeichen.
Man könnte z.B. so vorgehen:
1
char chararray[] = "p235054";
2
3
char befehl    = char_array[0];
4
uint8_t nummer = (char_array[1] - 0x30)*100 + (char_array[2] - 0x30)*10 + (char_array[3] - 0x30);
5
6
uint8_t wert   = (char_array[4] - 0x30)*100 + (char_array[5] - 0x30)*10 + (char_array[6] - 0x30);

Eventuell könnte man die Übertragung anhand der Buchstaben, die bei dir 
ja Befehle darstellen synchonisieren, falls die Kommunikation mal aus 
dem Takt kommt. Eine Prüfsumme oder ein Paritätsbyte wäre vllt auch 
nicht schlecht, um die Übertragung abzusichern.

Gruß Oliver

von Manuel B. (modellbahner)


Lesenswert?

Vielen Dank für eure Antworten.

Ich werde Olivers Vorschlag gleich mal umsetzten.

@Karl Heinz Buchegger: Ich werde HyperTerminal nur zum Testen der 
Funktionalität benutzen. Deshalb werde ich den String ohne Trennzeichen 
zum UART schicken. Eine GUI sollte dann die Benutzerfehler abfagen (-> 
Exceptionhandling).

von Karl H. (kbuchegg)


Lesenswert?

> uint8_t nummer = (char_array[1] - 0x30)*100 + (char_array[2] - 0x30)*10 + 
(char_array[3] - 0x30);

Schreibs besser so:
1
uint8_t nummer = (char_array[1] - '0')*100 + (char_array[2] - '0')*10 + (char_array[3] - '0');

dann wird deutlicher, wo die 0x30 herkommen. Das ist einfach der ASCII 
Code des Zeichens '0'.

von Manuel B. (modellbahner)


Lesenswert?

Das stimmt: So wird es übersichtlicher.
Ich habe es gerade ausprobiert: Es funktioniert. Wenn das ganze Projekt 
fertig ist, werde ich es im Forum in Form von Bildern zeigen.

von Oliver J. (skriptkiddy)


Lesenswert?

Karl Heinz Buchegger schrieb:
> dann wird deutlicher, wo die 0x30 herkommen. Das ist einfach der ASCII
> Code des Zeichens '0'.
Nun ja. Das ist in diesem Fall Geschmackssache. Ich schreib es schon 
ewig als 0x30 und finde daher '0' recht ungewöhnlich.

Gruß Oliver

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.