Forum: Mikrocontroller und Digitale Elektronik Einfaches RS232 "Protokoll" entwerfen um Datenpakete zu senden


von Florian H. (viper2000)


Lesenswert?

Hallo,

ich möchte vom PC zum Mikrocontroller per UART (RS232) einen 
Steuerbefehl (1 byte), dann 64 byte Nutzdaten + CRC in einem Datenpaket 
senden. Leider bin ich mir nicht ganz sicher wie man solch einen 
Datenverkehr sicher implementiert.

Man müsste ja sowas wie eine "Datenpaket Start" Bytefolge einführen 
damit der uC weiss wann ein neues Paket beginnt. Da meine 64 byte 
Nutzdaten aber beliebige Werte von 0x00 bis 0xFF annehmen können, würde 
ja dann unter Umständen auch im Datenpaket selbst darauf reagiert werden 
und der uC würde denken dass ein neues Paket kommt.

Vielleicht kann mir ja mal jemand auf die Sprünge helfen wie man sowas 
möglichst sicher machen kann...

Viele Grüße!

von Abdul K. (ehydra) Benutzerseite


Lesenswert?

Dein Paket ist immer gleich lang? Dann ist die einfachste Lösung: Ein 
Leerlauf-Signal vor der Übertragung des Datenpakets auf der Leitung, 
welches länger als das Datenpaket ist. Block-Sync ist dann immer 
gegeben.

Oder nimm das BREAK. Es gibt noch viele weitere vordefinierte Kommandos 
in ASCII.
Und les mal über HDLC, SDLC, CRC, ECC nach.

Man kann auch eine weitere Modulationsebene ins Datepaket packen. z.B. 
Manchester. Dann wirds allerdings länger und kostet mehr Zeit und 
Energie.

Es gibt viele Wege nach Rom.

von Klaus (Gast)


Lesenswert?

Sieh dir mal SLIP an (== Serial Line Internet Protocol), dort kannst du 
zumindest sehen wie man Nutzdatenpakete (in dem Fall IP-Pakete) so 
verpacken kann dass man Anfang und Ende beim Senden über die serielle 
RS232 Leitung wieder sicher erkennt !!!

von Jens (Gast)


Lesenswert?

Hallo!

Ich sende meine Datenpakete als String im ASCII Code. Als 
"Startbedingung" sende ich ein "A". Danach folgen die Daten (Zahlen von 
0 bis 255), gefolgt von einem Trennzeichen (z.B. ein Komma). Als 
"Endbedingung" sende ich dann ein "V" und damit ist dann die Übertragung 
abgeschlossen. Das funktioniert bei mir problemlos...

LG Jens

von Florian H. (viper2000)


Lesenswert?

Ja mein Datenpaket ist immer gleich lang. Genau 67 bytes.
Man könnte tatsächlich ein Zeichen öfters senden als das Datenpaket lang 
ist. Allerdings hat man dann ziemlich viel overhead :)

Ich muss mir die zeitlichen Bedingungen mal ansehen ob ich mir das 
leisten kann. Fürs erst werde ich es wohl mal so runterprogrammieren. 
Ein Anheben der Baudrate ist auch noch drin...

von Wilhelm F. (Gast)


Lesenswert?

Wenn es keine völlige Neuentwicklung sein soll, kann man sich auch mal 
das TC57-Protokoll anschauen. Da sind schon einige 
Sicherheitsmechanismen drin, und eignet sich zum Betrieb mit einem 
Master und mehreren Slaves.

In verschiedenen Bereichen ist es vorgeschrieben, z.B. in der 
Energietechnik und in der Straßenverkehrstechnik.

von Mäckel Eppentosch (Gast)


Lesenswert?

Wilhelm Ferkes schrieb:
> TC57-Protokoll

Wo kann man da was finden?

von Wilhelm F. (Gast)


Lesenswert?

Mäckel Eppentosch schrieb:

> Wo kann man da was finden?

Ich hatte in Gurgle gleich eine Seite Treffer zum Begriff 
"TC57-Protokoll".

Allerdings ist es eine IEC-Norm, und natürlich eine gute Frage, ob man 
die Protokollbeschreibung auch tatsächlich frei zugänglich findet. Ich 
würde da einfach mal die Gurgle-Suchergebnisse etwas abklappern, und 
ansonsten, falls sich nichts ergeben sollte, abwarten, vielleicht weiß 
ja hier noch jemand anders was. Ich weiß es eben nicht ganz genau. Aber 
das Protokoll existiert schon!

von Reinhard Kern (Gast)


Lesenswert?

Hallo,

ich empfehle in jedem Fall, lesbaren Text zu übertragen, das erleichtert 
Test und Fehlerfindung ungemein. Dann erhebt sich auch die Frage nach 
der Synchronisation nicht mehr, z.B. kann man das vorgesehene 
ASCII-Zeichen STX als Start verwenden und CR als Abschluss.

Auch bei lesbarem Text kann die Einteilung des Records fest sein 
(leichter zu programmieren), z.B. 3 ASCII-Zeichen pro Byte für 000..255 
oder 2 für 00..FF, ganz nach Geschmack. Dann ist ein Komma zwischen den 
Daten überflüssig, liest sich aber besser. Eine Prüfsumme wird genauso 
kodiert, beispielsweise mit 4 Hex-Stellen.

Gruss Reinhard

von Abdul K. (ehydra) Benutzerseite


Lesenswert?

Jens schrieb:
> Hallo!
>
> Ich sende meine Datenpakete als String im ASCII Code. Als
> "Startbedingung" sende ich ein "A". Danach folgen die Daten (Zahlen von
> 0 bis 255), gefolgt von einem Trennzeichen (z.B. ein Komma). Als
> "Endbedingung" sende ich dann ein "V" und damit ist dann die Übertragung
> abgeschlossen. Das funktioniert bei mir problemlos...
>

Du hast sein eigentliches Anliegen überhaupt nicht verstanden. Er möchte 
eine transparente Übertragung. Nach deiner Methode könnte er A und V 
nicht mehr als Inhalt senden.



@Florian:
Schau dir mal APRS an. Da sind alle Sachen schon implementiert.

von Mr. K. (kaktus-)


Lesenswert?

Reinhard Kern schrieb:
> ich empfehle in jedem Fall, lesbaren Text zu übertragen, das erleichtert
> Test und Fehlerfindung ungemein. Dann erhebt sich auch die Frage nach
> der Synchronisation nicht mehr, z.B. kann man das vorgesehene
> ASCII-Zeichen STX als Start verwenden und CR als Abschluss.

Das empfehle ich auch.

ich habe mir einfach ein paar Kommandos mit 3 Buchstaben 
zusamengestellt.

rst  = read Status
wcb  = write Config Byte
rcb  = read config Byte
rst  = reset

Der Controller antwortet mit *rst255
oder *rcf128
etc.

von Mr. K. (kaktus-)


Lesenswert?

Und wenn mehrere Bytes gelesen werden, dann verwende ich ein Komma als 
Trennzeichen.

PC: rst CR

µC:  *rst255,255,255CR

Alles est mal mit hterm testen, dort kann man sich Kommandos anlegen.
Erst wenn alles geht dann Programm zu Anzeige der Daten umsetzten.

Hierzu empfehle ich Profilab

von Rene Z. (renezimmermann)


Lesenswert?

Hallo,

vereinbare drei Zeichen die im Datenstrom nicht mehr vorkommen dürfen 
und drei Zeichen die diese ersetzen.

Sagen wir mal:
1
#define Startbyte = 0x55
2
#define Stopbyte = 0xAA
3
#define Sonderbyte = 0xCC
4
#define ErsatzStartbyte = 0x88
5
#define ErsatzStopbyte = 0x33
6
#define ErsatzSonderbyte = 0x11

Nun noch die Bytes filtern:
1
if(aktByte == Startbyte){
2
   SendeByte(Sonderbyte);
3
   SendeByte(ErsatzStartbyte);}
4
else if(aktByte == Stopbyte){
5
   SendeByte(Sonderbyte);
6
   SendeByte(ErsatzStopbyte);}
7
else if(aktByte == Sonderbyte){
8
   SendeByte(Sonderbyte);
9
   SendeByte(ErsatzSonderbyte);}
10
else{
11
   SendeByte(aktByte);
12
}

Jetzt sendest du das Startbyte dann die Anzahl der Bytes die noch folgen 
und dann deine Daten. Hinten dran noch irgend ein CRC deiner Wahl, dann 
das Stopbyte, fertig. Die Längenangabe, die Daten und den CRC natürlich 
durch den Filter.

Gruß Rene

von Wilhelm F. (Gast)


Lesenswert?

Reinhard Kern schrieb:

> ich empfehle in jedem Fall, lesbaren Text zu übertragen, das erleichtert
> Test und Fehlerfindung ungemein.

Das Intel-Hex-File z.B. hat ja aus Redundanzgründen auch nur rein 
lesbaren Text, alle Hex-Ziffern sind ASCII-codiert.

An den ASCII-Zeichensatz würde ich mich auch halten, dafür ist er ja da.

In C hat man da wunderbare Hilfsfunktionen zum Ausfiltern, wie isdigit, 
upperchar, lowerchar, und einiges mehr.

Falls sich zu TC57 nichts konkretes findet. Das ist für Hobbyanwendungen 
eventuell auch zu oversized, wenn auch sehr sicher. In der Firma war das 
mal ein vollgestopfter Aktenordner, rein nur die Protokollbeschreibung. 
Und mit der Software war immer irgend jemand beschäftigt, nur zur 
Wartung. Die Erstellung der Software war auch nicht ganz ohne, das war 
schon alleine ein kleines Paketchen. Eher doch was für Profis. Aber es 
war vom Feinsten.

Was man da als Luxusfunktionen implementieren kann, ist erst mal die 
Prüfsumme, und einen Lifecounter, der zyklisch reihum ständig überprüft, 
ob alle Busteilnehmer noch leben. Vielleicht eine variable Framelänge. 
Das sollte für den Anfang so gehen.

Und FIFOS in der seriellen Schnittstelle sind natürlich auch Pflicht, 
das erleichtert die Programmierung der Controller ungemein.

Am Anfang würde ich erst mal einen einfachen starren Frame gestalten, 
den Rest dann nach und nach.

von Abdul K. (ehydra) Benutzerseite


Lesenswert?

Naja. Bis man den Ordner mehrfach gelesen hat, hat man auch die 
Grundlagen ergoogelt oder erfragt (hier z.B.) und kann sich ein eigenes 
Protokoll basteln. Zumindest ich tue mich mit Fremdinput immer schwer. 
Ich war aber auch schon in der Schulzeit bei Gedichtenlernen eine Niete.

Da muß man also stark überlegen. Hängt auch sehr von der eigenen 
Umgebung ab. Tools usw.

von xcdark (Gast)


Lesenswert?

Was, wenn nun plötzlich rein zufällig im Datenstrom das Sonderbyte und 
ein Ersatzbyte auftauchen?

Wesentlich sinnvoller wäre ein Filter, der ein in den Daten 
auftauchendes Startbyte bzw. Stopbyte schlicht verdoppelt.
Das Startbyte sei z.B. 0x55, somit wird 7c:48:3a:45:6e:55:ff:12 zu 
55:7c:48:3a:45:6e:55:55:ff:12. Sieht der Empfänger ein einzelnes 
Startbyte, handelt es sich also tatsächlich um eines, bei einer geraden 
Anzahl von Startbytes hintereinander sind es Daten, bei einer ungeraden 
Anzahl ein echtes Startbyte gefolgt von einem Pseudostartbyte.

von Wilhelm F. (Gast)


Lesenswert?

Apropos Lifecounter:

Das war mir ja lange auch nicht so bewußt, bis ich da mal was selbst 
entwickeln mußte.

Früher in der Fernmeldetechnik bei Anlagen, zwitscherte es mehrmals 
sekündlich auf der Leitung (im Prüfhörer). Bei still stehenden Geräten. 
Von den Monteuren wußte aber auch keiner, was das war. Nur, daß man eine 
aktive Leitung erwischt hatte.

Die Geräte kommunizieren also bei Stillstand mit der Anlage. Der Master 
kommuniziert mit den Slaves, ob sie noch da sind.

von Uwe .. (uwegw)


Lesenswert?

xcdark schrieb:
> Was, wenn nun plötzlich rein zufällig im Datenstrom das Sonderbyte und
> ein Ersatzbyte auftauchen?

So geht es richtig:
http://de.wikipedia.org/wiki/Escape-Sequenz#Escape-Sequenzen_in_C_und_verwandten_Programmiersprachen
Man nimmt ein Zeichen als Markierung, das ein besonderes Symbol folgt. 
Kommt dieses Sonderzeichen selbst in den Daten vor, wird es verdoppelt.

(im Grunde entspricht das deiner Lösung, nur das die Auswertung beim 
Empfänger noch präziser formuliert wird: wenn zwei Sonderzeichen 
hintereinander kommen, wird eins davon wieder entfernt. Dazu muss man 
also immer nur zwei Zeichen betrachten, und nicht eine ganze Folge 
durchzählen.

von Christian R. (supachris)


Lesenswert?

Wir benutzen meistens das Protokoll des LMX9820 (ein Bluetooth Modul). 
Das klappt gut und dank Längenangabe und Checksumme kann man falsch 
empfangene Pakete verwerfen und dann passt es.

von noips (Gast)


Lesenswert?

Wenn die Paketlänge fest ist, dann kann ja folgendes helfen:

Du lässt auf der Empfängerseite nach dem Start-Byte die ankommenden 
Bytes zählen. Etspricht der Zählerstand der Paketlänge und wird ein 
Stop-Byte erkannt, so setzt du den Byte-Zähler zurück. Wenn dann in den 
Nutzdaten ein "Start-Byte" vorkommt, dann weißt du anhand des 
Zählerstandes, dass es kein echtes Start-Byte ist. Auf diese Weise läuft 
bei uns schon einiges.

von Abdul K. (ehydra) Benutzerseite


Lesenswert?

Das klingt mir aber sehr nach Schwierigkeiten, wenn die Verbindung auch 
nur leicht gestört ist.
Die Spreu vom Weizen trennt sich spätestens bei einer Funkverbindung.

von JojoS (Gast)


Lesenswert?

DUST3964R von Siemens ist ein Protokoll das sich rel. einfach umsetzen 
lässt und weit verbreitet ist. google findet auch schnell Infos und 
Codesnippets dazu, z.B. http://www.c-plusplus.de/forum/58610-10
Die Pakete bekommen ein STX (Startzeichen) und ETX (Endezeichen) sowie 
eine Checksumme. Wenn ein Byte aus dem Protokoll in den Daten liegt wird 
ein DLE vorangestellt.
Darauf aufbauend gibt es noch ein CP512, dann kannst du sogar SPS 
kompatibel werden.

von noips (Gast)


Lesenswert?

Abdul K. schrieb:
> Das klingt mir aber sehr nach Schwierigkeiten, wenn die Verbindung auch
> nur leicht gestört ist.
> Die Spreu vom Weizen trennt sich spätestens bei einer Funkverbindung.

Die oben vorgeschlagenen Lösungen mit Verdoppelung von Pseudostartbytes 
sind aber genauso störanfällig, haben aber dazu noch den Nachteil, dass 
Daten noch senderseitig "codiert" und empfängerseitig "gefiltert" werden 
müssen.

von Abdul K. (ehydra) Benutzerseite


Lesenswert?

Bei meinem Vorschlag wird nichts gefiltert. Es gibt genau zwei Dinge:
1. Eine Pause, die etwas länger als die Länge des Datenpakets ist. Der 
Empfänger wird erst aktiv, wenn diese Pause abgelaufen ist.
2. Ein Mitzählen der Datenbytes im Paket. Stimmt die Länge nicht, wird 
es verworfen.

Es artet wieder in eine Diskussion über wer hat den Längsten aus. Lassen 
wir das bis der Frager sich konkreter meldet.

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.