Guten Abend Leute,
Ich möchte per UART gerne einen String einlesen bis dieser mit CR/LF
beendet wird.
Abhängig davon welcher String eingelesen wurde, möchte ich verschiedene
Aktionen durchführen.
Zum Hintergrund: später soll der AVR Befehe über UART entgegen senden
und dann über das RFM12-Modul verschiedene Funk-Kommandos senden.
Im Folgenden ein Demo-Programm, das ich zum Nachvollziehen meines
Problems geschrieben habe.
Ich verwende die UART-Library von Peter Fleury.
Ob das richtige Commando geschickt wurde, prüfe ich testweise über eine
LED und einen Vergleich via strcmp().
Das funktioniert nicht und selbst die Prüfung auf "t" als erstes Zeichen
in meinem Char-Array schlägt fehl.
Auch wenn ich versuche mit über uart_puts() den gesendeten String
zurücksenden zu lassen, kriege ich keine Ausgabe.
Hier mein Code:
Die Kommunikation funktioniert, ich kann also ausschließen, dass es ein
generelles Problem, wie in der Checkliste beschrieben, ist.
Holger: uart_getc gibt mir ein unsigned int zurück. Nachdem ich jetzt
meine Varibale c als unsigned int geändert habe, geht es.
Hatte das in den ganzen Stunden wohl schon zu oft umgeändert.
Ich hab schon alles mögliche durchprobiert, aber das war der Fehler! Ein
"t" als ersten Buchstaben kann ich jetzt also erkennen!
Noch etwas: wenn ich jetzt meinen Vergleich mit Strcmp mache, matched
der nicht. Ich habe beim strcmp() jetzt schon "test", "test\n" und
"test\r\n" probiert, leider ohne Erfolg. Hast Du da noch einen Tip?
Vielen Dank schon mal,
LG Alex
Alex schrieb:> Noch etwas: wenn ich jetzt meinen Vergleich mit Strcmp mache, matched> der nicht. Ich habe beim strcmp() jetzt schon "test", "test\n" und> "test\r\n" probiert, leider ohne Erfolg. Hast Du da noch einen Tip?
Du hast eine UART. Du kannst dir über die UART Zeichen (und auch
Strings) ausgeben lassen.
Sieh dir an, was der AVR gekriegt hat! Lass es dir ausgeben.
Vor dem Kommandostring und dahinter gibst du ein Sonderzeichen aus, zb
ein '#', damit du auch die Position der im String enthaltenen
Zeilenvorschübe in der Ausgabe sehen kannst. Gibst du am Terminal "test"
ein, dann muss die Ausgabe
1
#test#
lauten.
Sie darf weder
1
#
2
test#
sein, noch darf sie
1
#test
2
#
sein, und auch
1
#
2
test
3
#
ist aus dem Rennen. Aus der Position deines Sonderzeichens in Relation
zum Text kannst du erkennen, wo im String ein Zeilenvorschub ist.
Und lass die Sache mit dem Ringbuffer sein. Wenn dein Commandostring zu
lang ist, dann machst du keinen Wraparound sondern ignorierst weitere
Zeichen (und gibst gegebenenfalls eine Fehler,eldung aus). Jedes
Kommando fängt im Array immer ganz vorne an. Dinge wie \r oder \n willst
du erst gar nicht im String haben, die speicherst du daher nicht. Ein \n
löst dann zwar die Weiterverarbeitung des empfangenen Strings aus, du
willst aber den \n nicht im String speichern. Der behindert dich nur bei
der Bearbeitung des Strings, liefert dir aber ansonsten keine
Information.
Ich habe sowas ähnliches mit einem Arduino und Ethernet gemacht. Dabei
lese ich in jedem Loop ein Zeichen aus dem Ethernet-Puffer in eine
Fifo-Struktur (Array) fester Länge (5 Byte bzw. Char) - d.h. alle
Array-Felder rücken eins vor, das letzte wird mit dem neuen Wert
gefüllt, das erste fällt weg. Ebenfalls in jedem Loop prüfe ich, ob ein
festgelegtes Anfangs- und Endezeichen auf dem ersten und letzten Platz
dieses Arrays steht. Wenn ja, dann
- Prüfsumme checken (4. Byte)
- Kommando auslesen (2. Byte)
- Paramter auslesen (3. Byte)
- Fifo-Array leeren
- Bestätigungs-Byte zurücksenden
- Kommando ausführen
- zurück zum Loop
Die UART hat ja auch einen eigenen Puffer. Wenn man den nicht
"zuschwemmt" sollte sich die Methode übertragen lassen ...