PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Protokoll zur UART Kommunikation PC<->AVR



Christoph2
24.06.2010, 23:55
Hi,

ich will meinem Roboter ein uATX Board spendieren, auf dem LabView laufen soll. Das Labview Programm soll die eigentliche Steuerung des Roboters übernehmen, als Schnittstelle zu den Motoren, Servos, Sensoren, etc. verwende ich ein RNBFRA Board.

Der PC sendet also Steuerbefehle an das RNBFRA Board und das RNBFRA sendet Sensorwerte an den PC.

Die serielle Kommunikation funktioniert schon, also ich kann z.B. einen String zum AVR schicken, und der schickt ihn wieder zurück.
Mein Problem ist aber die Erstellung eines möglichst einfachen Protokolles.

Ich habe mir das so gedacht, dass immer 3 Byte übertragen werden:

----------------------------------------
1. Byte: Befehls-ID
z.b.
0000 0001 Motordrehzahl rechts
0000 0010 Motordrehzahl links
0000 0011 Servo 1 Position
0000 0100 Servo 2 Position
0000 0101 Schrittmotor Position
...

2. Byte: Wert (low-Byte)

3. Byte: Wert (high-Byte)
----------------------------------------

Meine erste Frage ist, ob ihr Verbesserungsvorschläge habt.

Die zweite ist die Programmierung des AVRs, damit er das Protokoll versteht.

Damit ich einen Befehl verarbeiten kann, muss ich ja erstmal die 3 einzelnen Bytes "sammeln" und in einen string aus 3 Zeichen schreiben.
So einen Buffer habe ich jetzt schon programmiert, er wartet einfach bis er drei Zeichen empfangen hat und speichert die in einem String. Für die weitere Verarbeitung, bzw. Befehlsinterprätation ist es aber unbedingt nötig, dass das Befehls-Byte an erster Stelle steht.
Aber wie verdammt erkenne ich das Befehls-Byte???

Meine erste Idee war, das ich nach dem dritten Byte noch ein Byte einfüge, dass mir anzeigt, dass der Befehl zu Ende ist und ein neuer beginnt. Aber das geht auch nicht wirklich gut, wenn ich z.B. 1111 1111 als Befehl-Ende Sequenz nehme, darf ich sie ja sonst nirgends verwenden.
Beim Befehl wäre das ja nicht so schlimm, dann kann ich eben nur 255 Befehle verwenden, aber da ich aber mit Byte 2 und Byte 3 auch (auf 2*8Bit gesplittete) 16 Bit Variablen übertragen will, ist das ein großes Problem...

Könnt ihr mir irgendwie weiterhelfen?

lg Christoph

PicNick
25.06.2010, 10:04
Es gibt da Konzepte für UART Kommunikation auf basis von "messages"
http://www.rn-wissen.de/index.php/Bascom_UART_Input#Message-Header_und_Trailer

Wir hatten da mal ein Projekt:
http://www.rn-wissen.de/index.php/Network_Controller/PC
http://www.rn-wissen.de/index.php/Bascom_UART_Input#Bascom_UART_Input

Ist zwar vieles nach Bascom orientiert, aber doch meistens allgemeiner pseudo-code.

Christoph2
25.06.2010, 13:25
Hi, danke für die Links.

Ich habe mir das Byte-Stuffing angeschaut, mit dem sollte das eigentlich funktionieren.
Wenn ich z.B. als Start-Sequenz 1111 1111 nehme ergibt sich sowas:


1. Byte 1111 1111 "Start-Sequenz"
2. Byte 1001 1001 "Befehl"
3. Byte 1111 1111 "low Byte"
4. Byte 1111 1111 Es wird nochmals die Start-Sequenz "reingestopft", weil das low-Byte 1111 1111 ist
5. Byte 0001 1101 "high-Byte"

Die maximale Länge einer Nachricht ist dann, wenn Befehl, 1. Byte und 2. Byte 1111 1111 sind. Dann wird nämlich einmal die Start-Sequenz eingefügt, und vor alle 3 Bytes nochmal die Startsequenz, somit ergeben sich 7 Byte.

Wie der Empfänger das auswertet, verstehe ich aber überhaupt nicht...
Ich werd aus dem Bascom Code http://www.rn-wissen.de/index.php/Bascom_UART_Input#Byte-Stuffing nicht schlau...

Ich habe mir aber noch was anderes gedacht:
Der Sender sendet zu Beginn einer Nachricht die 3 Bytes
1111 1111
1111 1111
1111 1111
nur um anzuzeigen, dass eine Nachricht beginnt.
Wenn ich dann noch definiere, dass der Befehl nie 1111 1111 sein darf, dann ist es ausgeschlossen, dass diese Start-Sequenz in der normalen Nachricht vorkommt.
Der Empfänger hat dann einen 3 Byte großen ringbuffer, der jedes mal überprüft wird, wenn ein Zeichen hineingeschrieben wird. Wenn der Ringbuffer dann 11111111 11111111 11111111 ist, dann weiß der Empfänger, dass eine neue Nachricht beginnt, zählt mit, bis 3 neue Zeichen in den Rinbuffer geschrieben wurden, wertet den Ringbuffer aus und setzt den Zähler wieder auf 0.

Die Methode ist zwar sicher nicht so elegant, aber würde doch funktionieren oder?

Lieber wäre es mir aber wenn ich irgendwie einen C-Code für den Empfänger für das Byte-Stuffing zusammenbringen würde...

lg Christoph

PicNick
25.06.2010, 15:03
Für die PC-Seite gibt's ja die Routinen auch in C, vielleicht hilft das.
http://www.rn-wissen.de/index.php/Network_Controller/PC_Praxis#Anwendung_f.C3.BCr_RN-COMM

Richard
25.06.2010, 17:56
Aus alten Zeiten kann ich mich erinnern das als Start/Stopp
bestimmte ASCII Zeichen genommen wurden, Befehle aber
nur in Hex übertragen wurden. Oder halt auch anders herum,
ASICII FF oder NULL gibt es ja nicht wirklich. Hex FF oder Hex 0
sehr wohl...Dabei werden dann allerdings weit mehr Byt`s
übertragen.

Bei der RN Motorkontroll wird anscheinend einfach festgelegt was
wie übertragen wird und wie der Befehl (2,3,x Byte) aufgebaut ist.
Scheint gut zu klappen.

Gruß Richard