WiFi UDP Y-Netzwerk aus drei Pretzelboards und einem Laptop

Anmerkungen von Fabian Kainka:

Im Sommer dieses Jahres erreichte mich eine Mail von  Dr. Christian Rempel, mit einer Frage zum NanoESP. Im Rahmen eines Jugend forscht-Projektes sollte ein Pflückroboter realisiert werden. Mehrere NanoESP-Boards wurden dafür vernetzt um untereinander und mit einem Laptop Sensordaten auszutauschen. Ganz nebenbei hat das Projekt auch an anderen Stellen Wellen geschlagen, wie hier auf der TEC-IT Homepage. Außerdem ist aus diesem aufregenden Projekt ein Artikel entstanden, der die Problematik sehr gut beschreibt und eine Lösung bietet, die für viele Nutzer sehr nützlich sein sollte. An dieser Stelle möchte ich deswegen den überaus informativen und gut dokumentierten Artikel (sogar in englischer Version) von Dr. Christian Rempel und Laurin Kettner vorstellen. Viel Spaß beim Lesen.

Download: Ernteroboter_Programme

WiFi UDP Y-Netzwerk aus drei Pretzelboards und einem Laptop

Für unseren Ernteroboter Sensor benötigten wir ein Netzwerk aus einem Server (Pretzelboard S), zwei Arduino Clients (Pretzelboards C1 und C2) und einen Laptop als dritten Client (Packet Sender (s. Fabian Kainkas Weihnachtskalender 2016) oder TWedge von der Firma TEC-IT https://www.tec-it.com/de/download/Default.aspx ), um ein kleines UDP WiFi Netzwerk aufzubauen. Wir bezeichnen das als Y-Konfiguration, wobei das Zentrum des Buchstabens durch S gegeben ist, die beiden schrägen Arme symbolisieren dessen Verbindungen zu C1 und C2 und der senkrechte die Verbindung zum Laptop:

Der Aufbau

Der Aufbau

Die Clients können prinzipiell nicht direkt miteinander kommunizieren. Dies kann nur über den Server erfolgen. Eine spezielle Messagestruktur für unsere Zwecke ermöglicht das dennoch. Es sind folgende IP Adressen festgelegt:

  • 192.168.4.1         Server S
  • 192.168.4.2         Client Packet Sender oder TWedge:
  • 192.168.4.3         Client C1
  • 192.168.4.4         Client C2

Packet Sender ist ein Programm, das Fabian Kainka in seinen Weihnachtskalendern verwendet, und es erlaubt Nachrichten zu empfangen und zu senden. TWedge ist ein Programm der Firma TEC-IT, das ebenfalls Senden und empfangen ermöglicht, das aber im Zusammenhang mit einer Excel Tabelle die Visualisierung sehr erleichtert.

Folgende Ids sind vergeben worden:

  • Id = 0                 Client Packet Sender oder TWedge
  • Id = 1                 Client C1
  • Id = 2                 Client C2
  • Id = 5                 Server S

Folgende Ports werden genutzt:

  • 90, 91                 Client Packet Sender oder TWedge:
  • 92, 93                 Client C1
  • 94, 95                 Client C2

Die Sketches haben bei S<umgekehrtes Datum>_<Bezeichnung> die folgenden Bezeichnungen:

  • UDPBidirectional-Server               Pretzelboard S
  • UDPBidirectional-Client1             Pretzelboard C1
  • UDPBidirectional-Client2             Pretzelboard C2

Download: Ernteroboter_Programme

 

Die Sketches lehnen sich an Beispiele an, die von Fabian Kainka in den Weihnachtskalendern 2015 und 2016 gegeben wurden. Der Gebrauch der mit dem Jahr 2016 veröffentlichten Bibliothek erschien uns zu viel von den wirklichen Befehlen zu screenen und wurde im Sinne eines reverse engineering rückgängig gemacht.

Ein großer Nachteil des im Pretzelboard verwendeten ESP8266, zum Beispiel im Vergleich mit Bluetooth Modulen, erscheint uns, dass der Datenverkehr (messages) von den AT Befehlen, die überwiegend der Konfiguration des Moduls dienen, nicht getrennt ist. So werden auch AT Befehle zum Senden benutzt und bei empfangenen Meldungen muss man sich erst vergewissern, ob es sich um eine von außen empfangene Nachricht (message) handelt oder ob das ESP Modul selbst etwas zu sagen hatte (answer).

Meldungen des ESP8266 können entweder messages oder answers sein!

In den originalen Vorlagen werden alle konfigurierenden AT Befehle im Setup des Sketches gegeben, unter Verwendung des Unterprogramms sendCom, in das sie in etwas verklausulierter Form eingehen und dieses auch noch die Antwort des ESP Moduls auswertet, ohne diese vollständig auszugeben.

Bem.: Im Unterprogram SendCom() wird der Ausdruck esp8266.findUntil("OK", "ERROR") verwendet, der true ist, wenn vor  "ERROR" "OK“ gefunden wurde, und false, wenn zuerst "ERROR" gefunden wurde oder wenn beide Strings gar nicht gefunden wurden.

Für die Clients haben wir aus den Beispielen der Bibliothek die Dokumente
NanoESP-1.1\examples\BASICS\WiFi-Connect und …\UDP
als Vorlage verwendet.

Für den Server diente hingegen  Weihnachtskalender Tag 4 und die in diesem zur Verfügung gestellte Bibliothek als Grundlage, deren Verwendung im Sinne besseren Verständnisses wir aber rückgängig gemacht haben.

Die Packet Sender Oberfläche sieht wie folgt aus:

Das Packet Sender Programm

Das Packet Sender Programm

Unter „File“ findet man die Settings, in die Folgendes einzutragen ist:

Packet Sender Settings (1)

Packet Sender Settings (1)

Packet Sender Settings (2)

Packet Sender Settings (2)

Bei TWedge sind folgende Geräte zu definieren:

Twedge Geräte

Twedge Geräte

Eigentlich handelt es sich bei TWedge um einen einzigen Client, aber das Senden und Empfangen ist getrennt und das Programm lauscht als Gerät 2 (UDP Client) und sendet als Gerät 3 (UDP Server). Empfangene Daten können in eine Exceltabelle eingetragen werden und Zellinhalte aus dieser können gesendet werden.

Das Senden und Empfangen mit den quasioriginalen Sketches:

Die fast unveränderten Sketches erlauben Sendebefehle, die folgenden Syntax haben und z.B. über den Seriellen Monitor des entsprechenden Netzteilnehmers eingegeben werden können, der im Übrigen auf Baud 19200 und CR und LF aktiv steht, oder sie können natürlich im Sketch generiert werden:

AT+CIPSEND=<Id>,<messagelength+2>

Die Id ist die o.a. Id des Empfängers. Darauf erscheint im Seriellen Monitor ein Prompt: „>“ und man kann die Nachricht (message) eingeben. Diese sollte dann in dem entsprechenden Empfänger als Meldung

+IPD, <Id>,<length>:<message>

erscheinen, wobei Id hier die Id des Senders und die length die Länge der <message> ist.

Trennung der AT Befehle von der Übertragung von Nachrichten

Man kann die wünschenswerte Trennung der AT Befehle von den Sende- und Empfangsvorgängen realisieren, indem man das Prinzip anwendet, dass AT Befehle nur vom Sketch gesendet werden und über den Seriellen Monitor bzw. von und nach außen reine Nachrichten (messages) ausgetauscht werden. Die message besteht aus eine Nettomessage Msg und einer Id, die für Senden und Empfangen sowie für Server und Clients eine unterschiedliche Bedeutung hat. Diese wird durch Doppelpunkt getrennt (den natürlich Msg nicht enthalten darf) an die Nettomessage angehangen:

message = <Msg> : <Id >
Beispiel: 170pv:1

Sendet ein Client, so kann die Nachricht an einen anderen Client gerichtet sein. Dann heftet er an die Nettonachricht Msg das :Id an, wobei dann Id die final receiver Id (frId) bedeutet. Empfängt ein Client, so kann die Nachricht von einem anderen Client stammen, was er ebenfalls an message erkennt, denn diese hat dann zwar die gleiche Form Msg:Id, aber Id ist jetzt die original sender Id (osId). Id ist also die für die jeweilige Aktion interessante Id, so etwas wie die letztendliche Ziel- oder Absenderadresse, je nachdem, ob es sich um Senden oder Empfangen handelt.

Für die notwendige Bearbeitung der messages sorgt der Server, der der Empfangsnachricht:

+IPD, <osId>,<length>:<Msg>:<frId>

beide Ids entnehmen kann. Ist nicht er selbst der Adressat, sendet er die message weiter, in der Form:

message = <Msg>:<osId>

weil für den final receiver nur der ursprüngliche Absender (osId) von Interesse ist.

Man kann diese Zusammenhänge zusammenfassen, indem bei einer Nachricht (message) der, neben der Nettonachricht (Msg) angegebenen Id jeweils eine andere Bedeutung zukommt. Es ist also message = <Msg>:<Id>, wobei Id die folgenden Bedeutungen an den Netzwerkorten (locations) hat:

 

location sending receiving
Server osId frId
Client frId osId
Message Struktur

Message Struktur

Ist keine Id angegeben oder die Id der location selbst, wie es über den entsprechenden Seriellen Monitor erfolgen kann, so wird die Message an Ort und Stelle ausgewertet. Meldungen, die via ESP, also von anderen locations kommen und eine Nachricht enthalten, haben die Form +IPD, <Id>,<length>:<message>, wobei der String “+IPD,“ zur Unterscheidung von anderen Meldungen des ESP (answers) verwendet werden kann.

Die vielleicht kompliziert erscheinende Anbindung der jeweils interessierenden Id (osID oder frId) an die Nettonachricht Msg zur vollständigen Nachricht (message), ermöglicht es, dass Nachrichten von jedem Netzteilnehmer an jeden anderen geschickt werden können sowie an sich selbst, indem im Falle der Clients der letztendliche Empfänger (frId) in der mesage angegeben wird. Beim Empfangen einer Nachricht (message), erkennt jeder Netzteilnehmer den ursprünglichen Absender (osId).

Will zum Beispiel Client 1 and Client 2 eine Nettonachricht Msg = 123pv senden, sendet er:

<Msg>:<frId> = 123pv:2

worauf nach Durchlauf über den Server bei Client 2 ankommt:

<Msg>:<osId> = 123pv:1. 

Die Programmstruktur

Die der Konfiguration des ESP Moduls dienenden AT Befehle werden im Setup gegeben und sind tlwse. in Unterprogramme ausgelagert (ConfigESP, ConfigWifi, StartCon u.a.), wobei obige IPAdressen festgelegt werden und sich der Netzteilnehmer als Server oder Client (station) definiert.

In der Loop wird eine Hierarchie festgelegt, durch if else Anweisungen, die Meldungen, die über das ESP eingehen, priorisiert, als zweites nach dem Seriellen Monitor geschaut und erst, wenn bei beiden nichts los ist, seinen eigenen Berechnungen nachgeht.

Meldungen über ESP

Geht eine Meldung über ESP ein, kann es sich um den leidigen worst case, eine von diesem selbst generierte Antwort, handeln (self generated answer), wovon zunächst immer ausgegangen wird (Flag: ESPsga = true, ESPsga heißt: suppose ESP self generated answer). Erst wenn beim Lesen vom esp8266 die Sequenz “+IPD,“ erkannt wurde, wird dieses Flag auf false gesetzt (ESPsga = false), was wegen der Alternative bedeutet, dass es sich um eine message von außen handelt. Dann kann die eingegangene Nachricht geparsed (beim Einlesen entschlüsselt) werden und je nach Bedarf vom Server auch in der oben beschriebenen Form weitergesendet. Das Senden ist der einzige (implizite) AT Befehl, der in der Loop gesendet wird, entweder als weitergereichte oder weiterzureichende message oder aus den Rechnungen des jeweiligen Netzteilnehmers hervorgehend. Dafür dient ein weiteres Unterprogramm (WifiSend).

Bem.: Das Einlesen über ESP könnte man eleganter programmieren, etwa, wie beim Einlesen über den Seriellen Monitor verwendet (zB.: readStringUntil), was sich aber als so langsam erwies, dass wir dazu übergehen mussten, nur noch bei jedem Loopdurchlauf ein Character einzulesen, was dann so schnell ist, wie man es sich nur wünschen kann.

Meldungen über den Seriellen Monitor

Beim Einlesen über den jeweiligen Seriellen Monitor zeigte sich keine störende Verlangsamung, sodass dort elegantere Befehle Verwendung finden konnten. Über debug kann man steuern, welche Meldungen auf dem Terminal erscheinen sollen.

Bem.: Zwischen manchen aufeinanderfolgenden Lesebefehlen, die dann nicht funktionierten, hilft ein rettendes delay(1);.

Inbetriebnahme

Die drei Pretzelboards sind an hoffentlich vorhandene drei USB Ports eines Laptops anzuschließen und die Arduino IDE ist dreimal zu öffnen, um unterschiedliche Ports nutzen zu können. In „Werkzeuge“ ist jeweils “Arduino Nano“ und als Prozessor “ATMega328P“ und der entsprechende Com Port auszuwählen. Wenn die Programme für Server und Clients entsprechend hochgeladen sind, sollten nach kurzer Zeit an den Clients beide blauen Dioden leuchten. Über die entsprechenden Seriellen Monitore, die wie oben beschrieben einzustellen sind, kann man die debug Informationen sehen.

Auf dem Laptop erscheint das Netzwerk NanoESP:

Das NanoESP Netzwerk

Das NanoESP Netzwerk

Damit sollte man sich verbinden, worauf man dann allerdings kein Internet mehr hat. Die Firewall ist dann zu deaktivieren:

Firewall deaktivieren

Firewall deaktivieren

Danach kann man von jedem Seriellen Monitor Nachrichten an jeden Netzwerkteilnehmer senden bzw. den Empfang angezeigt bekommen, indem man eingibt:

<Nachricht>:<frId> also zum Beispiel: Ein Brieflein von mir:0

(diese geht dann an den Laptop und entweder Packet Sender oder TWedge).

Wir wünschen viel Freude mit den Pretzelboards, die manchmal zeitweilig den Geist aufgeben, und den Programmen.

Dr. Christian Rempel & Laurin Kettner

Zeuthen im August 2018

 

Refer to AT commands: https://room-15.github.io/blog/2015/03/26/esp8266-at-command-reference/

Download: Ernteroboter_Programme

 

Schreiben Sie einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.