Forum: Mikrocontroller und Digitale Elektronik Protokollaufbau


von Ralf N. (ralf25)


Lesenswert?

Hallo lese im Forum schon seid einiger Zeit mit und habe nun selber eine 
Frage.

Und zwar möchte ich ein Master/Slave Protokoll über RS485 aufbauen. Es 
gibt ein Master und mehrere Slaves. Der Master ist der PC und die Slaves 
mehrer µCs. So nun habe ich mir über das Protokoll Gedanken gemacht. Es 
soll ungefähr so aussehen.

1 Byte SlaveAdresse, welcher µC (256 Slaves dürfte reichen)
1 Byte Adresse des Registers (jeder Slave hat ein eigenes internes 
Register)
1 Byte Befehl (lesen oder schreiben, zuviel Overhead?)
1-2 Byte Daten (was ins Register geschrieben werden soll,bzw vom Slave 
die Antwort)
1 Byte CRC16

So das ganze soll nun noch über einen Timeout gesteuert werden, also 
Beginn Übertragung Start des Timers und wenn das Timeout kommt ist der 
Block zu Ende und kann verarbeitet werden.
Die Slaves,µC sollen irgendwelche Peripherie Einheiten haben die 
gesteuert oder ausgewertet werden sollen, z.B
Temperatursensor, Motoren oder ähnliches. Die Daten wie z.B Temperaturen 
werden ausgewertet und ins Register abgelegt.
Der PC liest zyklisch die Register aus und reagiert darauf, z.B schreibt 
er an einen anderen µC das dieser den Motor drehen soll.
Der Motor holt sich aus dem Register den Wert und fährt in der 
Geschwindigkeit. So dachte ich mir das ersteinmal.
Später soll das ganze dann MultiMaster werden, so dass ich nicht mehr 
über den PC "regeln" muss, sonder die µC direkt an den jeweiligen µC 
Befehle senden. Also in etwa eine kleine Hausautomation.
Ist RS485 dafür geeignet? Ich wollte später vielleicht noch auf CAN 
umsteigen. Ist da das Protokoll auch anwendbar?
Und wieviel Aufwand ist es, gleich auf Multimaster umzustellen. Wollte 
erstmal klein anfangen. Bin für jeden Tip dankbar.

Verzeihung für eventuelle Rechtschreibfehler.

: Verschoben durch User
von Udo S. (urschmitt)


Lesenswert?

Ralf Neubauer schrieb:
> 1 Byte SlaveAdresse, welcher µC (256 Slaves dürfte reichen)
> 1 Byte Adresse des Registers (jeder Slave hat ein eigenes internes
> Register)
> 1 Byte Befehl (lesen oder schreiben, zuviel Overhead?)

Ich würde mit dem Kommando starten und danach die Adresse senden, dann 
kannst Du abhängig vom Kommando völlig unterschiedliche Nachrichten mit 
unterschiedlichen Längen implementieren.
Ob dir ein Byte als Adresse reicht musst Du selbst wissen
Wozu noch eine Registeradresse? Du hast Doch schon den Slave mit der 
Adress ausgewählt.

> 1-2 Byte Daten (was ins Register geschrieben werden soll,bzw vom Slave
> die Antwort)
Du denkst zu sehr in Hardware. Du überträgst Kommandos und Daten. Welche 
Daten du überträgst weisst du angand des Befehls oder Kommandos.

> 1 Byte CRC16
Ein CRC16 hat 2 Bytes. Beachte Byte Ordering.

> So das ganze soll nun noch über einen Timeout gesteuert werden, also
> Beginn Übertragung Start des Timers und wenn das Timeout kommt ist der
> Block zu Ende und kann verarbeitet werden.
Timeout Steuerung? Was soll das bringen. Mach als Endekennzeichen ein 
'Magic Byte' das sonst nicht vorkommen darf, oder schreibe am Anfang des 
Telegramms die Gesamtlänge rein, das erleichtert dem Empfänger auch 
genügend Speicher zu reservieren.

> Ist RS485 dafür geeignet?
Das Softwareprotokoll und das Hardware Protokoll sollte vollkommen 
unabhängig voneinander sein. Den Bytes ist es egal wie du sie sendest, 
ob das jetzt Ethernet (TCP/IP) oder RS232 oder RS485 ist.


Du solltest Dir vieleicht mal gängige Protokolle anschauen und versuchen 
zu begreifen warum sie genau so aufgebaut sind wie sie sind.
Außerdem ist es meistens eine gute Idee vorhandene Protokolle zu nutzen, 
dann kann man auch mal mit etwas zugekauftem kombinieren/kommunizieren.
Viel Spass beim Basteln

von matrixx (Gast)


Lesenswert?

Udo Schmitt schrieb:
>> So das ganze soll nun noch über einen Timeout gesteuert werden, also
>> Beginn Übertragung Start des Timers und wenn das Timeout kommt ist der
>> Block zu Ende und kann verarbeitet werden.
> Timeout Steuerung? Was soll das bringen. Mach als Endekennzeichen ein
> 'Magic Byte' das sonst nicht vorkommen darf, oder schreibe am Anfang des
> Telegramms die Gesamtlänge rein, das erleichtert dem Empfänger auch
> genügend Speicher zu reservieren.

Mit dem Senden eines Endzeichens gebe ich dir Recht. Hatte mal das 
Problem, dass ich ein altes DOS-Programm in Linux emulieren wollte (mit 
Hardware-Zugriff). Dies läuft mit fast allen seriellen Geräten (am 
RS485) ohne Probleme. In meinem Aufbau gab es aber einen Teilnehmer, der 
über ein Timeout gesteuert wurde. Bei diesem brach die Verbindung aber 
immer ab, da Linux mitten in einer Nachricht eine Verzögerung einbaute.

LG

von Vorname N. (felixx)


Lesenswert?

Wenn Du ein eigenes Protokoll für RS485 bauen möchtest, dann kannst Du 
Dir auch 'mal die Software zum "Heizungs-Wärmemesser" auf der 
Elektor-Seite ansehen. Dort ist in "Softwarebeschreibung.pdf" ein 
Protokoll beschrieben, das auch Multimaster fähig ist. Darüber hinaus 
ist es "routingfähig", es ist nicht auf "Tiemouts" angewiesen und für 
8-Bit MCUs optimiert. Vielleicht ist das eine weitere Anregung für Dich.
Auch ich schließe mich der Meinung an, daß man bei der Suche nach dem 
"richtigen" Protokoll sich zunächst die vorhandenen und standardisierten 
Versionen ansehen sollte (für 2-Draht Systeme sind das nur als 
Beispiele: Fieldbus, Modbus, CAN usw. usw.).

von Reinhard Kern (Gast)


Lesenswert?

Hallo,

anbei ein praktisch eingesetztes Protokoll:
1
Messageformat:
2
Alle Messages sind als Klartext kodiert, mit einer Prüfsumme am Ende aus „:“, 4 Hex-Zeichen für 16 Bit und
3
CR als Message-Abschluss. Die Prüfsumme ist die Summe aller Zeichen bis einschliesslich des „:“ gekürzt auf
4
16 bit und ausgegeben als 4 Hexadezimal-Ziffern.
5
Request-Messages (vom Rechner zum BPM) beginnen mit „R“ und 2 Ziffern für den Record-Typ, Answer-Messages (vom BPM zum Rechner)
6
stattdessen mit „A“. Die einzelnen Felder enthalten nur Ziffern und sind durch Kommas getrennt, die Feldlängen sind jedoch
7
fest vorgegeben. Notwendig sind alle Felder bis zum ersten Messdatenfeld, nicht belegte Messdaten können weggelassen werden.
8
Aufbau eines Records, Positionen im String und Erklärungen:
9
10
    R00,32,100,2006,06,20,18,51,33,
11
    Rec No Prg Jahr Mo Ta St Mi Sec
12
    1   5  8   12   17 20 23 26 29 (Positionen aller Felder fix)
13
    
14
    0000001,+000001,-000001,001.500,01.5000,-1.5000, ...
15
    Wert1   Wert2   Wert3   Wert4   Wert5   Wert6    ... Wert24
16
    32      40   (max 24 Zahlen mit 7 Stellen Darstellung) max 224
17
18
    :89AB<CR>
19
     16-bit Prüfsumme aller Char ..max 230 
20
Rec  Record-Typ
21
No  Node-Nr  (Gerätenummer und Adresse)
22
Prg  Programm
23
Jahr  Jahr bei Aufzeichnung mit Echtzeit – ist J = 0, so ist die Zeit ab Programmstart angegeben.
24
Mo  Monat bei Echtzeit, siehe Jahr.
25
Ta  Tag
26
Mi  Minute
27
Sec  Sekunde
28
Wertx  Messwerte 1 bis max 24

Node ist die Slaveadresse, Programmnr. und Uhrzeit bezieht sich auf das 
laufende Messprogramm und sind also nur für dieses Gerät relevant.

Anmerkung:
Bei früheren Gerätegenerationen habe ich auch Daten binär übetragen, 
davon bin ich jedoch völlig abgekommen. Wie oben beschrieben, wird alles 
lesbar übertragen, das erleichtert das Testen erheblich. Dass dadurch 
die Datenmenge 2 bis 4 mal grösser wird ist heute ziemlich unwesentlich. 
Das ist nicht nur der Trend bei mir, auch im Internet wird ja alles als 
Text übertragen.

Ich hatte mal ein asynchrones Bitbus-Protokoll entwickelt, da war das 
Mitlesen am Analysator echter Horror.

Gruss Reinhard

von Udo S. (urschmitt)


Lesenswert?

Reinhard Kern schrieb:
> Anmerkung:
> Bei früheren Gerätegenerationen habe ich auch Daten binär übetragen,
> davon bin ich jedoch völlig abgekommen. Wie oben beschrieben, wird alles
> lesbar übertragen, das erleichtert das Testen erheblich. Dass dadurch
> die Datenmenge 2 bis 4 mal grösser wird ist heute ziemlich unwesentlich.
> Das ist nicht nur der Trend bei mir, auch im Internet wird ja alles als
> Text übertragen.
>
> Ich hatte mal ein asynchrones Bitbus-Protokoll entwickelt, da war das
> Mitlesen am Analysator echter Horror.

Hallo Reinhard,
wenn man die Zeit hat, gebe ich dir recht, dann macht lesbar übertragen 
absolut Sinn wegen dem Testen.
Aber bei serieller Übertragung ist das Thema Geschwindigkeit manchmal 
durchaus wichtig.
Und einem Analysator kann man ja vieleicht das Umsetzen des Protokolls 
in Klartext beibringen :-) (Ist schon klar, das macht wieder Arbeit und 
wenn man so ein Ding kauft ist das auch nicht immer möglich)

Gruß Udo

von Karl H. (kbuchegg)


Lesenswert?

Und Timeout

Timeout benutzt man ausschliesslich dazu, um gescheiterte Übertragungen 
zu erkennen.
Als Synchronisiermittel bzw. fixer Bestandteil eines Protokolls zur 
Endeerkennung ist es untauglich. Nicht umsonst hört man beim Funk nicht 
einfach zu reden auf, sondern gibt explizit zu erkennen, dass man fertig 
mit reden ist und der andere reden darf. Over.

von jimjack j. (jimjack)


Lesenswert?

ModbusRTU verwendet Timeouts zur Telegramrkennung bzw. Synchronisation.
Ist zwar nicht so prickelnd, ist aber ein gängiges Protokoll.

Steffen

von Reinhard Kern (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> .... Nicht umsonst hört man beim Funk nicht
> einfach zu reden auf, sondern gibt explizit zu erkennen, dass man fertig
> mit reden ist und der andere reden darf. Over.

Hallo,

bei militärischer Disziplin ok. Bei den meisten normalen Menschen ist es 
eher so, dass man sowieso warten muss, bis sie aufhören zu reden, weil 
sie mal Luft holen müssen...

Grundsätzlich setzt die Verwendung von Timeout den Durchsatz herab, weil 
man ja eine längere Zeit warten muss, bevor es weitergeht, jedenfalls 
länger als die Zeit für ein Sonderzeichen. Und es ist fehleranfällig, 
wenn der Sender nicht garantieren kann, alles unmittelbar nacheinander 
zu senden.

Gruss Reinhard

von Bernd R. (Firma: Promaxx.net) (bigwumpus)


Lesenswert?

Ich arbeite gerade auch so etwas heraus.

Timeout ist nur als Error-Ende zu gebrauchen, es kostet zu viel Zeit, 
weil Du ja immer nur kleine Pakete schickst und darum eher viele Pakete 
geschickt werden (wie bei CAN).
Ich habe am Anfang ein Längenbyte eingeführt, da kann man das Ende 
sauber erkennen oder mit Time-Out abbrechen.
Ein "Magic"-Byte ist auch schwierig, dann muß man gerade dieses Byte bei 
Adresse, Register und Daten vermeiden... geht wohl nur, wenn man reinen 
ASCII-Text überträgt.
Ich habe auch nur so quasi-Multi-Master eingeführt, weil ich in den 
Paketen vom PC eine Absender-Kennung einfüge, die der Slave auch wieder 
mit zurückschickt, so können die PCs die Antworten aussortieren. Ich 
habe hier die Situation, daß nicht mehrere PCs gleichzeitig arbeiten.

von Ralf N. (ralf25)


Lesenswert?

Okay werde mir das alles nochmal genauer betrachten.

CRC16 stimmt 2 Byte ...
Das mit dem Timeout hatte ich von Modbus, der Aufbau des Protokolls ist 
auch wenig abgekupfert und ich fand es passend für mein Protokoll.
Das mit dem Endbit habe ich mir auch überlegt, nur kommt nun bei mir die 
Frage auf, wie siche ist das? Wenn ich längere Leitungen oder Störungen 
auftretten und ein Bit getoggelt wird, bäuchte ich ja auch ein Timeout, 
damit er nicht endlos wartet. Oder ich lege gleich fest, oder gebe das 
im Protokoll mit, dass das Protokoll wirklich nur X Datenpakete hat.

Das mit lesbaren Text zu senden ist ansich eine gute Idee, nur ist bei 
mir wahrscheinlich das Problem, dass ich längere Leitungen haben werde 
(denke mal vorerst 5m, später mehr), was wiederum bedeutet das die 
Baudrate nicht so hoch sein kann.
Also vorerst erstmal binär.

von henne (Gast)


Lesenswert?

Bei RDM wird an Stelle eines CRC eine additive CS gebildet. Ich halte 
dies für die einfachere und schnellere Alternative.

Die Anzahl der Datenbytes im Paket mitzuliefern (bzw. die Paketlänge) 
ist sinnvoll. Allein schon, falls einer der Slaves den Parameter nicht 
kennt.

Ein Problem bei RS485 im Halbduplex ist der Status während eines 
Senderichtungswechsels (Port-Turnaround) - hier sollte der Bus durch ein 
senderseitiges Widerstandsnetzwerk auf IDLE gezogen werden.

Ein Startbyte ist besser als Timeouts oder Breaks.

Viel Erfolg,
Hendrik

von Blackbird (Gast)


Lesenswert?

Ein "Protokoll" ist nicht gleichzusetzen mit "Message" (oder 
"Nachricht").
Wie die Nachrichten aussehen hat erst mal nicht viel mit dem Protokoll 
zu tun.
Ein paar Blicke zum OSI-Modell sind da sehr hilfreich.
Die ausführlichere Vorgehensweise wäre etwa so:
1. Sich eine "Anwendung" vorstellen, z.B. wer hat das Sagen und wer 
bekommt Nachrichten und wer muß sich melden. Den Inhalt der "Messages" 
festlegen.
2. Ein Protokoll ausdenken (oder eins suchen, was paßt) welches diese 
Nachrichten einpackt und verlustfrei und gesichert überträgt. Also mit 
Timeouts, evtl. Kollisionen, Bestätigungen, Re-Transmissions, usw. usf.
3. "Primitives" festlegen zwischen der Anwendungs-"Schicht" und der 
Protokoll-"Schicht", also interne Nachrichten, die zwischen den beiden 
Layern auf jeder Seite ausgetauscht werden müssen.
4. Kontrollieren, Trockentest, Implementieren, Testen und, und, und ...

Es geht auch viel einfacher, aber ob dann alles noch übersichtlich und 
im Fehlerfall auch nachvollziehbar ist, das ist eher unwahrscheinlich.

"Request" sendet der Master, mit Acknowledges bestätigt der Slave. Mit 
"Indication" sendet der Slave was zum Master und bekommt per 
"Confirmation" die Bestätigung.

Was man mit diesem (stark vereinfachten) "Protokoll" dann für "Messages" 
sendet, kann man sich selber aussuchen.
In der Praxis ist es aber noch ein wenig verzickter, siehe CAPI (ISDN) 
oder HDLC.


Blackbird

von heinzhorst. (Gast)


Lesenswert?

Habe mir gerade mal das oben genannte "Heizungs-Wärmemesser"-Protokoll 
von Elektor angesehen. Mag zwar sein, dass alle Teilnehmer dabei eine 
eigene Adresse bekommen und es auch eine Prüfsumme gibt, mit der erkannt 
werden kann, ob eine Nachricht fehlerhaft ist. Aber verhindern, dass 
mehrere Teilnehmer gleichzeitig senden kann man damit nicht. Und das ist 
schließlich der Punkt, um den es hier geht.

von Reinhard Kern (Gast)


Lesenswert?

heinzhorst. schrieb:
> .... Mag zwar sein, dass alle Teilnehmer dabei eine
> eigene Adresse bekommen und es auch eine Prüfsumme gibt, mit der erkannt
> werden kann, ob eine Nachricht fehlerhaft ist. Aber verhindern, dass
> mehrere Teilnehmer gleichzeitig senden kann man damit nicht.

Hallo,

wieso nicht - nur der Slave mit der gesendeten Adresse antwortet, also 
null problemo um Alf zu zitieren.

Ich behaupte das nicht einfach so, ich weiss es, weil meine Geräte seit 
vielen Jahren zuverlässig so arbeiten. Der Steuer-PC fragt reihum ab und 
jedes Messgerät antwortet auf eine Anfrage mit seiner Adresse.

Gruss Reinhard

von heinzhorst. (Gast)


Lesenswert?

Reinhard Kern schrieb:
> Der Steuer-PC fragt reihum ab und
> jedes Messgerät antwortet auf eine Anfrage mit seiner Adresse

Also doch kein Multi-Master Protokoll. Laut dieser Aussage ist dein PC 
der Master und alle anderen Teilnehmer sind Slaves. Nehmen wir nun 
einmal an, du hast zwei oder mehr Master am Bus. Also in deinem Fall 
einen zweiten PC oder einen Embedded Webserver, der auch Daten von den 
Sensoren haben möchte. Wie willst du mit diesem Protokoll sicherstellen, 
dass die beiden (oder drei oder vier) Master nicht gleichzeitig auf dem 
Bus quatschen?

von Reinhard Kern (Gast)


Lesenswert?

heinzhorst. schrieb:
> .... Wie willst du mit diesem Protokoll sicherstellen,
> dass die beiden (oder drei oder vier) Master nicht gleichzeitig auf dem
> Bus quatschen?

Selbstverständlich erstmal überhaupt nicht. Ich entwerfe doch kein 
Protokoll das ich nicht brauche.

Falls doch, wäre das aber auch kein Problem, Master1 fragt ja die 
Clients nacheinander ab, da kann er genausogut zwischendurch auch 
Master2 fragen, ob der mal was sagen will. Der gibt dann genauso zurück 
oder weiter. Bei mir sieht ein Szenario eher so aus, dass der 
verantwortliche Ingenieur im Betrieb die Messreihe verwaltet, aber sein 
Chef im Urlaub auf den Bahamas möchte mal reinsehen. Ich fürchte da ist 
es mit einer Steuerleitung nicht getan.

Im übrigen ginge es auch ohne Änderung, wenn die Anfragen sauber 
serialisiert sind (z.B. über Ethernet): schliesslich können Webserver 
ihre Seiten an tausende User ausliefern, obwohl zwischen denen kein 
Multimaster-Protokoll läuft. Auf eine Anfrage erfolgt eine Antwort, so 
einfach ist das.

Gruss Reinhard

PS Zitat aus dem Ursprungsposting:
Und zwar möchte ich ein Master/Slave Protokoll über RS485 aufbauen. Es
gibt ein Master und mehrere Slaves.

von Vorname N. (felixx)


Lesenswert?

Arbitrierung, also die Verwaltung von Kollisionen auf dem Bus 
funktioniert sicher nur, wenn alle Busteilnehmer synchronisiert senden. 
Beim CAN-Protokoll z.B. wird das mit rezessiven und dominanten Bits im 
ersten Datenbyte gelöst. Ob man nun die Nachrichten nach Priorität 
sortiert (siehe CAN) oder eher die Busteilnehmer ist eine Frage der 
Anwendung. Ohne Echokontrolle, also dem Auslesen vom selbst 
ausgesendeten Byte kommt auch CAN nicht aus und wird wohl allg. keine 
Arbitrierung funktionieren. Aber mit Echokontrolle geht's.

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.