Forum: Mikrocontroller und Digitale Elektronik Wie Daten per UART zwischen zwei µCs übertragen?


von Rick (Gast)


Lesenswert?

Hallo,
ich möchte gerne einen 32-bit Integer zyklisch per UART von einem 
Mikrocontroller an einen anderen schicken.
Zunächst mal scheint das ja recht einfach zu sein:
 1. ich zerlege den int in vier bytes
 2. Ich schicke die Bytes nacheinander über die Schnittstelle
 3. Der Empfänger setzt die Bytes wieder zusammen
 4. Fertig :-)

Das klappt auch soweit, hat allerdings einen ganz großen Haken: wenn der 
Empfänger später startet als der Sender (oder zwischendurch mal ein Byte 
verpasst), geht die Welt unter. Dann interpretiert der Empfänger die 
Bytes in falscher Reihenfolge und es kommt nur noch Murks raus.

Nun ist die Frage, wie man dieses recht einfache Problem lösen kann:
a) Per Timing. Der Sender muss lange Pausen einlegen, so dass der 
Empfänger sich daran orientieren kann.
b) Einen Bytewert als Trennzeichen reservieren. Damit wären aber 
plötzlich viele Werte nicht mehr darstellbar -> unschön

Beide Lösungen finde ich nicht wirklich schön. Übersehe ich vielleicht 
einen viel einfacheren Weg?

Bin dankbar für Tipps :-)

von Thomas R. (r3tr0)


Lesenswert?

Kann dein Empfänger auch etwas zurück senden? Dann würde ich mit dem 
Master kommunizieren und checken ob die Daten richtig angekommen sind.

von Rath Looser (Gast)


Lesenswert?

Rick schrieb:
> Beide Lösungen finde ich nicht wirklich schön. Übersehe ich vielleicht
> einen viel einfacheren Weg?

Nein. Du hast gerade erkannt dass man für viele Zwecke bei
der Datenübertragung ein Protokoll braucht bzw. definieren muss.

von Jens M. (schuchkleisser)


Lesenswert?

Wenn du STX und ETX benutzt, und dazwischen immer 4 Byte sind, ist jedes 
Protokoll nur dann gültig, wenn es STX-4byte-ETX enthält.
Sollte das Wort STX und/oder ETX enthalten (können), ist das kein 
Problem, denn dazu kann man dann noch ESC benutzen.
Dazu ersetzt man im Wort
- STX durch ESC1
- ETX durch ESC2
- ESC durch ESC3
Das Protokoll wird dann ab und an etwas länger sein können, dafür weiß 
man aber sicher: kommt STX fängts an. Genau genommen brauchts dann kein 
ETX mehr.

von Cyblord -. (cyblord)


Lesenswert?

Jens M. schrieb:
> Wenn du STX und ETX benutzt, und dazwischen immer 4 Byte sind, ist jedes
> Protokoll nur dann gültig, wenn es STX-4byte-ETX enthält.
> Sollte das Wort STX und/oder ETX enthalten (können), ist das kein
> Problem, denn dazu kann man dann noch ESC benutzen.
> Dazu ersetzt man im Wort
> - STX durch ESC1
> - ETX durch ESC2
> - ESC durch ESC3
> Das Protokoll wird dann ab und an etwas länger sein können, dafür weiß
> man aber sicher: kommt STX fängts an. Genau genommen brauchts dann kein
> ETX mehr.

Dann noch eine CRC ans Ende.

von Rath Looser (Gast)


Lesenswert?

Rick schrieb:
> Bin dankbar für Tipps

Hier ein Beispiel wie man es machen kann. Verdoppelt zwar die
Datenmenge, muss aber bei kleinen Datenmengen kein Nachteil
sein.

Beitrag "ADF4351: offenes Interface mit AVR zum PC über Serial/USB"

von Thomas (Gast)


Lesenswert?

Rick schrieb:
> Bin dankbar für Tipps :-)

Hallo Rick,

diese Lösung ist nicht die schönste, aber für den Anfang ausreichend.

Mach daraus einen Hex String  0xFFFFFFFF
sende den mit abschliessenden chr(13) = CR.

1.  Sync nach jeden CR
2.  0x  als Frameerkennung

Wenn du noch etwas Luxus haben willst hängst du noch eine QuerSumme 
Modulo 0xFF ran.

-->
    0xFFXXXXXX
  + 0xXXFFXXXX
  + 0xXXXXFFXX
  + 0xXXXXXXFF
  Diese Summe gleich mit einem Byte machen, dann sparst du das Modulo, 
da der Überlauf dies für dich erledigt.


und wenn es nicht Mensch lesbar sein muss......
dann nimm nicht HEX Zahlen, sondern nimm im Ascii die folgenden nach der 
9

Sprich:  0-->48, 1-->49, ...., 9-->57, 10-->58(:),11-->59(;), usw....
dann musst du vom Ascii Wert immer nur die 48 Abziehen...
Gruß Thomas

von Oliver S. (oliverso)


Lesenswert?

Wenn du an beiden Controllern noch je einen Pin frei hast, nimm die zur 
Synchronisation.

Oliver

von Norbert (Gast)


Lesenswert?

Zerlege in fünf Bytes a 7Bit.
Das erste Byte bekommt MSB auf '1' gesetzt, alle anderen auf '0'
Fertisch…

von A. S. (Gast)


Lesenswert?

Die zentrale Frage: Spielt Effizienz eine Rolle? Oder kannst Du Dir 
erlauben, 2 oder dreimal so viele Daten zu senden (Zeit, Strom, 
Rechenleistung, ...)

Effizienz: Es gibt viele mögliche einfache Verfahren mit 1 Byte 
Overhead.

keine Rolle: ÜBerlege, ob Du einfach als String überträgst, mit CR/LF 
als Abschlusskennung. Das ist die allgemeine Empfehlung um portabel und 
lesbar zu sein (mit jedem Sniffer im Klartext mitlesbar)

Die untergeordnete Frage1: Brauchst Du eine Prüfsumme/Fehlererkennung?

Effizient: ein oder zwei Byte anhängen als CRC, XOR oder Summe.

keine Rolle: doppelt übertragen (aber z.B. invertiert),

Die untergeordnete Frage2: Willst Du später auf gleiche Weise mehrere 
Daten übertragen?
Falls ja, dann mache Dich mit 2 oder 3 Protokollen vertraut, überlege 
Dir Deine Anfoderungen und frag nochmal nach. Das ist ein eigenes 
Universum.

von Peter D. (peda)


Lesenswert?

A. S. schrieb:
> ÜBerlege, ob Du einfach als String überträgst, mit CR/LF
> als Abschlusskennung. Das ist die allgemeine Empfehlung um portabel und
> lesbar zu sein (mit jedem Sniffer im Klartext mitlesbar)

Klartext ist immer das einfachste zum Debuggen (Sniffen).
Den Sendestring kann man bequem mit sprintf() basteln und mit sscanf() 
kann man ihn wieder in eine Variable einlesen.

von A. S. (Gast)


Lesenswert?

Primitives Beispiel für 1 Byte overhead:

Als Startzeichen 0xA0 .. 0xAF reservieren. Wenn das kommt, dann hast Du 
den Anfang der neuen Zahl.

Wenn ein Startzeichen im Datenstrom auftaucht, dann addiere 0x100 vor 
dem Senden. Aus 0xA5 wird dann 0xB5

die unteren 4 Bit des Startzeichens geben an, welche Bytes "korrigiert" 
wurden. 0xA3: Das erste und zweite Byte.

-----------
Wie gesagt, ein primitives Verfahren, dass auch nicht skaliert. Aber 
viel mehr Overhead haben gute Protokolle auch nicht

von LostInMusic (Gast)


Lesenswert?

Billiglösung mit erheblichem Overhead (soviel wie die Nutzdaten), dafür 
sehr simpel zu managen:

Spalte Deine 32-Bit-Zahl, z. B. 4F802BD1, in ihre acht Nibbles auf und 
übertrage die acht Bytes 04, 1F, 28, 30, 42, 5B, 6D, 71. Das erste 
Nibble gibt jeweils den Index an, das zweite das Datennibble. Index 0 
markiert den Sendestart, Index 7 das Ende.

Auch diese Methode setzt natürlich eine fehlerfreie Übertragung voraus. 
Sollte das nicht gewährleistet sein, braucht man fehlererkennende bzw. 
-korrigierende Codes. Das wäre dann eine andere Baustelle.

von Jan H. (jan_h74) Flattr this


Lesenswert?

Ein schones Beispiel ist das binaire ublox ubx (GPS-daten) protocol : 
Erst werden mit 2 bestimmte bytes das typ von protocol gesendet, danach 
kommt den payload (specifiert ins protocol), und dan abschluss mit 2 CRC 
bytes.
Beim Anfang sucht den Empfanger nach diese 2 bytes, und macht am ende 
ein check ueber die CRC. Google mal nach ubx-protocol.
Uberhead kann klein sein, wan den payload gross ist !

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Peter D. schrieb:
> Klartext ist immer das einfachste zum Debuggen (Sniffen).
Ich würde auch die Zahl in einen ASCII-String umwandeln und mit CRLF 
abschließen. Dann kann ich die übertragenen Daten mit jedem Laptop in 
Klaransicht mitloggen.

Und wenn dann wegen der zusätzlichen paar Bytes die Bandbreite des 
Busses nicht mehr reicht, dann habe ich sowieso ein grundlegendes 
Problem und brauche was Schnelleres.

A. S. schrieb:
> Die zentrale Frage: Spielt Effizienz eine Rolle?
Und wenn ich diese Frage stelle, dann darf ich auch fragen: muss das 
unbedingt ein 32-Bit Integer sein? Oder ändert sich da immer nur ein 
kleiner Teil davon?

von Nosnibor (Gast)


Lesenswert?

Wenn es tatsächlich nur um die Übertragung zwischen zwei 
Mikrocontrollern geht, reicht die Pause zur Synchronisation. Der Sender 
muss dann eben seine vier Bytes ohne Pause dazwischen raushauen, und der 
Empfänger muss in der Lage sein, die Pause zwischen den Paketen 
eindeutig zu erkennen. Auf "bare metal" Mikrocontrollern ist das 
normalerweise kein Problem.

Den Aufwand mit speziellen Startbytes etc. braucht man dann, wenn man 
(im Sender oder im Empfänger) die Kontrolle über das Timing verloren 
hat, z.B. wenn
 - der Sender ein multitasking-Betriebssystem hat
 - der Empfänger ein multitasking-Betriebssystem hat
 - der Empfänger einen ungeeigneten UART-Treiber hat
 - irgendwelche anderen "transparenten" Übertragungsstrecken 
dazwischengeschaltet sind (TCP/IP, digitale Funkmodule...)
 - die Daten in einer Datei gesammelt und später ausgewertet werden

von Sebastian (Gast)


Lesenswert?

Stichwort COBS hilft dir evtl.

von Stefan F. (Gast)


Lesenswert?

Manche Mikrocontroller können die Übertragungspausen sogar in HW 
erkennen und dann ein Flag setzen, den Puffer leeren oder eine ISR 
aufrufen.

von Peter D. (peda)


Lesenswert?

Nosnibor schrieb:
> Wenn es tatsächlich nur um die Übertragung zwischen zwei
> Mikrocontrollern geht, reicht die Pause zur Synchronisation.

Man sollte sich miese Sachen gar nicht erst angewöhnen.
Das Problem dabei ist, man denkt irgendwann nicht mehr daran, daß der 
Sendeinterrupt die höchste Priorität haben muß. Und dann fügt man 
weitere Interrupts ein und sucht sich nen Wolf nach dem Fehler.

Interruptfehler sind mit Abstand die ekligsten, weil sie so selten 
auftreten. Meistens dann erst bei der Kundenpräsentation.

von Andreas B. (bitverdreher)


Lesenswert?

Norbert schrieb:
> Zerlege in fünf Bytes a 7Bit.

Fast. ;-)
Ich würde in 7 Bytes a 5 Bit codieren und die drei oberen Bits als 
"Adresse" verwenden.

von Frank K. (fchk)


Lesenswert?

Rick schrieb:

> Nun ist die Frage, wie man dieses recht einfache Problem lösen kann:
> a) Per Timing. Der Sender muss lange Pausen einlegen, so dass der
> Empfänger sich daran orientieren kann.
> b) Einen Bytewert als Trennzeichen reservieren. Damit wären aber
> plötzlich viele Werte nicht mehr darstellbar -> unschön
>
> Beide Lösungen finde ich nicht wirklich schön. Übersehe ich vielleicht
> einen viel einfacheren Weg?

Der LIN-Bus verwendet eine dritte Möglichkeit: ein BREAK-Signal. Ein 
BREAK-Signal ist eine Folge von mindestens 13 0-Bits, die niemals im 
normalen Betrieb vorkommen kann. Bessere UARTs haben die Möglichkeit, so 
ein Signal direkt zu erzeugen, ansonsten muss man tricksen (Bitrate 
runterstellen oder so).

Der Empfänger muss die Möglichkeit haben, einen Framing Error zu 
detektieren. Das ist ein Zustand, wo nach dem Startbit (immer 0) und der 
erwarteten Zahl an Datenbits kein Stopbit (immer 1) kommt. Wenn Du beim 
Empfang eines Zeichens einen Framing Error hast, dann hast Du den 
Blockanfang erwischt.

Bei LIN wird anschließend ein Synchronbyte 0x55 gesendet, das der Slave 
ausmessen kann, um seine Bitrate daran anzupassen.

fchk

von Norbert (Gast)


Lesenswert?

Andreas B. schrieb:
> Norbert schrieb:
>> Zerlege in fünf Bytes a 7Bit.
>
> Fast. ;-)
> Ich würde in 7 Bytes a 5 Bit codieren und die drei oberen Bits als
> "Adresse" verwenden.

Platzverschwendung!

Außerdem schrieb ich:
Zerlege in fünf Bytes a 7Bit.
Das erste Byte bekommt MSB auf '1' gesetzt, alle anderen auf '0'

0b1000dddd
0b0ddddddd
0b0ddddddd
0b0ddddddd
0b0ddddddd

Nur wenn's nicht vorher schon klar war:
Das erste Byte bekommt MSB auf '1' gesetzt,
alle anderen Bytes bekommen MSB auf '0' gesetzt.

Das MSB=1 (0b1000dddd) signalisiert Anfang der Sequenz und oberste vier 
Bits, dann noch weitere vier Bytes mit MSB=0 mit 7 Datenbits sammeln und 
zusammen fügen.

Kürzer geht es nicht.

von Norbert (Gast)


Lesenswert?

…Kürzer geht es nicht.

Mit einer Ausnahme, man benutzt als Protokoll nicht 8N1 sondern 9N1
8N1 braucht 5 Bytes (5 x 10Bits)
9N1 braucht 4 Bytes (4 x 11Bits)

von Der Opa aus der Muppet Show (Gast)


Lesenswert?

UART kannst du auch mit zwei zusätzlichen Leitungen betreiben 
Ready-To-Send und Clear-To-Send.

Bei den meisten MCs wertest du diese Leitungen mit einer Kombination aus 
UART-Modul und zusätzlicher Software aus. Steht im Datenblatt und 
Application Notes des MCs.

von Patrick L. (Firma: S-C-I DATA GbR) (pali64)


Lesenswert?

Wenn die Bitanzahl unterschiedlich ist, und du sie aus Plazgründen nicht 
als Ascii senden willst.
Du kannst auch mit dem ersten Byte,
Die Anzahl der 4 Bit nibbles senden (1~256)=(1~128 Byte).

Dann die Empfangsdaten in Stack puschen und wieder abholen,
wen die Anzahl der Beits empfangen sind.
Wenn du ganz sicher sein willst kannst du ein CRC mitsenden.
 So mache ich das bei µC zu µC Kommunikation,
wenn ich nicht grad den MSP430 verwende der dazu extra ein Mode in der 
eUSCI hat die für das Prozedere extra gemacht ist.

von Michael (Gast)


Lesenswert?

Norbert schrieb:
> Mit einer Ausnahme, man benutzt als Protokoll nicht 8N1 sondern 9N1
> 8N1 braucht 5 Bytes (5 x 10Bits)
> 9N1 braucht 4 Bytes (4 x 11Bits)

Würde ich auch so machen, im ersten Byte Bit 8 gesetzt, in den anderen 
gelöscht.

von Framulestigo (Gast)


Lesenswert?

Habt Ihr keine Controller mit 9 Bit Datenbreite? Kann doch so ziemlich 
jeder AVR.

von Norbert (Gast)


Lesenswert?

Framulestigo schrieb:
> Habt Ihr keine Controller mit 9 Bit Datenbreite? Kann doch so
> ziemlich jeder AVR.

Jetzt raten wir mal gemeinsam was 9N1 wohl bedeuten mag. ;-)

von Klaus W. (mfgkw)


Lesenswert?

oder (falls eh wieder bezahlte Pins ungenutzt sind) kann man mit HW 
signalisieren, wann ein neues Wort kommt oder gesendet werden soll.

Eigentlich sind schon zuviele Lösungen hier unterwegs, aber auf eine 
mehr kommt es auch nicht an.

von Günter Lenz (Gast)


Lesenswert?

Man könnte auch Handshakeleitungen RTS und CTS benutzen,
dann geht es auch ohne Softwareprotokoll.

Siehe hier Seite 18:

http://www.netzmafia.de/skripten/hardware/Control/schnittstellen.pdf

https://www.itwissen.info/Handshake-Betrieb-handshake.html

von Andreas B. (bitverdreher)


Lesenswert?

Norbert schrieb:
> Platzverschwendung!

Je nachdem. Bei meiner Methode hat man für jedes Byte auch die 
zugehörige Position.
Es führen viele Wege nach Rom.

Klaus W. schrieb:
> Eigentlich sind schon zuviele Lösungen hier unterwegs, aber auf eine
> mehr kommt es auch nicht an.
Eben. ;-)

von Norbert (Gast)


Lesenswert?

Andreas B. schrieb:
> Es führen viele Wege nach Rom.

Stimmt, dennoch ist die kürzeste Verbindung eine Gerade. ;-)

von Andreas B. (bitverdreher)


Lesenswert?

Norbert schrieb:
> Stimmt, dennoch ist die kürzeste Verbindung eine Gerade. ;-)
Je nachdem mit wieviel Übertragungsverlusten man rechnet.
Die Länge und Qualität der Übertragungsstrecke hat der TO ja nicht 
genannt.
Sicherheit gegen Geschwindigkeit. Das ewige Spiel. ;-)
Im Extremfall als ASCII mit Start- und Endcode schicken ist auch nicht 
so ganz falsch.

von Klaus W. (mfgkw)


Lesenswert?

Norbert schrieb:
> Stimmt, dennoch ist die kürzeste Verbindung eine Gerade. ;-)

Leider muß man dann in den meisten Fällen einen mehr oder weniger 
langen+tiefen Tunnel bauen.

von Norbert (Gast)


Lesenswert?

Klaus W. schrieb:
> Norbert schrieb:
>> Stimmt, dennoch ist die kürzeste Verbindung eine Gerade. ;-)
>
> Leider muß man dann in den meisten Fällen einen mehr oder weniger
> langen+tiefen Tunnel bauen.

Stimmt, wenn die beiden in Frage kommenden Mikrocontroller in 
Deutschland und zB. in Neuseeland liegen muss man so ungefähr in der 
Mitte wohl auch noch kräftig kühlen.

von W.S. (Gast)


Lesenswert?

Rick schrieb:
> Das klappt auch soweit,...

Nö, das klappt nur manchmal, weil serielle Übertragungen immer in Gefahr 
sind, daß Sender und Empfänger nicht synchron laufen.

Du brauchst bei sowas immer irgend ein Protokoll, z.B. in ASCII mit 
Zeilenenden (CR oder CR LF) oder irgend etwas anderes, was aber 2 Dinge 
können sollte:
1. den richtigen Start oder das richtige Ende erkennen können
2. Übertragungsfehler feststellen können

W.S.

von c-hater (Gast)


Lesenswert?

Rick schrieb:

> Beide Lösungen finde ich nicht wirklich schön. Übersehe ich vielleicht
> einen viel einfacheren Weg?

Ja.

Man könnte z.B. Bytes mit 9 Datenbits übertragen und das 9. Bit nur bei 
einem von vier Bytes als Marker für einen Wortanfang setzen. Overhead 
10%. Timing unkritisch. Sehr einfach umzusetzen.

Blöd ist daran eigentlich nur, dass viele UARTs die 9Bit-Datenwörter 
nicht unterstützen. In einem solchen Fall kann man statt dessen das 
Paritätsbit zum gleichen Zweck verwenden. Man toggelt z.B. bei jedem 
4-Byte-Paket zwischen Odd und Even Parity. Der Overhead ist genauso wie 
bei der Variante mit 9 Datenbits, aber man gewinnt auch noch 
Übertragungssicherheit als Nebenprodukt dazu. Der Nachteil ist, dass auf 
der Empfängerseite etwas mehr Aufwand bei der Synchronisationslogik 
getrieben werden muss.

von A. S. (Gast)


Lesenswert?

Rick schrieb:
> b) Einen Bytewert als Trennzeichen reservieren. Damit wären aber
> plötzlich viele Werte nicht mehr darstellbar -> unschön

Wie es geht, habe ich ja schon geschrieben. Hier nur zur Ergänzung, wie 
es heißt: Byte-Stuffing, auf Bitebene Bit-Stuffing 
(https://de.wikipedia.org/wiki/Bitstopfen).

In der einfachsten Form: Wenn das Sonder-Byte kommt, stopft man vorher 
ein Special Character dazwischen. Beispiel: 0x81 als Startzeichen, 0x80 
als Special Character.

Wenn ich nun 0x82, 0x81, 0x80 0x79 als Frame übertragen will, dann sende 
ich:

 * 0x81 (Startzeichen)
 * 0x72 (erstes Byte)
 * 0x80 (special Character)
 * 0x01 (zweites Byte 0x81-0x80)
 * 0x80 (special Character)
 * 0x00 (drittes Byte 0x80-0x80)
 * 0x79 (viertes Byte)

Man kann damit auch weitere Zeichen ausblenden, z.B. Ende und 
Acknowledge.

Leider wird das Telegramm damit bis zu doppelt so groß, wenn auchbei 
geschickter Wahl meist deutlich seltener.

Das ganze kann man bei weiteren Randbedingungen auch auf 0 Byte overhead 
reduzieren (wie in meinem Beispiel) oder für beliebig lange Strings auf 
1 Byte je 256/n Nachrichtenbytes (n=Anzahl der Sonderzeichen) 
beschränken.

von Wolfgang (Gast)


Lesenswert?

Günter Lenz schrieb:
> Man könnte auch Handshakeleitungen RTS und CTS benutzen,

Ein kleiner Schönheitsfehler dabei ist, das lange nicht alle uCs von 
sich aus HW-Handshake unterstützen. Da müsste der TO schon konkreter 
werden.

von Abdul K. (ehydra) Benutzerseite


Lesenswert?

Handshake für jedes Byte ist sowieso unschön. Normalerweise hat man 
einen FIFO auf beiden Seiten mit Hysterese, dessen Füllstandregelung 
über xon/xoff oder RTS/CTS signalisiert wird.
Das ist dann über Funk oder ähnliche Medien, die erhebliche Latenzzeiten 
wegen Synchronisation haben, deutlich effektiver.

von Framulestigo (Gast)


Lesenswert?

Norbert schrieb:
> Jetzt raten wir mal gemeinsam was 9N1 wohl bedeuten mag.

Wenn Du von mir gelesen werden willst, musst Du schon etwas größer 
schreiben.

Aber eigentlich auch alles murks. Wenn der TO doch irgendwann mal mit 
dem PC oder mit dem Handy über BT will, fängt er wieder von vorne an.

von Unkenruf (Gast)


Lesenswert?

Am Ende mag sich gar herausstellen, dass für die zu übertragenden Daten 
der volle Wertebereich von 32-Bit gar nicht benötigt wird ...

von neuer PIC Freund (Gast)


Lesenswert?

>Stichwort COBS hilft dir evtl.

+1

von A. S. (Gast)


Lesenswert?

neuer PIC Freund schrieb im Beitrag #6780957:
>>Stichwort COBS hilft dir evtl.
>
> +1

Dann gebt doch auch einen Link dazu, da es so für einen absoluten 
Beginner kaum zu finden ist:

https://en.wikipedia.org/wiki/Consistent_Overhead_Byte_Stuffing

Die Beispiele dort haben allerdings kein Startzeichen sondern ein 
Endzeichen.

Ich kannte das erst seit 2001 etwa, kurz nachdem wir unser Protokoll 
verabschiedet hatten ;-(

Interessanterweise kommt bei üblichen Anwendungen eine 
Designentscheidung auf: Soll der Sender oder der Empfänger die 
Kodierung/Dekodierung im Strom machen können. In den Beispielen muss der 
Sender den Strom vorher komplett kennen, während der Empfänger byte für 
byte dekodieren kann.

Man kann diese Logik aber auch umdrehen oder auf mehrere Sonderzeichen 
ausdehnen (mit der oben von mir genannten Einschränkung)

Im Gegensatz zum normalen Bytestuffing wird der Overhead hier geringer, 
je öfter das Zeichen im normalen Datenstrom auftritt.

von Weinbauer (Gast)


Lesenswert?

Für so kleine Sachen per UART hab ich früher gern das 9te Bit genommen, 
also 9n1, das überzählige Bit bietet sich an als Flag für Beginn
🤷‍♂️

von Forist (Gast)


Lesenswert?

Weinbauer schrieb:
> Für so kleine Sachen per UART hab ich früher gern das 9te Bit genommen,
> also 9n1, das überzählige Bit bietet sich an als Flag für Beginn
> 🤷‍♂️

Wurde alles schon vorgeschlagen, nur nicht von jedem.

Norbert schrieb:
> Mit einer Ausnahme, man benutzt als Protokoll nicht 8N1 sondern 9N1

Framulestigo schrieb:
> Habt Ihr keine Controller mit 9 Bit Datenbreite?

von Cyblord -. (cyblord)


Lesenswert?

Weinbauer schrieb:
> Für so kleine Sachen per UART hab ich früher gern das 9te Bit genommen,
> also 9n1, das überzählige Bit bietet sich an als Flag für Beginn
> 🤷‍♂️

Die 9 Bit Sache hat aber den Nachteil dass man quasi keine solchen 
Wandler für den PC bekommt. Will man da mal mit einem PC ran steht man 
dumm da. Auch ein UART-Bluetoothmodul wird man dafür schwer finden und 
Kopplung mit PC oder Smartphone geht dann auch nicht.

Das ist ein Graus mit den Modellbausensoren von JETI. Die haben 9O2. 9 
Bit + Parity. AVRs können das. Aber kein USB-UART Wandler kann das. Ich 
finde nicht mal einen STM32 der das kann. Gut die STM32 können 
wenigstens 9 Bit ohne Parity. Aber ich würde die 9 Bit nicht ohne Not 
machen. Ist zu viel Ärger.

: Bearbeitet durch User
von A. S. (Gast)


Lesenswert?

Cyblord -. schrieb:
> Die 9 Bit Sache hat aber den Nachteil dass man quasi keine solchen
> Wandler für den PC bekommt.

Ich verstehe nicht mal, wie man einem Anfänger sowas vorschlagen kann.
Neben der Inkompatibilität mit der Mehrzahl der Übertragungswege und 
Treiber  ist es zudem eine Sackgasse: Eine Erweiterung zu einem echten 
Protokoll ist ausgeschlossen und verschleudert 10% Overhead für eine 1 
Bit-Info pro Telegramm.

genauso könnte ich vorschlagen, mit Parity zu senden und das erste Byte 
mit Parity-Error. Dann habe ich noch einen kleinen Zweitnutzen bei der 
Vergewaltigung des Uarts ;-)

Ich weiss natürlich auch, dass es all sowas auch als etablierte 
Protokolle gibt, mit den abgefahrensten HW-Unterstützungen durch Uarts. 
Inclusive Aufwecken und Start-Kondition. Aber das ist doch alles nichts, 
was man einem blutigen Anfänger (der sich ja auch nicht mehr meldet) um 
die Ohren hauen sollte.

von Cyblord -. (cyblord)


Lesenswert?

A. S. schrieb:
> Ich verstehe nicht mal, wie man einem Anfänger sowas vorschlagen kann.
> Neben der Inkompatibilität mit der Mehrzahl der Übertragungswege und
> Treiber  ist es zudem eine Sackgasse: Eine Erweiterung zu einem echten
> Protokoll ist ausgeschlossen und verschleudert 10% Overhead für eine 1
> Bit-Info pro Telegramm.

Ja korrekt. Vor allem weil es hier so viele bessere Lösungen gibt. Und 
quasi keine Einschränkungen. Da kann man einfach ein Frame mit CRC usw. 
aufsetzen. Ganz old school. Spricht nichts dagegen.
Alles besser als den UART zu vergewaltigen.

von Sebastian (Gast)


Lesenswert?

Hat schon jemand JSON vorgeschlagen :?

LG, Sebastian

von Cyblord -. (cyblord)


Lesenswert?

Sebastian schrieb:
> Hat schon jemand JSON vorgeschlagen :?
>
> LG, Sebastian

Wenn dann CBOR.

von Framulestigo (Gast)


Lesenswert?

A. S. schrieb:
> Ich verstehe nicht mal, wie man einem Anfänger sowas vorschlagen kann.

Das ist der evolutionäre Weg des Programmierers. Zwischen dem 
Lesen/Schreiben einzelner Bytes und dem störungs- und abbruchsicheren 
bidirektionalen Austausch von Telegrammen (mit Interrupts, Fifos und 
zeitlich entkoppeltem Callback) liegt halt die Lücke von etwa 300 
Programmzeilen, die sich der Youngster mit begrenzten Hilfsmitteln 
(Nachrichtenpausen, zusätzlichen Steuerleitungen, ...) füllt.

Es heißt ja nicht, dass man beim "erst einmal falsch machen" nix lernt.

von Andreas B. (bitverdreher)


Lesenswert?

Framulestigo schrieb:
> Es heißt ja nicht, dass man beim "erst einmal falsch machen" nix lernt.
Weise Worte. ;-)

von Yalu X. (yalu) (Moderator)


Lesenswert?

Norbert schrieb:
> Zerlege in fünf Bytes a 7Bit.
> Das erste Byte bekommt MSB auf '1' gesetzt, alle anderen auf '0'
> Fertisch…

Wenn es um die Minimierung des Overheads geht, würde ich diese Methode 
ebenfalls präferieren. In die dabei ungenutzten 3 Bit würde ich noch 
eine CRC packen.

von c-hater (Gast)


Lesenswert?

Yalu X. schrieb:

> Norbert schrieb:
>> Zerlege in fünf Bytes a 7Bit.
>> Das erste Byte bekommt MSB auf '1' gesetzt, alle anderen auf '0'
>> Fertisch…
>
> Wenn es um die Minimierung des Overheads geht, würde ich diese Methode
> ebenfalls präferieren.

Gerade dafür ist sie ziemlich unterirdisch, nämlich 25% Overhead. Die 
9Bit-Varianten (egal ob 9 Datenbits oder 8 Datenbits + Parität) haben 
nur 10%.

> In die dabei ungenutzten 3 Bit würde ich noch
> eine CRC packen.

Die Variante mit 8 Datenbits + Parität nutzt nebenbei sogar 4 Bits 
(naja, eigentlich nur 3,75) als Redundanz. Wenn man die Redundanz nicht 
als Verlust betrachtet, hat diese Lösung also sogar nur einen Overhead 
von 0,625%

Also auch diesbezüglich kann die Lösung mit 5 Bytes nicht punkten, denn 
wenn man auch hier nach dem Prinzip der Chancengleichheit die drei 
Redundanzbits nicht als Verlust betrachtet, hat sie immer noch einen 
Overhead von 17,5%. Also satt das 28fache der 8x1-Lösung!

von Wolfgang (Gast)


Lesenswert?

c-hater schrieb:
> Also auch diesbezüglich kann die Lösung mit 5 Bytes nicht punkten, denn
> wenn man auch hier nach dem Prinzip der Chancengleichheit die drei
> Redundanzbits nicht als Verlust betrachtet, hat sie immer noch einen
> Overhead von 17,5%. Also satt das 28fache der 8x1-Lösung!

In Relation zu JSON ist das fast gar nichts.

Sebastian schrieb:
> Hat schon jemand JSON vorgeschlagen :?

von Norbert (Gast)


Lesenswert?

c-hater schrieb:

> Also satt das 28fache der 8x1-Lösung!

Achtundzwanzig-fach, da schau her!

von Rainer V. (a_zip)


Lesenswert?

War das mit den 9Bit nicht sowas wie Master-Master-Topologie, wobei das 
Bit9 eine Adresse darstellte? Könnte auch etwas älter sein...ich 
erinnere mich nicht mehr so genau...
Gruß Rainer

von Klaus W. (mfgkw)


Lesenswert?

Rainer V. schrieb:
> War das mit den 9Bit nicht sowas wie Master-Master-Topologie,
> wobei das
> Bit9 eine Adresse darstellte? Könnte auch etwas älter sein...ich
> erinnere mich nicht mehr so genau...
> Gruß Rainer

Vielleicht hilft "RS485" der Erinnerung nach?

von Rainer V. (a_zip)


Lesenswert?

Klaus W. schrieb:
> Vielleicht hilft "RS485" der Erinnerung nach?

Ja...aber da war das doch anders...wie gesagt...das alte Rechenwerk :-)

von Abdul K. (ehydra) Benutzerseite


Lesenswert?

Das 9.Bit gab es vermutlich zuerst beim 8051 und konnte bei gesetzt 
einen Interrupt auslösen.

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.