Paketübertragung per UART

OP #527015
Lesenswert?

Hallo Forum,

ich hab grad mal ein kleines Problem.
Zwar möchte ich über die Serielle Schnittstelle Pakete senden und 
empfangen.
Diese haben folgenden Aufbau an Nutzdaten:

[1Byte ID][nBytes Wert]

So wie kann ich die Pakete nun am besten verschicken? Also wie erkenn 
ich Anfang und Ende? Klar durch Start/Stoppbyte. Nur was nehm ich da als 
Codierung? Ich brauch ja alle 8Bit für die Übertragung der Werte und 
IDs. Es kann ja jede Bitfolge in einem Wert Byte vorkommen. Wie lös ich 
also das Problem?
Oder hab ich da grad nen Denkfehler?
Mein Überlegung war noch das ich nur 7Bit für den Inhalt, und 1 Bit dann 
für die Erkennung ob Startbit oder nicht. Aber dann brauch ich ja um ein 
8Bit Wert zu übertragen schon 2 Byte...

Gruß
Uwe
OP #527105
Lesenswert?

Das mit dem 9. Bit war auch schon meine Überlegung. Nur können das die 
meisten Terminal Programme wohl nicht. Die Daten wo ich verschicke 
sollen dann auch per Labview ausgewertet werden, fraglich ob das damit 
klar kommt.


@holger
Da ist nichts wild durcheinander ;)
Ein Paket besteht aus 1 Byte wo die ID drin steht, dahinter kommt eine 
beliebige Anzahl von Bytes wo der dazugehörige Wert steht.
Die Pakete sollten so kompakt wie möglich sein.

@Minetti
Bei der base64 Codierung muss ich ja immer Blöcke mit 3 Bytes 
verarbeiten. Das erzeugt u.U. wieder viel Overflow. Aber ansonsten eine 
gute Idee, werde ich mir mal noch genauer anschauen.
Gast #527110
Lesenswert?

Was willst du denn übetragen? Wenn's möglich ist das Ganze ASCII zu 
übetragen ist das die einfachste Methode. Einfach Startsequenz (mehrere 
Byte), die Nutzdaten und anschließend eine CRC16-Checksumme schicken. 
Ich habe auf diese Weise Zählerstände Drahtlos übermittelt und bin sehr 
zufrieden mit dem Ergebnis.
Bei Binärdaten ist das Ganze natürlich etwas komplizierter ...
OP #527111
Lesenswert?

Ich muss Messwerte von 10 Sensoren auswerten und dann per USART 
rausschicken. Um die Messwerte zu unterscheiden soll eben eine ID vorne 
angehängt werden.
Da die Sensoren zum Teil mit 1000Hz abgefragt werden, sollten die Pakete 
nicht unnötig groß sein.

Achja, die Messwerte sind also eigentlich nur integer Werte.
Gast #527122
Lesenswert?

Vergiss die ganzen Posts oben !

Stell deine Schnitstelle auf 1 Startbit, 8 Datenbits, 1 Stopbit ein.
Um Startbit und Stopbit musst du dich NICHT kümmern. Das macht
die Hardware. Was am Ende rauskommt sind einfach die 8 Datenbits.
Wenn du die vernünftig formatierst kann nichts schief gehen.

1:Byte ID   wahrscheinlich um auszuwerten wofür das Paket gut ist
2:Byte n    gibt an wieviele Datenbytes empfangen/gesendet werden
3:Byte 0    erstes Datenbyte
4:Byte 1    zweites Datenbyte
.
.
.
.           letztes Datenbyte
Gast #527123
Lesenswert?

Natürlich kannst du das Gaze auch binär übertragen, wie du das codierst 
bleibt dir überlassen. Am Ende eine CRC-Prüfung, dann klappt das auch. 
Aber grade wegen der Starterkennung ud IDs ist ASCII eben einfacher.
OP #527124
Lesenswert?

ja so hatte ich das bisher, nur ohne ein Byte mit der länge.
Dann konnte ich aber halt nie unterscheiden wann ein Paket zu ende war. 
Aber auf die Idee einfach ein Byte mit der Anzahl der Bytes zu senden 
bin ich nicht gekommen :-(
Ich werde mal testen ob das so funktioniert. Und ob Labview das dann 
korrekt entschlüsseln kann.
Kennt jemand sonst noch ne Software die so etwas visualisieren kann?
#527128
Lesenswert?

>1000Hz
Und an welche Baudrate hast du gedacht?

Wie wäre es denn, wenn du ein Paket "schnürst", das die Werte der 
Sensoren der Reihe nach überträgt.
Interessant ist auch, Temperaturen mit 1kHz abzufragen (vermutlich 
irgendein Verbrennungsprozess, da sich die Raumtemperatur in längeren 
Intervallen ändert...).
OP #527134
Lesenswert?

Baudrate? Was der Controller so bringt :D Momentan läufts mit 38400, 
aber da ist nach oben ja noch etwas Luft.
Wie meinst du der Reihe nach? Da gibts das Problem das manche Sensoren 
eben mit 1kHz (wobei dies noch nicht sicher ist) und manche nur mit 10Hz 
oder weniger abgetastet werden. Also sollten diese schon sobald ein Wert 
anliegt verschickt werden.

@Sonic
Der Empfänger läuft eigentlich bevor der Sender sendet, das sollte 
erstmal nicht so schlimm sein. Oder hast du grad nen Lösungsvorschlag 
parat?
Gast #527140
Lesenswert?

Ich habe das bei einem Drahtlossystem so gemacht: EIN Master der alle 
Slaves nacheinander abfragt. Als Start eine Präambel 0x55 (ist ein 
Rechtecksignal), danach 2x 0xFF (High-Signal bekannter Länge), hierauf 
wird der Start der Daten eingeleitet, danach kommen Daten. Am Ende 
CRC16-Checksumme. Alles was dazwischen kommt kannst du dir einteilen wie 
du willst.
Wenn die Messstellen natürlich willkürlich senden wird's komplizierter.
Gast #527141
Lesenswert?

>Ich muss Messwerte von 10 Sensoren auswerten und dann per USART
>rausschicken. Um die Messwerte zu unterscheiden soll eben eine ID vorne
>angehängt werden.
>Da die Sensoren zum Teil mit 1000Hz abgefragt werden, sollten die Pakete
>nicht unnötig groß sein.

Autsch !

10 Sensoren a 2 Bytes plus eine ID.
Also sagen wir mal 3 Bytes * 10 mit 1kHz.
Das sind 30000 Bytes/s. Bei 8 Datenbits mit 1 Start/Stop Bit
sind das 300000 Bits /s. Das macht deine serielle Schnittstelle
sicher nicht mehr mit !

#527154
Lesenswert?

Bei der Übertragung von Datenstrings über die serielle Schnittstelle 
gibt es eine primäre Gefahrenquelle!

Und die heisst Synchronisationsverlust.

Das heisst, es gibt keine eindeutige Identifikation, an welcher Stelle 
des Datenstrings man sich gerade befindet.
Da in einem binären Datenstring jedes Datenbyte das andere in seinem 
Wert ersetzen kann, ist es möglich, daß das Protokoll sozusagen außer 
Tritt gerät.

1. Möglichkeit:
Trennung von binären Datenstrings durch eine Zeitlücke, wobei 
gewährleistet sein muß, daß die Abstände zwischen den Datenbytes im 
String immer kleiner als die Austastzeitlücke ist.
Im Binären Datenstring können Startbyte, Zählbyte, Datenbytes den 
gleichen Wert annehmen. Sollte im Protokoll ein Fehler auftreten, kann 
der Anfang des Strings nicht mehr eindeutig identifiziert werden.

2. Möglichkeit:
Wie von Sonic schon beschrieben, die Daten als ASCII Werte übertragen.
Daher 1 Byte als 2 Zeichen. Dafür brauchst Du dann zwar die doppelte 
Übertragungsrate, hast aber ein Ultra-felxibles Protokoll. Zeitlücke 
kannst Du Dir sparen.
Wie hoch ist denn Dein Datenaufkommen???

Gast #527159
Lesenswert?

Also die Sensoren werden vom µC abgefragt und aud einen PC (oder 
ähnlich) per USART übertragen? Dann sammle die Messergebnisse bis der 
letzte Sensor abgefragt ist und schicke das Ganze in einem festgelegten 
Protokoll 'raus.
Ob da jetzt ein Sensor 10x abgefragt wird ist gegenstandslos, der 
langsamste gibt den Übertragungsrhytmus vor.
OP #527163
Lesenswert?

@sonic
und gerade das will ich nicht! Die Sensoren sollen schon mit 
Unterschiedlicher Frequenz abgetastet werden und verschickt werden.

Das Datenaufkommen kann ich noch nicht genau bestimme. Zur Test und 
Kalibrierungsphase sollen die Sensoren so oft abgefragt werden wie der 
Sensor es her gibt. Dabei müssen nicht alle 10 Sensoren unbedingt 
übertragen werden.
Im späteren Flugbetrieb reicht es sicher wenn man die Abtastrate runter 
setzt. Nur um das zu beurteilen sollen am Anfang alle Sensorwerte 
übertragen werden.
Gast #527164
Lesenswert?

Noch ein Vorschlag nach dem gar nicht gefragt wurde. Wenn es nur 10 
Sensoren sind, dann würden ja 4 Bit reichen, um die Sensoren zu 
identifizieren. Bleiben von einem Byte noch 4 Bit übrig (angenommen man 
sendet 8Bit pro Byte) um die länge zu definieren. Man könnte also noch 
zwischen 0 und 15 oder 1 bis 16 Datenbyte senden, falls das reicht. So 
reicht ein Byte für Identifikation und Anzahl der Bytes (Problem ist, 
dass dann in diesem Byte auch fast jede Information auftauchen kann und 
ein ausgelassenes Byte die gesamte Kommunikaiton total aus dem Tritt 
bringt...

Gast.
Gast #527166
Lesenswert?

@holger
>Deine Rechnung geht nicht auf ;) Nicht alle 10 Sensoren werden mit 1kHz
>abgefragt.

Danke für die fehlenden Informationen. Ich geh jetzt schlafen
und morgen interessierts mich einfach nicht mehr ;)
Gast #527177
Lesenswert?

Andere Variante, ungefähr orientiert an PPP(async): 0xFF trennt Pakete. 
Kommen im Paket die Codes 0xFE oder 0xFF vor, wird zuerst 0xFE 
übertragen, danach das ursprüngliche Byte XOR 0x20.

Ergibt eindeutige Trennung der Pakete, und kostet anders als Base64 oder 
andere Recodierungen webder nennenswert Bandbreite (~1%) noch 
Rechenleistung.
OP #527179
Lesenswert?

@holger

da stehts ;)
> Wie meinst du der Reihe nach? Da gibts das Problem das manche Sensoren
> eben mit 1kHz (wobei dies noch nicht sicher ist) und manche nur mit 10Hz
> oder weniger abgetastet werden.

@gast
nein das geht leider auch nicht. Ich brauch noch platz für mehrere IDs. 
Also 6 Bit bräucht ich mindestens.
Gast #527180
Lesenswert?

>Die Sensoren sollen schon mit Unterschiedlicher Frequenz abgetastet werden und 
verschickt werden.
Da kriegst du ja jede Menge Kollisionen 'rein, wie soll denn das gehen?
Was für einen BUS benutzt du da? Mit CAN geht das meises Wissens, mit 
I²C auch. Aber mit RS232 wird das nicht funktionieren!
Gast #527285
Lesenswert?

Google mal nach "Consistent Overhead Byte Stuffing"... Eine ziemlich
einfache und dennoch geniale Lösung, um sämtliche 0x00-Bytes aus den
Nutzdaten herauszufiltern um die 0x00 dann als Trennzeichen verwenden zu
können; und das bei annähernd garkeinem Overhead.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren