Hallo, ich möchte einen Mega8 mit einem Linux-PC kommunizieren lassen. Dafür würde ich gerne jeweils "Bytepakete" Hin- und Hersenden. Allerdings müsste ich dem Gegenüber erst mitteilen dass jetzt ein neues Paket beginnt - aber wie mache ich das am besten?? Evtl. über einen Frame Error? Kann ich den mit dem PC erzeugen?? MFG Mixer
Nein, Du solltest vielmehr ein sinnvolles Protokoll definieren. Eines, wo Pakete mit einem definierten Header beginnen, der unter anderem die Anzahl der zum Paket gehörenden Nutzbytes und eine Prüfsumme enthält.
Was sind den "Bytepakete" ?? Mit der Standart UART kannst du normalerweiße immer Byteweise senden. Warum mußt du erst mitteilen das ein neues Pakte kommt? Der ATmega kann das Byte enpfangen und gibt dir dann einen Interupt das ein neues Byte empfangen worden ist. Einfacher geht's wohl kaum.
Der Mega8 soll aber auch wissen was er mit dem Byte machen soll. Rufus, ich habe mir schon so etwas in die Richtung gedacht (so ähnlich wie bei DMX-512) Aber wie kann ich dann dem Mega8 mitteilen dass jetzt "Start" ist und dann "Ende"?? Steh glaub irgendwie auf m Schlauch... MFG Mixer
Mixer S. schrieb: > Der Mega8 soll aber auch wissen was er mit dem Byte machen soll. > Rufus, ich habe mir schon so etwas in die Richtung gedacht (so ähnlich > wie bei DMX-512) > Aber wie kann ich dann dem Mega8 mitteilen dass jetzt "Start" ist und > dann "Ende"?? Tja. Da musst du dir etwas suchen, was in deinen Daten per Definition nicht vorkommen kann. Wenn deine Bytepakete grundsätzlich alle mit einem Byte überhaupt möglichen Werte enthalten können, hast du natürlich ein Problem. Was willst du denn übertragen?
Eigentlich alles Mögliche, z.B. Werte für Hardware-PWMs, usw. Also es können alle Möglichkeiten von $00 bis $FF vorkommen! Wenn ich die Länge eines Paketes definiere und der Mega8 die empfangenen Bytes mitzählt würde das zwar gehen - aber wenn er mal ein Byte vergisst würde ja alles durcheinanderkommen!! MFG Mixer
Mixer S. schrieb: > Eigentlich alles Mögliche, z.B. Werte für Hardware-PWMs, usw. Also es > können alle Möglichkeiten von $00 bis $FF vorkommen! > > Wenn ich die Länge eines Paketes definiere und der Mega8 die empfangenen > Bytes mitzählt würde das zwar gehen - aber wenn er mal ein Byte vergisst > würde ja alles durcheinanderkommen!! Ebent. Darum kommt es auch auf die jeweilige Anwendung an. Wenn alle Stricke reissen, kann man zb sowas machen: Man definiert, dass in den Daten auf der Übertragungsstrecke keine 0xFF vorkommen können, schaufelt sich also diesen Bytewert frei. Nur was, wenn dann tatsächlich mal ein 0xFF übertragen werden muss. Dann baut man sich ein Escape-Byte: Man definiert zb das 0xFE nicht direkt beim Empfänger als 0xFE interpretiert wird, sondern dass das nachfolgende Byte eine andere Bedeutung besitzt. Zb 0x01 bedeutet 0xFE und 0x02 bedeutet 0xFF Damit hat man sich einen Bytewert freigeschaufelt, der ausschliesslich für Synchronisationszwecke dient: 0xFF bedeutet 'hier beginnt der nächste Datenframe' (anstelle von 0xFF nimmt man natürlich einen Bytewert von dem man erwartet, dass er nicht allzuoft vorkommt) Wenn dein Protokoll also so aussieht 0xFF 1 Byte Länge des Pakets Datenbytes (wobei obige Ersetzung zum Tragen kommt) und deine zu übertragenden Daten wären 0x80 0x40 0x32 Dann würde das Paket auf der seriellen so aussehen 0xFF 0x03 0x80 0x40 0x32 durch das 0xFF kann sich der Empfänger sauber auf den Start des Pakets synchronisieren. Erst dann, wenn er ein 0xFF sieht ist er sicher, dass er den Paketanfang gefunden hat Sind deine Daten 0x80 0xFF 0x20 0xFE 0x32 Dann sieht das Paket zb so aus 0xFF 0x07 0x80 0xFE 0x02 0x20 0xFE 0x01 0x32 Ob du als Längenangabe die ursprüngliche Länge nimmst oder die Länge die sich durch die 0xFF Substitution ergeben hat, bleibt dir überlassen. Ich würde die ursprüngliche Länge nehmen, weil dann der Aufrufer der Sendefunktion nicht darauf achten muss, dass ein Paket kürzer als 255 bytes sein muss, wenn es 0xFF Bytes enthält. Auf der anderen Seite mag es für jemandem der an der Seriellen mitlauscht befremdlich sein, wenn die Längenangabe nicht zu der Anzahl der tatsächlich übertragenen Datenbytes passt. -> Du entscheidest Edit: ****** Wichtig: Diese Bytewertesubstitution soll so tief wie möglich im Kommunikationsstack passieren. Für darüberliegende Schichten soll das völlig transparent sein. Und: Man berücksichtige auch den Fall, dass die Längenangabe einer dieser 'verbotenen Werte' sein kann.
Wenn es nicht auf Geschwindigkeit ankommt übertrage deine Daten als ASCII Codes. 0xFF einfach zweimal 'F' senden z.B. Dann können deine Daten nur Codes von '0'-'9' und 'A'-'F' enthalten. Alle anderen Zeichen kannst du für eine Startkennung nehmen, z.B. '~' oder '$'. Die Zeichen werden wohl nicht so häufig benutzt. Ansonsten: Lass dir was einfallen!
gast schrieb:
> Einfacher geht's wohl kaum.
Sowas kann nur jemand sagen, der sich noch nie Gedanken über eine
robuste Kommunikation gemacht hat :-)
Zu deiner Info:
Robuste Kommunikation bedeutet auch, dass man zwischendurch einfach den
RS232 Stecker abziehen, wieder aufstecken kann und alles läuft weiter
wie gewohnt (abzüglich der fehlenden Daten natürlich). Sprich: Sender
und Empfänger synchronisieren sich wieder selbsttätig.
Eine weitere einfache Möglichkeit ist die Implementierung eines Protokolls per endlicher Zustandsmaschine. Dann entfällt auch das ganze Escaping.
>Sowas kann nur jemand sagen, der sich noch nie Gedanken über eine >robuste Kommunikation gemacht hat :-) >Zu deiner Info: >... danke für die Info. Von robuster Kommunikation war aber nicht die rede. und das nicht nur "Bytepaket" übertragen werden soll sondern auch noch Steuerinfos wurde erst später erwähnt. Und das es da einen Stecker gibt auch nicht.
> Von robuster Kommunikation war aber nicht die rede. > und das nicht nur "Bytepaket" übertragen werden soll sondern auch noch > Steuerinfos wurde erst später erwähnt. Und das es da einen Stecker gibt > auch nicht. Stecker gibts! Genauso wie Stromausfälle auf beiden Seiten, unerwartete Abstürze des Betriebssystems auf PC-Seite und unerwartete Reset's auf µC-Seite... Das hab ich eig. als selbstverständlich angesehen... Werd aber trotzdem zuerst mal den Ansatz von Karl Heinz ausprobieren, weil es für mich sehr verständlich und einfach klingt. Außerdem hat er auch viel Mühe beim Beschreiben gegeben! MFG Mixer
Dem von Karl Heinz beschriebenen Paket würde ich auf jeden Fall noch eine Prüfsumme mitgeben. Nach dem Empfang der durch die Paketlängenangabe definierten Anzahl an Daten wird die Prüfsumme der empfangenen Daten bestimmt und mit der aus dem Paketheader verglichen. Dann ist auch ein "Escaping" nicht nötig, weil so auch zufälliges Auftreten der Paketanfangskennung erkannt werden kann: Die Prüfsumme stimmt nicht. Wird zusätzlich eine Prüfsumme über den Paketheader definiert, so kann bereits nach Empfang des Headers herausgefunden werden, ob der gültig ist, und der Paketanfangserkennungsvorgang neu gestartet werden. Mit zusätzlichen logischen Einschränkungen kann auch die Paketgültigkeit verifziert werden, bsp. könnte die Paketlängenangabe zwar ein 16-Bit-Wert sein, aber nie größer als 4096 werden ... oder was halt sinnvoll im Rahmen des geforderten Protokolles ist.
Ralf Schwarz schrieb: > Eine weitere einfache Möglichkeit ist die Implementierung eines > Protokolls per endlicher Zustandsmaschine. Dann entfällt auch das ganze > Escaping. Wie das?
Für Rufus' Protokoll könnte das empfängerseitig so ähnlich wie folgt aussehen: ----------- <-----------, | START | ^ (5) | ----------- ----´ | | | (7) | (1) | v | ----------- (8) | | PRÄAMBEL | <-----------| ----------- | | | | (2) | v | ----------- | | LÄNGE | | ----------- | | | | (3) | v | ----------- <---, | | DATEN | | (6) | ----------- ----´ | | | | (4) | v | ----------- | | PRÜFSUMME | ------------' ----------- Die Übergänge würden dann wie folgt ausgelöst: (1) Präambel empfangen (2) Byte empfangen (Länge) (3) Byte empfangen (Datum) (4) Byte empfangen (Prüfsumme) (5) Byte empfangen, aber nicht Präambel (6) Byte empfangen, weitere Daten kommen noch (7) Byte empfangen (nicht Präambel) Falls Prüfsumme okay -> Daten weiterverarbeiten (8) Präambel empfangen Falls Prüfsumme okay -> Daten weiterverarbeiten So ziemlich alle hier nicht eingezeichneten Übergänge müssten noch durch ein Timeout ausgelöst werden, damit das zuverlässig funktioniert. Das ist natürlich nicht unbedingt die effizienteste Lösung. Aber wenn man das Protokoll mal noch erweitern oder umbauen will, hat man nicht so einen grossen Aufwand.
Nur laesst deine Implementierung einfach die Anforderung des eindeutigen Startcodes weg. Die Statemachine vollbringt also kein Wunder, sondern ist nur eine huebsche Darstellung eines Parsers fuer ein vereinfachtes Protokoll.
Rufus t. Firefly schrieb: > Dann ist auch ein "Escaping" nicht nötig, weil so auch zufälliges > Auftreten der Paketanfangskennung erkannt werden kann: Die Prüfsumme > stimmt nicht. Damit bist du aber immer noch nicht aus dem Dilemma heraus, dass du ein zufälliges Auftreten des Startbytes im weiteren Datenstrom als nächsten Paketanfang interpretierst. Du fängst dort wieder zu lesen an und auch diese Prüfsumme wird nicht stimmen etc. Das geht solange bis ein Paket übertragen wird, in dem das Startbyte nach der 'falschen Prüfsummenposition' nicht mehr auftritt. Erst dann synchronisieren sich Sender und Empfänger wieder. > Wird zusätzlich eine Prüfsumme über den Paketheader definiert, so kann > bereits nach Empfang des Headers herausgefunden werden, ob der gültig > ist, und der Paketanfangserkennungsvorgang neu gestartet werden. Das wäre allerdings eine Lösung um zu entscheiden ob ein Startwert tatsächlich das Startbyte war oder nicht. Möglichkeiten gibt es viele. Mit dem Escaping ist es wasserdicht, darum hab ich diesen Vorschlag gemacht.
Ralf Schwarz schrieb: > So ziemlich alle hier nicht eingezeichneten Übergänge müssten noch durch > ein Timeout ausgelöst werden, damit das zuverlässig funktioniert. Was wenn dein Datenstrom einfach kein Timeout zulässt? Ausserdem rettet dich dein Verfahren immer noch nicht davon, dass du einem falschen Startbyte mitten im Datenstrom aufsitzt und ständig das Paket falsch auswertest.
Peter Stegemann schrieb: > Nur laesst deine Implementierung einfach die Anforderung des eindeutigen > Startcodes weg. Ja sorry, bei mir heisst das einfach "Präambel". > Die Statemachine vollbringt also kein Wunder, sondern > ist nur eine huebsche Darstellung eines Parsers fuer ein vereinfachtes > Protokoll. Nee, das vollbringt sie noch nicht. War mir aber auch nicht bewusst, dass das die Anforderung ist in diesem Projekt.
gast schrieb: >>Sowas kann nur jemand sagen, der sich noch nie Gedanken über eine >>robuste Kommunikation gemacht hat :-) >>Zu deiner Info: >>... > > danke für die Info. > Von robuster Kommunikation war aber nicht die rede. > und das nicht nur "Bytepaket" übertragen werden soll sondern auch noch > Steuerinfos wurde erst später erwähnt. 1) Dürfte das ziemlich klar sein. Ein Paket existiert ja nicht im luftleeren Raum. Die Daten stellen irgendetwas dar und in den seltensten Fällen hat man nur einen Strom von Bytes, in dem jedes einzelne Byte tatsächlich einen Wert darstellt. 2) Was machen wir hier? Machen wir Bastelprogramme oder wollen wir was Vernünftiges?
> Ausserdem rettet dich dein Verfahren immer noch nicht davon, dass du > einem falschen Startbyte mitten im Datenstrom aufsitzt und ständig das > Paket falsch auswertest. Dazu dient ja die Checksumme.
Ralf Schwarz schrieb: > Peter Stegemann schrieb: >> Nur laesst deine Implementierung einfach die Anforderung des eindeutigen >> Startcodes weg. > > Ja sorry, bei mir heisst das einfach "Präambel". > >> Die Statemachine vollbringt also kein Wunder, sondern >> ist nur eine huebsche Darstellung eines Parsers fuer ein vereinfachtes >> Protokoll. > > Nee, das vollbringt sie noch nicht. War mir aber auch nicht bewusst, > dass das die Anforderung ist in diesem Projekt. Ist ja kein Problem. Deine Auswertung ist einfach nur auf einer anderen Schichtebene anzusiedeln. Unterste Schicht ist es, ein Paket völlig ohne jegliche Möglichkeit für Fehler zu übertragen. Sender und Empfänger müssen sich selbst soweit synchronisieren, dass der Empfänger ohne jeden Zweifel ein Paket aus dem Datenstrom herausfischen kann. Und zu guter letzt soll natürlich diese Synchronisierung möglichst rasch erfolgen, damit nicht zuviele Daten verloren gehen.
10 02 = STX Start of text 10 03 = ETX end of text wenn im Datensatz eine 10 vorkommt, wird eine weitere 10 eingefügt z.B. 10 02 01 02 10 10 04 05 10 03 ergibt 01 02 10 04 05 ergänzt in der Regel durch eine angehängte Prüfsumme so habe ich es in Nachrichtentechnik gelernt
Ralf Schwarz schrieb: >> Ausserdem rettet dich dein Verfahren immer noch nicht davon, dass du >> einem falschen Startbyte mitten im Datenstrom aufsitzt und ständig das >> Paket falsch auswertest. > > Dazu dient ja die Checksumme. Ja. ok. Damit stellst du fest, dass die letzten Bytes kein Paket gebildet haben. Und, wie geht es weiter? Du liest weiter. Da du aber die Paketgrenze falsch angenommen hast, triggert das nächste Datenbyte mit dem richtigen Wert den nächsten Auswerteversuch. Und schon liest du schon wieder Bytes zu einem Paket zusammen die eigentlich nicht zusammengehören. Klarerweise wird die Checksumme dann wieder nicht stimmen, woraufhin du das Paket verwirfst und im Datenstrom nach dem nächsten Startbyte suchst. Wenn das blöderweise wieder mitten in den Daten auftaucht, versucht deine Statemachine das nächste mal erfolglos sich auf eine falsche Paketgrenze zu synchronisieren. Wenn die Datenbytes richtig stehen, kann dieses Spielchen noch stundenlang so weitergehen, ohne dass sich deine Statemachine wieder korrekt in den Datenstrom einlockt.
Karl heinz Buchegger schrieb: > Mit dem Escaping ist es wasserdicht, darum hab ich diesen Vorschlag > gemacht. Nicht ganz, dafür sorgt die asynchrone Kommunikation. Wenn nonstop Daten gesendet werden kann es vorkommen, dass der Empfänger nie auf's Byte synchronisiert weil er nie weiss wo eines anfängt. Drum: Vor jedem Paket bischen Pause lassen, entsprechend >1 Byte.
A. K. schrieb: > Karl heinz Buchegger schrieb: > >> Mit dem Escaping ist es wasserdicht, darum hab ich diesen Vorschlag >> gemacht. > > Nicht ganz, dafür sorgt die asynchrone Kommunikation. Wenn nonstop Daten > gesendet werden kann es vorkommen, dass der Empfänger nie auf's Byte > synchronisiert weil er nie weiss wo eines anfängt. I stand corrected :-) Da hast du natürlich recht.
> Wenn die Datenbytes richtig stehen, kann dieses Spielchen noch > stundenlang so weitergehen, ohne dass sich deine Statemachine wieder > korrekt in den Datenstrom einlockt. Ja, das stimmt natürlich. Aber meiner Meinung nach ist dein Einwand ein etwas akademischer Fall. Mit realen Daten wird sich der Empfänger mit sehr hoher Wahrscheinlichkeit einsynchronisieren. Und falls der Datenstrom nicht kontinuierlich ist, kann man via Timeout wieder in den Anfangszustand kommen.
Ralf Schwarz schrieb: >> Wenn die Datenbytes richtig stehen, kann dieses Spielchen noch >> stundenlang so weitergehen, ohne dass sich deine Statemachine wieder >> korrekt in den Datenstrom einlockt. > > Ja, das stimmt natürlich. Aber meiner Meinung nach ist dein Einwand ein > etwas akademischer Fall. Mag sein. Deshalb habe ich am Anfang nach den Daten selbst gefragt. Kommt halt immer darauf an, wie allgemein so etwas verwendbar sein soll. Wenn ich eine sichere Paketverbindung als Plug&Play Baustein haben möchte, würde ich auf jeden Fall zu escaping greifen, wenn sich nichts Eindeutiges als Startbyte anbietet. > Datenstrom nicht kontinuierlich ist, kann man via Timeout wieder in den > Anfangszustand kommen. dazu muss ich allerdings auch sagen, dass ich Timeout als Mittel zur Kommunikationssteuerung nicht sehr gerne verwende. Das Schreckgespenst eines Timeout durch herunterfallendes Kabel steht da bei mir immer im Raum. Und das von einem gewollten Timeout von der Sendeseite zu unterscheiden ist praktisch nicht möglich.
NB: Was KHB hier beschrieben hat ist letztlich nichts anderes als das Verfahren im asynchronen PPP, wie man es im Internet-Anschluss mit Modems verwendet hat. Funktionierte da eigentlich ganz gut.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.