Forum: Mikrocontroller und Digitale Elektronik Protokoll für serielle Kommunikation zwischen zwei Controllern


von Phillip H. (philharmony)


Lesenswert?

Hallo zusammen,
Ich arbeite mit einer gegebenen Hardware, bei der ein Arduino Due über 
(und nur darüber) rx und tx der seriellen Schnittstelle mit tx und rx 
eines ESP8826 Chips (Beschaltung acc esp07, aber die gpio pins sind 
nicht verbunden) Sprechen kann. Ursprünglich war geplant, den esp über 
AT-Commands anzusprechen, inzwischen gibt es dafür aber eine arduino 
lib, was die Gestaltungsmöglichkeiten enorm erweitert. Ziel ist, dass 
der Nutzer über den ESP-seitigen Webserver, über ein Webinterface, die 
am arduino due hängende Hardware bedienen kann.
Die Funktionalität auf beiden Chips ist kein Problem, und wie gesagt, 
das Hardwarelayout ist vorgegeben, wenn auch nach heutigem Kenntnisstand 
nicht die geschickteste Lösung.
Was mir noch fehlt, ist ein möglichst schlankes und einfaches Protokoll, 
um die beiden Chips mit einander sprechen zu lassen. Klar könnte ich 
selbst was entwickeln, aber warum das Rad neu erfinden?
Fällt euch da was passendes ein? Es soll eine Art Master - Slave - 
Situation sein, ausgetauscht werden Funktionsbefehle und einige wenige 
kleine (8-16bit) Zahlenwerte.
Ideal wäre es, wenn es dafür eine arduino bib gäbe, oder es relativ 
einfach selbst zu implementieren wäre.
Vielen Dank schon mal!

von Patrick J. (ho-bit-hun-ter)


Lesenswert?

Hi

Wie weit sind die Chips voneinander entfernt? -> I²C

MfG

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Phillip H. schrieb:
> Ich arbeite mit einer gegebenen Hardware, bei der ein Arduino Due über
> (und nur darüber) rx und tx der seriellen Schnittstelle mit tx und rx
> eines ESP8826 Chips (Beschaltung acc esp07, aber die gpio pins sind
> nicht verbunden)

Ich hoffe für Dich, daß nicht nur rx/tx verbunden sind, sondern auch 
noch die Signalmasse (GND).

von L. Gaston (Gast)


Lesenswert?

SLIP resp. CSLIP

von Phillip H. (philharmony)


Lesenswert?

Klar, Masse ist zusammen, sind auf einer großen Platine, Distanz ca 2cm.
Wie gesagt, es sind die pins des Hardware uart mit einander verschalten, 
daher wäre i2c ja ein woekaround. Möchte schon dwn serial benutzen.

von DraconiX (Gast)


Lesenswert?

Ich mache in solchen Fällen, eigentlich immer wenn ich Daten über UART 
oder sonstigen selbst-definierten BitBanging empfange / sende, eine 
Abart des MODBUS.


>>> [Start][Adress][Command][Anzahl-n-bytes][Nutzbytes*n][CRC][2*Endbyte]


Wobei ich gerade drum und drann bin meine Biblio dahingehend zu ändern 
das das doppelte Endbyte, wie bei SLIP, abgesichert ist. Denn sollte in 
den Nutdaten dies mal doppelt hintereinander vorkommen - ist die 
Übertragung für die Tonne, da ich in meinem Protkoll das Überwachen des 
Ende der Übertragung an erster Instanz stehen habe, bevor ich überhaupt 
den Inhalt antaste (CRC, Nutzdaten etc...). Da bin ich schon das eine 
oder andere mal hinten runter gefallen.

von Codix (Gast)


Lesenswert?

Diese Fragen wurde in diesem Forum schon 100 fach beantwortet.
Durchsuche einfach mal das Forum. Oder auch das I-Net.
Seid ihr eigentlich inzwischen alle zu bequem einmal selbst zu denken?

Suche einfach mal......

von Phillip H. (philharmony)


Lesenswert?

> Seid ihr eigentlich inzwischen alle zu bequem einmal selbst zu denken?
>
> Suche einfach mal......

Danke für den Ansch***, natürlich habe ich schon gesucht, und auch 
diverse Sachen gefunden. Schwieriger ist es einzuschätzen, was in der 
Praxis taugt und was nicht. Daher habe ich hier gefragt, wer was 
taugliches kennt.

Die Struktur von draconiX macht Sinn, und könnte ich natürlich ao 
implementieren. Ich möchte mich, soweit möglich aber an gängigen 
Standards orientieren, und, sollte es den geben, liest sich das aus den 
Suchergebnisen nicht heraus.
Und wenn es eine fertige Bib dafür gibt, dann umso besser...

von Felix F. (wiesel8)


Lesenswert?


von grundschüler (Gast)


Lesenswert?

genau die gleiche Frage wollte ich hier auch stellen. Mein code sieht so 
aus:
1
//===========================================================
2
/*    Protokoll:
3
4
Header: src                 MP092005
5
    dst
6
    len100
7
    len10
8
    len1
9
    cmd100
10
    cmd10
11
    cmd1
12
    
13
payload
14
15
    crc100
16
    crc10
17
    crc1
18
    Lf - terminate
19
 
20
 
21
*/
22
23
Ziemlich ähnlich zu dem von draconix. Die Zieladresse gehört nach vorne damit sie als erstes ausgewertet werden kann.
24
25
26
//===========================================================

von schundgrübler (Gast)


Lesenswert?

grundschüler schrieb:
> genau die gleiche Frage wollte ich hier auch stellen. Mein code sieht so
> aus:

Genau das ist die Antwort auf alle ähnlichen Fragen.

von Brigitte-Lea Schultess (Gast)


Lesenswert?

Felix F. schrieb:
> https://github.com/firmata/arduino
> https://github.com/firmata/protocol
> https://www.arduino.cc/en/reference/firmata

Genau: firmata

Damit lässt sich jederzeit den ESP gegen ein Programm auf dem PC, resp. 
den DUE gegen ein Programm auf dem PC (nat. mit Pegelwandler dazwischen) 
verifizieren/testen/debuggen.
Ausserdem ist es jederzeit möglich ESP und/oder DUE gegen was anderes 
austauschen, sollte es nötig werden.

von Phillip H. (philharmony)


Lesenswert?

Brigitte-Lea Schultess schrieb:
> Damit lässt sich jederzeit den ESP gegen ein Programm auf dem PC, resp.
> den DUE gegen ein Programm auf dem PC (nat. mit Pegelwandler dazwischen)
> verifizieren/testen/debuggen.

Danke. Es sollen ja aber Due und ESP MITEINANDER sprechen. Firmata ist 
ja, soweit ich verstanden habe, für nC <-> PC gedacht. Oder sehe ich das 
falsch?
LG

von DraconiX (Gast)


Lesenswert?

Phillip H. schrieb:
> Danke. Es sollen ja aber Due und ESP MITEINANDER sprechen. Firmata ist
> ja, soweit ich verstanden habe, für nC <-> PC gedacht. Oder sehe ich das
> falsch?
> LG

Ein bisschen "falsch". Jedes Protokoll kann überall eingesetzt werden, 
du musst nur beiden beibringen dies zu verstehen. Das Protokoll ist ja 
erstmal abgelöst von der Trägerschicht. Wenn du dem ESP beibringst das 
Protokoll zu verstehen dann ist das in Ordnung - Wobei ich persönlich 
diesem Firmata nicht wirklich was abgewinnen kann (Das ist aber eine 
persönliche Präferenz) Deswegen habe ich ein, so wie eigentlich jeder 
andere der viel mit Kommunikation zwischen verschiedenen Geräten zu tun 
hat, seine eigene kleine "Suppe".

Siehe es wie eine gesprochene Sprache: Die Stimme ist die 
Übertragungsschicht (in der EDV z.b. UART, TCP, UDP etc..) und das Wort 
das Protokoll - ist das Wort in einer anderen Sprache z.b. englisch, 
müssen beide Englisch können um sich zu verstehen (das ist das 
Protokoll) aber die Stimme ist davon erstmal abgelößt da man sie immer 
hört auch wenn man sich nicht verstehen kann.

Willst du wirklich ein De-Facto Standard haben - dann nutze MODBUS als 
Protokoll - das ist so dermaßen weit verbreitet in der Industrie das du 
früher oder später immer darüber stolpern wirst. Mich würde es auch 
wirklich wundern wenn es für diese Arduino Geschichte keine MODBUS Lib 
geben würde.

z.b. hier:  http://playground.arduino.cc/Code/ModbusMaster

von Brigitte-Lea Schultess (Gast)


Lesenswert?

Phillip H. schrieb:
> Brigitte-Lea Schultess schrieb:
>> Damit lässt sich jederzeit den ESP gegen ein Programm auf dem PC, resp.
>> den DUE gegen ein Programm auf dem PC (nat. mit Pegelwandler dazwischen)
>> verifizieren/testen/debuggen.
>
> Danke. Es sollen ja aber Due und ESP MITEINANDER sprechen. Firmata ist
> ja, soweit ich verstanden habe, für nC <-> PC gedacht. Oder sehe ich das
> falsch?
> LG

Nicht falsch, nur beschränkt ;-)
Klar ist uC<->PC der Paradefall: da will man zeigen dass man per 'duino 
dem PC fehlende I/Os nachrüsten kann. Der PC hat die Master Rolle 
inne, der 'duino die Slave Rolle beim Dialog über das Firmata 
Protokoll.

Für Dich heisst das: kein Programm für dein DUE schreiben müssen, 
einfach den Firmata Sketch laden.
Deine Aufgabe: für dein ESP ein Programm zu schreiben, welches /wie der 
PC/ Firmata zum DUE spricht. Dem DUE ist es schliesslich egal von wem 
er Firmata Befehle zu Hören bekommt, solange sie korrekt sind.

Als Einstieg könnte auf dem ESP z.B. eine Simple Webseite sein, welche 
ein Textfeld entgegennimmt. Da gibt man den String "a:0:i" ein und dann 
wird intern mit "analog_0.read()" der Spannungswert an Pin A0 gemessen 
und dem Webbrowser angezeigt.

Verständlich jetzt?

von Brigitte-Lea Schultess (Gast)


Lesenswert?

ModBus geht natürlich auch als Universalprotokoll.
Je nach Geschick sitzt du dann aber in der Patsche wenn Du 
gleichzeitig Deine Fehler im DUE wie im ESP suchen musst...

von Brigitte-Lea Schultess (Gast)


Lesenswert?

Es gibt genug Standardprotokolle für solche Aufgaben, inkl. Libs und 
Musterbeispiele.
Man muss schon sehr SEHR gute Gründe haben UND wissen was man tut, um 
solch ein Protokoll neu zu erfinden.

von DraconiX (Gast)


Lesenswert?

Brigitte-Lea Schultess schrieb:
> ModBus geht natürlich auch als Universalprotokoll.
> Je nach Geschick sitzt du dann aber in der Patsche wenn Du
> gleichzeitig Deine Fehler im DUE wie im ESP suchen musst...

DAS hat man bei jedem Protokoll, sei es MODBUS, S0, SLIP, MIDI, Firmata 
oder sonstigem.

Über Firmata bin ich übrigens jetzt hier zum ersten mal gestolpert, muss 
also so ne Arduino Geschichte sein. Ist ne Abart vom Midi-Protokoll - 
mir wäre das persönlich zu restriktiv. Da man auschhließlich 2Byte Daten 
hat, und davon jeweils nur 7Bit zur Verfügung. Zur reinen 
Datenübertragung wäre mir das zu umständlich, und was ist wenn ich ein 
16Bit Wert übertragen will, wenn mir nur 14Bit zur Verfügung stehen? Was 
ist mit 32Bit oder gar 64Bit für z.b. nen Key-Exchange? Dann ist man, 
wenn man das Protokoll wirklich einhalten will an die, an die 
Commanddaten wie z.b. Servo, I2C gebunden? Nee, das ist zu restriktiv. 
Nicht umsonst hat sich ModBus seit ~40 Jahren durchgesetzt. Da ist ja 
SLIP mit der "Sicherung" noch um Welten besser umsetzbar.

von Felix F. (wiesel8)


Lesenswert?

DraconiX schrieb:
> Über Firmata bin ich übrigens jetzt hier zum ersten mal gestolpert, muss
> also so ne Arduino Geschichte sein. Ist ne Abart vom Midi-Protokoll -
> mir wäre das persönlich zu restriktiv. Da man auschhließlich 2Byte Daten
> hat, und davon jeweils nur 7Bit zur Verfügung. Zur reinen
> Datenübertragung wäre mir das zu umständlich, und was ist wenn ich ein
> 16Bit Wert übertragen will, wenn mir nur 14Bit zur Verfügung stehen? Was
> ist mit 32Bit oder gar 64Bit für z.b. nen Key-Exchange? Dann ist man,
> wenn man das Protokoll wirklich einhalten will an die, an die
> Commanddaten wie z.b. Servo, I2C gebunden? Nee, das ist zu restriktiv.

Firmdata ist auch NICHT für die Datenübertragung ausgelegt, sondern für 
die Ansteuerung von (Arduino)Hardware, genau das was der TE sucht. Nicht 
mehr und nicht weniger!

mfg

: Bearbeitet durch User
von DraconiX (Gast)


Lesenswert?

Felix F. schrieb:
> Firmdata ist auch NICHT für die Datenübertragung ausgelegt, sondern für
> die Ansteuerung von (Arduino)Hardware, genau das was der TE sucht. Nicht
> mehr und nicht weniger!

Hab ich das Eingangsposting falsch gelesen?!

...

Phillip H. schrieb:
> Was mir noch fehlt, ist ein möglichst schlankes und einfaches Protokoll,
> um die beiden Chips mit einander sprechen zu lassen.

Firmata ist weder schlank noch einfach.

Phillip H. schrieb:
> ... ausgetauscht werden Funktionsbefehle und einige wenige
> kleine (8-16bit) Zahlenwerte.

Wie oben schon gesagt, sehe ich bei 16Bit über Firmata schon die ersten 
Probleme. Und ja, das zählt für mich als Datenübertragung von Werten.

von Felix F. (wiesel8)


Lesenswert?

Phillip H. schrieb:
> Ziel ist, dass
> der Nutzer über den ESP-seitigen Webserver, über ein Webinterface, die
> am arduino due hängende Hardware bedienen kann.

Phillip H. schrieb:
> Es soll eine Art Master - Slave -
> Situation sein, ausgetauscht werden Funktionsbefehle und einige wenige
> kleine (8-16bit) Zahlenwerte.

Das lässt sich jetzt interpretieren wie man will.

Entweder will er 8-16 Bit Befehle senden um eben die Hardware (Pins etc) 
anzusteuern (Wofür Firmdata ausgelegt ist) oder er meint, dass er er 
einfach nur irgendwelche Software "auf" der (Arduino)Hardware ansteuern 
will.



mfg

DraconiX schrieb:
> Firmata ist weder schlank noch einfach.

Jeder will schlanke und einfache Software, da die eigene meist nur 
Bloatware ist.

: Bearbeitet durch User
von Phillip H. (philharmony)


Lesenswert?

Ja das hatte ich schon verstanden, ich hatte eben gedacht, es gäbe was 
das genau dafür schon was von Ratiopharm :)
Aber wahrscheinlich ist es wirklich einfacher, selbst was zu bauen.
Hatte überlegt, da die Datenmenge recht klein, und die Zeitliche 
Komponente unkritisch ist, mit grob an i2c zu orientieren, und die 
standard ASCII-Steuerzeichen zu verwenden.
Also SOH -> Adresse -> ACK -> STX -> ACK -> NBytes -> ACK -> Datenframe 
-> ACK -> Checksumme ACK/NACK...
(Adresse braucht es bei zwei Chips eigentlich nicht, aber vielleicht 
kommt ja nochmal einer dazu)
Etwas unsicher bin ich noch, wie ich ACK einsetze. Bei i2c ist es klar, 
ist ja nur ein einzelner Peak auf der Leitung.
Aber in meinem Fall ja ein ganzes Byte. Würdet ihr nach JEDEM Byte ein 
ACK senden, oder zb nur nach SOH+Adresse -> ACK, STX + Frame + 
Checksumme + ETX -> ACK?

Weitere Frage:
Es soll drei Modi geben, ich nenne sie SET, GET und DO/CMD.
SET + Parameter-ID + Wert weisst den Slave an, einen Parameter zu 
ändern,
GET + Parameter ID weisst ihn an, den Wert eines Parameters 
zurückzuschicken,
DO oder CMD  + Funktions ID weisst den Slave an, irgendeine Funktion 
auszuführen.

Beispiele wären:

- GET MACHINE_STATE
- SET PUMP_PROTECTION_TIME 4500
- CMD START_CLEANING_CYCLE

Würdet ihr dafür zB ^Q, ^R, ^S, also DC1-3 nehmen, also die 
Device-Control Zeichen, andere Zeichen, oder einfach "GET", "SET" und 
"CMD" als String im Datenframe verschicken und in der übergeordneten 
Schicht zu interpretieren?

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Phillip H. schrieb:
> Es soll drei Modi geben, ich nenne sie SET, GET und DO/CMD.
> SET + Parameter-ID + Wert weisst den Slave an, einen Parameter zu
> ändern,

 Vielleicht so:
Beitrag "Re: Kommunikationsprotokoll als Baum definieren?"

 Irgendwann wirst du vielleicht auf mehrere Teilnehmer erweitern,
 dann ist so etwas über RS485 oder CAN(nur Hardware, nicht Protokoll)
 ziemlich einfach zu realisieren.


> Aber in meinem Fall ja ein ganzes Byte. Würdet ihr nach JEDEM Byte ein
> ACK senden, oder zb nur nach SOH+Adresse -> ACK, STX + Frame +
> Checksumme + ETX -> ACK?

 Ein ACK nach jedem Byte ist unnötig und fehleranfällig.
 Kurze Pakete und ACK danach sind viel sicherer, vor allem da man
 beim ACK nur bit7 beim Command setzen muss - leeres Paket als Antwort
 gilt als ACK, ansonsten werden noch angeforderte Daten zurückgesendet.

 P.S.
 Und natürlich brauchen nicht alle Befehle eine Bestätigung (ACK).

: Bearbeitet durch User
von Phillip H. (philharmony)


Lesenswert?

Marc V. schrieb:
>  da man
>  beim ACK nur bit7 beim Command setzen muss - leeres Paket als Antwort
>  gilt als ACK,

Sorry, bei dem Teil hänge ich. Dh command & bit7 zurück = ACK?
Wieso nicht ein festes Zeichen für ACK?

von Brigitte-Lea Schultess (Gast)


Lesenswert?

> Man muss schon sehr SEHR gute Gründe haben UND wissen was man tut, um
> solch ein Protokoll neu zu erfinden.

...was das Gegenteil ist von (so vielen Fragen).

Ansonsten gibt es von Ratiopharm Firmata, ModBus und Konsorten.

von dummschwaetzer (Gast)


Lesenswert?

> Beispiele wären:
>
> - GET MACHINE_STATE
> - SET PUMP_PROTECTION_TIME 4500
> - CMD START_CLEANING_CYCLE
dann evtl SCPI (IEEE 488)

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Phillip H. schrieb:
> Sorry, bei dem Teil hänge ich. Dh command & bit7 zurück = ACK?
> Wieso nicht ein festes Zeichen für ACK?

 Bei 2 Geräten kann das noch gutgehen aber bei mehreren geht das
 bestimmt in die Hose.

 Es sind 6 Zeichen bei einem leeren Paket - bei 38400B dauert es
 ungefähr 1,5ms - es ist nicht viel und ein Paket mit 6Byt Nutzlast
 dauert gerade 3ms.

 Und das bei 38400B - CAN funzt ohne Probleme mit 500KB, das ist
 13 Mal schneller.

 Geschwindigkeit wird oft überschätzt - nur sehr wenige Anwendungen
 brauchen mehr als 10-20 Pakete/sec.

: Bearbeitet durch User
von DraconiX (Gast)


Lesenswert?

Ich glaube er verkompliziert sich diese Geschichte auch ein bisschen, 
wenn du schon TX/RX Verbund hast - dann nutze auch die UART. Im Grunde 
kannst du dir das ganz einfach aufstricken, wenn du nur ein Slave hast - 
z.b. wegen der UART - dann lass die Adresse weg, ich hab mal ein kleines 
Beispiel gemacht:

Du willst z.b. auf dem Arduino PortB Pin5 einschalten - das Command 
heist da z.b. 0x01 dafür. Die Größe sind zwei Byte, einmal der Port und 
einmal die Pins, gefolgt vom Abschluss:
1
Master -> Slave
2
           [Size of->][Data                ]     
3
[Command  ][Size     ][Port     ][Pin      ][CR\LF    ]
4
[0000 0001][0000 0010][0000 0010][0001 0000][1101 1010]

Als ACK kannst du dann entweder die 4 Bytes zurückschicken mit Bit 7 im 
Command gesetzt z.b. wie Marc das meinte, und du hast gleich nochmal die 
Bestätigung das der Slave alles so gemacht hat wie du es wolltest:
1
Slave -> Master
2
[Command  ][Size     ][Port     ][Pin      ][CR\LF    ]
3
[1000 0001][0000 0010][0000 0010][0001 0000][1101 1010]
4
 ^
5
 ACK Bit

Und das schöne an der Size Geschichte ist - du kannst egal welche Werte 
oder Variablen schicken die du magst, ob es nun 1Byte Daten oder 5Byte 
Daten sind - dich begrenzt da nur die Übertragungsschicht.

Um z.b. einen 8Bit Wert auszulesen und man hat sich dafür das Command 
0x03 ausgesucht und für die Variable den Wert 0x01:
1
Master -> Slave    
2
[Command  ][Size     ][Var      ][CR\LF    ]
3
[0000 0011][0000 0001][0000 0001][1101 1010]
4
5
Slave -> Master 
6
[Command  ][Size     ][Value    ][CR\LF    ]
7
[1000 0011][0000 0001][0101 0111][1101 1010]

usw... usw...

von Phillip H. (philharmony)


Lesenswert?

Hm ok ich denke damit kann ich was anfangen. Vielen Dank für die 
Anregungen!
Lg

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.