Hallo Leute, eine Frage an die "Theoretiker" unter euch. Ich möchte mehrere Bytes via UART übertragen. Das heißt, ich muss feststellen können, dass es sich (vermutlich) um das erste Byte eines Frames handelt. Das macht man üblicherweise mit einem bestimmten Wert ("SYNC-Byte"). Frage: Gibt es irgendwelche mathematische Theorien, um ein möglichst optimalen Wert zu wählen? 0x00 und 0xFF sind sicher nicht geeignet, aber welche sonst? Die Nebenbedingungen sind: - Es handelt sich um einen Bytestrom (keinen Bitstrom) - Jeder Wert - von 0x00 bis 0xFF - kann in den Nutzdaten vorkommen - Ob es sich tatsächlich um einen gültigen Frame handelt wird am Ende mittels CRC-Prüfsumme festgestellt. Mein Bauchgefühl sagt mir, man sollte eine Kombination kurzer und längerer 0/1-Längen nehmen, z.B. 0x3A = [0]00111010[1] (mit Start- und Stopbit). Kann das jemand bestätigen/berichtigen? Vielen Dank für eure Hilfe. Gruß, DetlevT
Detlev T. schrieb: > - Jeder Wert - von 0x00 bis 0xFF - kann in den Nutzdaten vorkommen > Gibt es irgendwelche mathematische Theorien, um ein möglichst > optimalen Wert zu wählen? Garantiert, aber wenn du in deinem Datenstrom jedes Byte und jede beliebige Bytereihenfolge in gleicher Häufigkeit haben kannst, dann ist jede Sync-Kennung gleich gut und gleich schlecht... Dann da reicht prinzipiell ein einziges Byte nur für eine Wahrscheinlichkeit von 1/256, dass du das richtige Sync-Byte gefunden hast. > Mein Bauchgefühl sagt mir, man sollte eine Kombination kurzer und > längerer 0/1-Längen nehmen, z.B. 0x3A = [0]00111010[1] (mit Start- und > Stopbit). Kann das jemand bestätigen/berichtigen? Das wäre wohl eher eine Beruhigung für deinen Bauch, als ein wirklicher Grund. > Das heißt, ich muss feststellen können, dass es sich (vermutlich) um > das erste Byte eines Frames handelt. Das macht man üblicherweise mit > einem bestimmten Wert ("SYNC-Byte"). Oder gleich mit einem Sync-Word (16-Bit), bzw. einem noch längeren Sync-Pattern (aka Magic-Code 0xAA,0x55,0xAA...)... Die sicherste Methode wäre aber, einen bestimmten Wert nicht zur Datenübertragung zu nehmen. Wenn da z.B. ein ADC angeschlossen ist, dann könnte es ja reichen, nur die Werte 0..254 zur Datenübertragung zu nehmen, und die 255 zur Synchronisation. Oder die 254 und 255 in 2 Bytes zu verschlüsseln: wenn 254 übertragen werden soll, dann kommen die 2 Bytes 254 und 0, wenn 255 übertragen werden soll, dann kommen die 2 Bytes 254 und 1 (das Zeichen 254 wäre hier quasi ein "Escape"-Zeichen). Dann hättest du die 255 wieder "freigeräumt" und könntest diesen Wert als Sync-Zeichen verwenden. Daraus resultiert aber eine unterschiedlich lange Übertragungsdauer, weil ja für diese Werte jeweils 2 Bytes übertragen werden müssen. Und dann bräuchtest du im Empfänger einen Mechanismus, der das wieder zurückwandelt. Nicht kompliziert, nur eben ein wenig aufwendig...
Hallo Lothar, wird das Signal durch einen Impuls gestört, der eine Zeit lang eine "0" repräsentiert, ergibt sich für den UART je nach dessen Länge einer der Werte 0xFF, 0x7F, 0x3F,..., 0x01 oder 0x00. Solche Werte halte ich daher für ein SYNC-Byte weniger geeignet, die sollte man lieber gleich verwerfen, wenn sie während einer Sendepause auftreten, und nicht auf Datenbytes warten, die niemals kommen werden. Gruß, DetlevT
warte doch ab, bis das nächste Datenpaket eintrifft und prüfe, ob der Abstand zwischen zwei Triggerbytes gleich der Länge eines Datenpakets ist. So mache ich es hier, habe die 255 als Triggerbyte. Ich lese mehrere A/D-Wandler aus und übertrage verrechnete Werte zum PC. Die 255 entspricht einer Eingangsspannung von +10V, also dem höchsten Ausschlag, wenn der PC das High-Byte "findet", beim Low-Byte kann die 255 recht häufig vorkommen, daher mache ich eine Erkennung, ob die 255 beim nächsten und übernächsten Paket auch an der gleichen Stelle ist. Mein Signal rauscht, sodass es eher unwahrscheinlich ist, dass das Low-Byte 3 mal in Folge 255 ist. Außerdem habe ich eine kleine Korrektur, dass meine Triggerung sich nach falschem Einrasten erneut synchronisiert.
@ Detlev Ich habe, offen gesagt, den Eindruck, das Du die möglichen Störungen und Gegenmaßnahmen auf Bit-Ebene und Protokollebene nicht in den richtigen/sinnvollen Proportionen siehst und sie falsch anwendest. Zunächst mal gibt es eine Sicherungsschicht (wenn man das denn angesichts der geringen Möglichkeiten so nennen mag). Die besteht nur aus dem Parity-Bit und kann naturgemäß nur einen Teil der denkbaren Störungen erkennen, es werden keine Fehler korrigiert. Ihrer Funktion nach kann sie nur Störungen, die ein Bit betreffen erkennen sowie bestimmte Kombinationen von Mehrbitstörungen. Sollte letzteres tatsächlich regelmäßig/reproduzierbar auftreten so ist _RS232 nicht das geeignete Übertragungsmedium_ ! Genau diesen letzteren Fall aber stellst Du hier in den Raum, nämlich das mehrere Bits gestört werden. Ebenso ist die Anwendung von Prüfsummen eine die Fehler auf der Bitebene erkennen soll. Je nach Wahl des Verfahrens muss bei Problemen damit entweder das Prüfsummenverfahren oder das Übertragungsmedium gewechselt werden. Ein völlig anderer Fall ist die Synchronisation auf Protokollebene. Hier geht es nicht um die Erkennung von Störungen auf der Bitebene. Aber nur für diese Ebene stellt sich die Frage der Wahl einer geeigneten Bitkombination, Anwendung von Escape Sequenzen oder ähnlichem. Die Auswahl eines bestimmten Musters macht also keinen Sinn. Denn genauso wie Du annimmst, das eine Störungen eine Reihe von Bits auf 0 zieht kann man annehmen, dass völlig andere Störungsmuster auftreten die Dein Muster dann nicht abfängt. Entweder also, hast Du uns die Information darüber, das und warum nur eine bestimmte Art von Störungen vorliegen kann nicht gegeben oder aber Dein Versuch die Übertragung an der Stelle des Frame-Synchronisationsbytes sicherer zu machen ist untauglich.
Kommt drauf an, wie immer. Zur Synchronisation benutzt man auch gerne eine BREAK-Bedingung. Die taucht im USART z.B. als Framefehler auf, der im normalen Datenstrom normalerweise nicht vorkommt. Dazu noch ein paar Prüfbytes, um den Fehler von echten Übertragungsfehlern zu unterscheiden. Das macht z.B. DMX so.
Vielleicht ein bißchen Tricky, aber was spräche den dagegen, die Länge der Nutzdatenbits an die Identifikation zu verknüpfen. Mein Vorschlag wäre, die Sync-Info z. B. mit 7-Bit oder weniger zu übertragen. Solange im Empfangsinterrupt des nicht synchonisierten Empfänger stets Datenframes mit 8-Bits eintreffen, sollte ein Frameerror erkannt werden und die Daten verworfen werden. Wenn dann ein 7-Bitwort empfangen wird, wäre es gleichgültig, welchen Wert es enthielte. Damit die Datenframelänge für die nun folgende Nachricht paßt, müßte der Empfänger nur auf die andere Datenbitlänge umschalten. Bei UART sollte das im Gegensatz zu CAN funktionieren. Ein Punkt ist mir jedoch nicht klar. Wann weißt Dein Programm, dass ein Datenkontainer vollständig ist. Hast Du eine festgelegte Byteanzahl?
Hallo Leute, ich habe das S.N.A.P.-Protokoll im Hinterkopf. Einiges gefällt mir da nicht, deshalb will ich mir etwas einfacheres ausdenken. Dort wird 0x54 als SYNC-Byte verwendet. Ich kann die Frage daher auch so formulieren: Gibt es einen Grund, warum dieser Wert besser geeignet ist als so mancher andere? Störungen muss ich ohnehin erkennen. (@Guru: von RS232 hatte ich nichts geschrieben. Nur von UART). Es könnte aus meiner Sicht aber von Vorteil sein, "typische" Störungen gleich verwerfen zu können. Gruß, DetlevT
> @Guru: von RS232 hatte ich nichts geschrieben. Nur von UART
Aha. Und? Beruht die Tatsache, dass unvollständige Informationen
vorliegen auf einem Fehler Deinerseits oder meinerseits?
UART heisst üblicherweise RS232. Wenn nicht hättest DU die Information
geben müssen.
Guru schrieb: >> @Guru: von RS232 hatte ich nichts geschrieben. Nur von UART > UART heisst üblicherweise RS232. bei weitem nicht!
@ Kevin K. (nemon) >Guru schrieb: >>> @Guru: von RS232 hatte ich nichts geschrieben. Nur von UART >> UART heisst üblicherweise RS232. >bei weitem nicht! Das "UART" "bei weitem nicht" "üblicherweise", heisst anders ausgedrückt, das UART "in den seltensten Fällen" mit RS232 verknüpft ist. Aha.
Kevin K. schrieb: >> UART heisst üblicherweise RS232. > bei weitem nicht! Wenn ich Auto schreibe, dann hast du sofort das "Durchschnittsauto" (nämlich einen PKW) vor Augen. Und wenn ich dann aber einen LKW meinte, dann wäre es schön, wenn ich dich vorher darauf hinweise. Es könnte ja sein, dass das an meiner Aussage was ändert... Wenn ich U(S)ART (ohne Einschränkungen oder Anmerkungen) lese, dann habe ich sofort eine RS232-Schnitte vor Augen... Detlev T. schrieb: > Störungen muss ich ohnehin erkennen. (@Guru: von RS232 hatte ich nichts > geschrieben. Nur von UART). Es könnte aus meiner Sicht aber von Vorteil > sein, "typische" Störungen gleich verwerfen zu können. Wenn man schon nach "typischen Störungen" sucht, dann wäre es durchaus interessant, welches Medium diese typischen Störungen mit sich bringen könnte. Und UART ist hier dann ja wohl ein Begriff, der z.B. auf CAN genauso zutrifft. Nur sind dort die Störmechanismen und die Störbehandlung ganz anders... Detlev T. schrieb: > durch einen Impuls gestört, der eine Zeit lang eine "0" > repräsentiert, ergibt sich für den UART je nach dessen Länge einer der > Werte 0xFF, 0x7F, 0x3F,..., 0x01 oder 0x00. Solche Werte halte ich daher > für ein SYNC-Byte weniger geeignet, die sollte man lieber gleich > verwerfen, wenn sie während einer Sendepause auftreten, und nicht auf > Datenbytes warten, die niemals kommen werden. Wenn ich z.B. xFF als Sync-Byte nehme, und es kommt wegen einer Störung ein xFF zustande, dann tut mir das nicht weh. Denn mit dem nächsten gültigen und fehlerfrei übertragenen Frameanfang kommt ja wieder ein xFF. Und auf das wird neu synchronisiert. Dazwischen warte ich auf gar nichts... Schlimmstenfalls/Bestenfalls kommt ein Timeout-Fehler, der mich auf eine schlechte Übertragungsstecke hinweisen könnte. Genauso dann, wenn zwei Frame-Starts hintereinander kommen...
Guru schrieb: > @ Kevin K. (nemon) > >>Guru schrieb: >>>> @Guru: von RS232 hatte ich nichts geschrieben. Nur von UART >>> UART heisst üblicherweise RS232. >>bei weitem nicht! > > Das "UART" "bei weitem nicht" "üblicherweise", heisst anders > ausgedrückt, das UART "in den seltensten Fällen" mit RS232 verknüpft > ist. > > Aha. RS232 ist als asynchroner Bus eine Untermenge aller UART-Varianten. Derzeit wird sie wohl sehr häufig implementiert, um eine Schaltung mit einem Computer zu verbinden. Wenn du aber beispielsweise einen µC an einen PC ohne RS232-Schnittstelle klemmen willst, nimmst du möglicherweise einen Wandler von UART mit TTL-Pegel zu USB (FT232 und konsorten). Der µC bekommt davon nichts mit, dem ist völlig egal, was mit den Daten passiert. Aber RS232 hast du trotz UART nicht benutzt. Bei der Zeile, die du zitierst trat genau das Problem auf, dass du UART mit RS232 gleichgesetzt hast, der User vor dir aber (vermutlich, man weiß es nicht so recht) TTL-Pegel meinte. Das "üblicherweise" aus deinem Post impliziert, dass man pauschal UART mit RS232 gleichsetzen kann und Ausnahmen vernachlässigbar selten sind. RS232 ist wie gesagt, eine häufige Implemention, aber es gibt noch andere, die eben nicht vernachlässigbar häufig anzutreffen sind. So drücke ich es auch mit meinem "bei weitem nicht" aus. Letzteres heißt nämlich nicht "in den seltensten Fällen". Just my 2 Cent
Lothar Miller schrieb: > Wenn ich U(S)ART (ohne Einschränkungen oder Anmerkungen) lese, dann habe > ich sofort eine RS232-Schnitte vor Augen... Und ich eine RS485. ;-) Beim UART sind "0" und "1" aber nicht gleichwertig, weil "1" den Ruhezustand bedeutet - und "0" den Beginn eines Frames. Aber meine eigentliche Frage wurde nicht beantwortet. Vermutlich kann man daher wirklich nach Lust und Laune sich einen Wert aussuchen. Gruß, DetlevT
@ Kevin K.
>So drücke ich es auch mit meinem "bei weitem nicht" aus. Letzteres heißt >nämlich
nicht "in den seltensten Fällen".
Wenn Du diese Äusserung unter das Zitat von mir stellst schon.
"üblicherweise" lässt nämlich durchaus auch das Gegenteil zu. Das UART
zwangsweise, immer und nur mit RS232 verknüpft ist, habe ich nie
geschrieben. "Bei weitem nicht" ist eine Negation die nur sehr wenige
Ausnahmen zulässt. In Verbindung heisst das "in den seltensten Fällen".
Das mich hier jemand belehren will, der noch nicht mal die Grundlagen
der Sprache und Logik kennt, ist absurd.
Lothar hat es schon gesagt: Mangels Information geht man vom Üblichen
aus. Du suggerierst das hier nur, das ich eine absolute Aussage
getroffen habe, zu welchem Zweck auch immer, denn das Problem des TO
hilft das nicht zu lösen.
Also, ich halte mich mal 'raus, anstatt mich auf sinnlose Diskussionen
einzulassen.
Das Grundproblem, das hier einerseits Informationen fehlen und
andererseits verschiedene Problembereiche vermischt werden habe ich
angesprochen.
Wenn es nutzt, dann gut. Wenn nicht, dann auch gut.
@Guru, bloß nicht als blödes Anmachen sehen ;) Ich halte mich hier jetzt auch mal raus, zumindest, was die sprachlichen Feinheiten angeht.
Bevor Ihr hier ein Semiotik-Seminar gründet: Der Begriff U(S)ART impliziert eine asynchrone serielle Schnittstelle, was für die Problembetrachtung ausreichend genau ist. Ob nun RS232, TTL-Pegel, RS485 oder RS422 auf dem Übertragungsmedium genutzt wird, ist für das Problem des Threadstarters vollkommen irrelevant.
Kevin K. schrieb: > ... einen Wandler von UART mit TTL-Pegel zu USB (FT232) ... > Aber RS232 hast du trotz UART nicht benutzt. Allerdings möchte ich gern dazu anmerken, dass selbst FTDI den FT232 ausdrücklich FT232 benannt hat. Und nicht FTUART... ;-) > Bei der Zeile, die du zitierst trat genau das Problem auf, dass du UART > mit RS232 gleichgesetzt hast, der User vor dir aber (vermutlich, man > weiß es nicht so recht) TTL-Pegel meinte. Ich meine nicht. Denn seine Bedenken waren genau so, dass ein kurzer Störspike im Ruhezustand (='1', high, 5V TTL) fälschlicherwese als Startbit angesehen werden könnte, und daraus resultierend ein xFF eingelesen würde... Detlev T. schrieb: > Beim UART sind "0" und "1" aber nicht gleichwertig, weil "1" den > Ruhezustand bedeutet - und "0" den Beginn eines Frames. Und ob die '1' jetzt als 5V im Logikpegel oder als -3..12V im RS232 Pegel dargestellt wird, ist dabei eher zweitrangig... Rufus Τ. Firefly schrieb: > Ob nun RS232, TTL-Pegel, RS485 oder RS422 auf dem Übertragungsmedium > genutzt wird, ist für das Problem des Threadstarters vollkommen > irrelevant. Das bringt die Thematik auf den Punkt.
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.