Willa
14.09.2010, 18:52
Hallo,
ich müsste mal wieder auf eure Erfahrung zurückgreifen... Ich habe zwei µCs die per UART kommunizieren. Der Sender errechnet aus GPS, Kompass und Drucksensor allerlei buntes Zeugs, dass er dann als vier fertige Bytes an den Empfänger schickt.
Der Empfänger läuft in einem Dauerloop mit 500 Hz und guckt bei jedem Durchlauf nach ob der Sender etwas geschickt hat. Falls ja, dann bezieht er die empfangenen Daten in seine weiteren Berechnungen mit ein. Falls nein, dann macht er einfach weiter wie bisher. Der Empfänger soll möglichst wenig Rechenzeit für das Abfragen des UARTS benötigen.
Um die Sicherheit zu erhöhen habe lasse ich beide eine Checksumme berechnen. Jedenfalls glaube ich, dass ich das mache - ich habe mit CRC8 noch keine Erfahrungen.
Das Problem bzw. meine Befürchtung: Falls mal ein Byte vom Sender oder Empfänger verschluckt wird, sind dann die Daten nicht dauerhaft verschoben? Also Externalinput(1) entspricht nicht mehr Command(1) ; Externalinput(2) nicht mehr Command(2) und so weiter. Das müsste ich unbedingt verhindern. Vielleicht mit einer Art Marker am Ende des Arrays?
z.B. so:
Wenn die letzten drei Bytes das spezifische Muster 0; 255; 0 haben, dann sind die vorherigen 4 Bytes richtig empfangen worden. Gibt es so eine Möglichkeit? CRC8 macht ja so etwas ähnliches, aber wie bringe ich dem Empfänger bei, dass er bei Unstimmigkeiten wieder richtig synchronisiert (so dass Externalinput(1) wieder aus Command(1) gezogen wird)?
Einen Interrupt möchte ich nicht verwenden, mir wäre es viel lieber, wenn der Empfänger regelmäßig mit 500 Hz guckt ob etwas da ist, und sich bei seinen restlichen Berechnungen nicht unterbrechen lässt.
Hier mal der vereinfachte Code:
Sender (dieser Code läuft in einem Loop mit 5 Hz)
Clear Serialout
Command(1) = OutputPID_height_integer
Command(2) = OutputPID_heading_integer
Command(3) = OutputPID_roll_integer
Command(4) = OutputPID_nick_integer
Command(5) = Crc8(command(1) , 4)
Printbin Command(1) ; 5
Empfänger (dieser Code läuft in einem Loop mit 500 Hz)
If Ischarwaiting() > 0 Then
Inputbin Externalinput(1) , 5
Crc = Crc8(externalinput(1) , 4)
If Crc = Externalinput(5) Then
Heighthold_int = Externalinput(1)
Heading_int = Externalinput(2)
Gps_roll = Externalinput(3)
Gps_nick = Externalinput(4)
End If
Else
'do nothing
end if
Wäre wunderbar wenn mir jemand Tipps geben könnte....
ich müsste mal wieder auf eure Erfahrung zurückgreifen... Ich habe zwei µCs die per UART kommunizieren. Der Sender errechnet aus GPS, Kompass und Drucksensor allerlei buntes Zeugs, dass er dann als vier fertige Bytes an den Empfänger schickt.
Der Empfänger läuft in einem Dauerloop mit 500 Hz und guckt bei jedem Durchlauf nach ob der Sender etwas geschickt hat. Falls ja, dann bezieht er die empfangenen Daten in seine weiteren Berechnungen mit ein. Falls nein, dann macht er einfach weiter wie bisher. Der Empfänger soll möglichst wenig Rechenzeit für das Abfragen des UARTS benötigen.
Um die Sicherheit zu erhöhen habe lasse ich beide eine Checksumme berechnen. Jedenfalls glaube ich, dass ich das mache - ich habe mit CRC8 noch keine Erfahrungen.
Das Problem bzw. meine Befürchtung: Falls mal ein Byte vom Sender oder Empfänger verschluckt wird, sind dann die Daten nicht dauerhaft verschoben? Also Externalinput(1) entspricht nicht mehr Command(1) ; Externalinput(2) nicht mehr Command(2) und so weiter. Das müsste ich unbedingt verhindern. Vielleicht mit einer Art Marker am Ende des Arrays?
z.B. so:
Wenn die letzten drei Bytes das spezifische Muster 0; 255; 0 haben, dann sind die vorherigen 4 Bytes richtig empfangen worden. Gibt es so eine Möglichkeit? CRC8 macht ja so etwas ähnliches, aber wie bringe ich dem Empfänger bei, dass er bei Unstimmigkeiten wieder richtig synchronisiert (so dass Externalinput(1) wieder aus Command(1) gezogen wird)?
Einen Interrupt möchte ich nicht verwenden, mir wäre es viel lieber, wenn der Empfänger regelmäßig mit 500 Hz guckt ob etwas da ist, und sich bei seinen restlichen Berechnungen nicht unterbrechen lässt.
Hier mal der vereinfachte Code:
Sender (dieser Code läuft in einem Loop mit 5 Hz)
Clear Serialout
Command(1) = OutputPID_height_integer
Command(2) = OutputPID_heading_integer
Command(3) = OutputPID_roll_integer
Command(4) = OutputPID_nick_integer
Command(5) = Crc8(command(1) , 4)
Printbin Command(1) ; 5
Empfänger (dieser Code läuft in einem Loop mit 500 Hz)
If Ischarwaiting() > 0 Then
Inputbin Externalinput(1) , 5
Crc = Crc8(externalinput(1) , 4)
If Crc = Externalinput(5) Then
Heighthold_int = Externalinput(1)
Heading_int = Externalinput(2)
Gps_roll = Externalinput(3)
Gps_nick = Externalinput(4)
End If
Else
'do nothing
end if
Wäre wunderbar wenn mir jemand Tipps geben könnte....