Forum: Mikrocontroller und Digitale Elektronik UART interface: String command sets sinnvoll verarbeiten


von Alex V. (bastel_alex) Benutzerseite


Lesenswert?

Hallo zusammen,

ich versuche gerade eine sinnvolle architektur für die Verarbeitung der 
RX-Daten meines uart interfaces auf dem mikrocontroller aufzubauen. Der 
µC schickt eigentlich nur daten raus (unkompliziert), muss aber einige 
wenige konfigurationsdaten verstehen.

Das sind
1) User ASCII eingaben (Konsole) - das ist umkompliziert, da ich mir 
hier meine eigene einfache einzelchar syntax überlegen kann. Bislang 
sieht die so aus: ASCII "#" Als start, "*" als Terminierbyte und 
dazwischen die paar chars für die Konfiguration.
2) Die String-Antworten des AT2 Command sets auf einem Bluetoothmodul 
(SPBT2632C2A).

Zu 2) suche ich nun noch sinnvolle anregungen, denn: Die Opcodes sehen 
z.B. so aus:
µC sendet "AT+AB DefaultLocalName [name]" um dem Modul (z.B. bei der 
Anzeige am PC) einen neuen Namen [name] zu geben. Das Modul schickt dann 
zurück
"AT-AB LocalNameOk".

Von diesen Commands gibt es viele - und die Antworten sind 
unterschiedlich lang und nicht durch ein spezielles Zeichen Terminiert.
Ich weiß nun nicht, wie ich die Daten aus meinem UART RX-FIFO-Ringbuffer 
am sinnvollsten verarbeite, weil das Ende eines AT-AB Opcodes nie 
eindeutig ist. Erst dann, wenn entweder ein erneutes AT-AB kommt (dann 
war der letzte Befehl wohl zu ende) oder ein "#....*", dann ist es wohl 
ein User-Konfigurationsbefehl.

Ideen? Ansätze?

Beste Grüße

von Volker S. (vloki)


Lesenswert?

Alex V. L. schrieb:
> Das Modul schickt dann zurück
> "AT-AB LocalNameOk".

Sicher, dass da kein CR oder NewLine am Ende mit geschickt wird ?

von Alex V. (bastel_alex) Benutzerseite


Lesenswert?

Nicht sicher, leider ist die Dokumentation des Command Sets extrem mies 
oder ich bin einfach noch nicht fit genug darin( 
http://www.google.de/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CCIQFjAA&url=http%3A%2F%2Fwww.st.com%2Fst-web-ui%2Fstatic%2Factive%2Fen%2Fresource%2Ftechnical%2Fdocument%2Fuser_manual%2FDM00055990.pdf&ei=eco0VYnAMIWgsAH5-YFw&usg=AFQjCNFgWEZrfp89b82p4ZykZhmqiPULUg&sig2=MInp5zfgcfDkmUzj86fEiw&bvm=bv.91071109,d.bGg&cad=rja 
)

Dass das Format der Commands ASCII ist wird zB auch nirgends angegeben, 
wahrscheinlich weil der gesunde Menschenverstand es schon erschließen 
kann...

von Alex V. (bastel_alex) Benutzerseite


Lesenswert?

Lediglich in der Definition des ErrorFormats (Errformat error response) 
wird geschrieben dass diese kommt, wenn die AT2FW ein command 
(abgeschlossen durch CR/LF) erhält das nicht der syntax beginnend mit 
AT+AB entspricht. Was aber die rausgeschickten daten angeht finde ich 
nichts.

Aber: Die CR/LFs am Ende - sind die vielleicht einfach Konvention und 
stehen deshalb nicht drin? Wenn ja wäre ja trotzdem die Frage CR, LF 
oder CR+LF..

von Karl H. (kbuchegg)


Lesenswert?

Alex V. L. schrieb:
> Nicht sicher, leider ist die Dokumentation des Command Sets extrem mies
> oder ich bin einfach noch nicht fit genug darin(
> 
http://www.google.de/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CCIQFjAA&url=http%3A%2F%2Fwww.st.com%2Fst-web-ui%2Fstatic%2Factive%2Fen%2Fresource%2Ftechnical%2Fdocument%2Fuser_manual%2FDM00055990.pdf&ei=eco0VYnAMIWgsAH5-YFw&usg=AFQjCNFgWEZrfp89b82p4ZykZhmqiPULUg&sig2=MInp5zfgcfDkmUzj86fEiw&bvm=bv.91071109,d.bGg&cad=rja
> )

Was sich bewährt hat, das ist solche Module erst  mal mit einem Terminal 
zu verbinden (zb PC mit einem Terminalprogramm) und dort mal 'händisch' 
mit dem Modul zu 'spielen'.

Dann sieht man sehr schnell, ob und wie so ein Modul reagiert und auch 
ob es einen CR (+LF) sendet oder nicht. Gerade wenn Kommandos bzw. 
Antworten im Klartext hin und her geschickt werden, dann ist es 
eigentlich üblich das Ende einer 'Übertragung' mit einem CR 
abzuschliessen. Warum? Weil es das einfachste bzw. naheliegenste für 
jeden ist, der vor einem Terminal sitzt, nach der Eingabe eines 
Kommandos auf Return zu drücken, bzw. weil sich dann auf einem Terminal 
ganz automatisch eine optische Zeilenstruktur ergibt, in der leicht 
nachvollziehbar ist, welches Kommando welche Antwort nach sich gezogen 
hat.
 Ok, heutzutage bei den Mausschubsern ist das vielleicht nicht mehr so 
naheliegend, aber alle die noch mit einer Commandline aufgewachsen sind 
finden das intuitiv naheliegend.

Aus genau demselben Grund würde ich auch hier
> Bislang sieht die so aus: ASCII "#" Als start, "*" als Terminierbyte
das nicht so machen, sondern das Terminierbyte ganz simpel als CR 
fordern (ein eventuelles LF wird ignoriert) und kein Startbyte machen. 
Da du textuelle Kommandos hast, ist ganz einfach das erste Wort (alles 
bis zum ersten Leerzeichen bzw. bis zum CR) das Kommandowort und wenn 
das in deine Liste von Kommandos passt, dann gilt das.

von Eric B. (beric)


Lesenswert?

AT commands sind CR terminiert.

http://en.wikipedia.org/wiki/Hayes_command_set#The_basic_Hayes_command_set 
- direkt unter der Tabelle:
  "Note: a command string is terminated with a CR (\r) character"

von Warten (Gast)


Lesenswert?

Ich hab ein ähnlich gelagertes Problem (keine eindeutige Ende Kennung) 
aber andere Problemstellung.

Also da hab ich keine andere Lösung gefunden, als einen Timer laufen zu 
lassen, der laufend hochzählt (alle ... Ticks unabhängig der Empfangenen 
Zeichen). Jedes Zeichen, das einwandfrei empfangen wurde, setzt den 
Zähler wieder auf "0". Wenn ... Ticks vergangen sind, (z.B. mehr als 10 
Zeichen Pause), wird davon ausgegangen, das der gesendete String zu Ende 
ist. Funktioniert natürlich nur, wenn zwischen den Strings Pausen sind, 
die länger als ein paar einzelne Bytes sind.

Viel Erfolg und viele Grüße und auch mal schreiben, wie es gelöst wurde 
:-)

von Alex V. (bastel_alex) Benutzerseite


Lesenswert?

Danke für eure Antworten, allesamt sehr hilfreich! :)
Jetzt kann ich durchstarten - und ja, ich mache auch meine eigenen 
Kommandos mit CR, das war natürlich ein überaus einleuchtender Hinweis!

von Ben (Gast)


Lesenswert?

Noch aus Interesse:
gibt es dden Fall überhaupt, dass beide Arten von Kommandos (AT + deine 
Userbefehle) gleichzeitig ankommen können?

Oft sind diese Module ja erstmal in einem Kommandomodus und können durch 
einen Befehl, einen Hardwarepin oder eingehenden Verbindungsaufbau in 
den Übertragungsmodus geschalten werden.
In diesem Modus werden dann AT-Befehle weder ausgegeben noch 
verarbeitet. Andernfalls könntest du kein Binärprotokoll über das Modul 
laufen lassen, da im Datenstrom durchaus AT+... vorkommen kann.

Aber keine Ahnung wie das bei deinem Modul aussieht.

von Alex V. (bastel_alex) Benutzerseite


Lesenswert?

Ben schrieb:
> Oft sind diese Module ja erstmal in einem Kommandomodus und können durch
> einen Befehl, einen Hardwarepin oder eingehenden Verbindungsaufbau in
> den Übertragungsmodus geschalten werden.

Damit hast du auch bei diesem Modul recht, soweit ich das beurteilen 
kann -und damit kann, wenn ich es soweit richtig verstanden habe, nicht 
beides gleichzeitig kommen.
Sobald das Modul im Bypass mode ist gehen weder AT commands rein noch 
raus. Aber erneut - ich habe nur die AT2FW Documentation von ST für das 
modul und finde persönlich, dass die äußerst mager gehalten ist. Ich 
weiß zB. noch nicht, über welchen Befehl ich aus dem Bypass Befehl 
wieder herauskomme, wenn ich nicht die Verbindung z.B. über 
SPP/LinkDisconnect komplett disconnecten möchte. Einen "AT+AB Bypass" 
befehl gibt es, ein "StopBypass" Äquivalent habe ich noch nicht 
entdecken können.

Der Hinweis das Modul direkt an die Console zu hängen (ich hab da noch 
einen sparkfun FTDI basic converter rumliegen) war sicherlich ein guter, 
mit dem ich mehr herausfinden können werde.

von Moby (Gast)


Lesenswert?

Warten schrieb:
> Also da hab ich keine andere Lösung gefunden, als einen Timer laufen zu
> lassen

Wenn man mal annimmt, daß jedem Kommando Pausen folgen ist das ohne 
Terminierbyte die beste Lösung.
Ich machs umgekehrt: Ein für viele Aufgaben verwendeter 
Haupt-Timerinterrupt dekrementiert ein für solche Zwecke vorgesehenes 
Word-Variablenfeld jeweils bis 0 (z.B. bei mir mit 200Hz). Die 
Interrupt-Empfangsroutine setzt nun eine solche ihr zugehörige Variable 
bei jedem Zeichen auf einen bestimmten Wert (z.B. 3). Erreicht dieser 
Wert jemals 0 (also hier nach ca. 15ms Pause)  ist der Empfangsstring 
vollständig.

von Karl H. (kbuchegg)


Lesenswert?

Alex V. L. schrieb:

> Sobald das Modul im Bypass mode ist gehen weder AT commands rein noch
> raus.

> SPP/LinkDisconnect komplett disconnecten möchte. Einen "AT+AB Bypass"
> befehl gibt es, ein "StopBypass" Äquivalent habe ich noch nicht
> entdecken können.

Du könntest versuchen, ob die übliche sog. Escape Sequence greift.

Das Zeichen im Register S2 (ab Werk ein '+') ist 3 mal zu senden, mit 
jeweils davor und dahinter einer Pause

http://en.wikibooks.org/wiki/Serial_Programming/Modems_and_AT_Commands/Special_Commands_and_Character_Sequences#.2B.2B.2B:_Escape_Sequence

von Alex V. (bastel_alex) Benutzerseite


Lesenswert?

Karl Heinz schrieb:
> Du könntest versuchen, ob die übliche sog. Escape Sequence greift.

Danke, mache ich!

von Alex V. (bastel_alex) Benutzerseite


Lesenswert?

Karl Heinz schrieb:
> Was sich bewährt hat, das ist solche Module erst  mal mit einem Terminal
> zu verbinden (zb PC mit einem Terminalprogramm) und dort mal 'händisch'
> mit dem Modul zu 'spielen'.

Das hat sich jetzt auch bei mir bewährt - wunderbarer Hinweis, schade 
dass ich nicht selbst drauf gekommen bin! Mit diesem Vorgehen konnte ich 
heute in wenigen Stunden BT Modul testen und auf dem µC implementieren - 
läuft!
Vielen Dank!

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.