ESP Now: Datenübertragung per Funk. Zusatzmaterial zum Artikel in Make 3/22

Wenn ein WLAN nicht verfügbar ist, kann mittels ESP Now eine einfache und kostengünstige Funkübertragung zwischen ESP-Boards aufgebaut werden.

vorlesen Druckansicht
Lesezeit: 8 Min.
Von
  • Thomas Fischer

Wenn die bessere Hälfte ruft, sollte man erreichbar sein. Und damit sind wir mitten im Thema: Meine Werkstatt ist in unserem Gartenhaus (siehe Titelbild des Artikels) untergebracht. Bin ich dort einmal in ein Projekt vertieft, vergesse ich die Welt um mich herum: Das Handy ist stumm geschaltet und im Hintergrund verbreitet mein Radio Musik. Ein Paradies, wie es sicher viele Leser kennen, nicht wahr? In regelmäßigen Abständen versucht allerdings meine Frau vergeblich auf sich aufmerksam zu machen, z.B. weil das Essen gerade heiß dampfend auf dem Tisch steht.

So ging es nicht weiter, es musste eine Lösung her. Deshalb kam mir der Gedanke, einen kleinen Sender zu bauen, der mich aus meinen Gedanken zurück in die Realität führen würde. Die naheliegendste Option war, dazu das Radio auszuschalten. Und als ich an diesem Punkt ankam, fiel mir ein, dass es eigentlich auch ganz sinnvoll wäre, wenn ich meine Werkstatt bereits aufgewärmt betreten könnte, der Heizlüfter also für eine angenehme Temperatur gesorgt hätte. Da ich bei der Einrichtung meiner Werkstatt im letzten Sommer meine Wanduhr heruntergerissen hatte, sollte auch noch eine neue Zeitanzeige hinzukommen.

Die Lösung war dann ESP-Now, den kompletten Artikel lesen Sie in der Make 3/22. Hier geben wir Ihnen noch einige Zusatzinformation über den interessanten Chip MCP23017.

Make 3/22
Cover der Make 3/22 mit Geigerzähler, Raspi-Alternativen, 3D-Scannern und einem Macro-Keyboard

Mehr zum Thema gibt es in Ausgabe 3/22 der Make.

Schauen wir uns zunächst die Pinbelegung an und gehen auf die wichtigsten Punkt ein:

Pinbelegung des MCP23017

(Bild: Datenblatt)

Die mögliche Betriebsspannung liegt zwischen 1,8 und 5,5V was ihn geradezu für den Einsatz mit allen Arten von Microcontrollern prädestiniert. Weiterhin benötigt er nur zwei Anschlüsse zur Ansteuerung, welche per I2C-Bus erfolgt. Wie man auch sehen kann, stehen insgesamt 16 Pins (8xGPAx und 8xGPBx) zur freien Verfügung. Die A- und B-Pins können insgesamt wahlweise als Ein- oder Ausgänge definiert werden. Wichtig für die Programmierung ist, dass die Zählung hier immer mit 0 beginnt!

Doch damit nicht genug. Die I2C-Adresse des Chips ergibt sich durch die Beschaltung der A0-, A1- und A2- Pins (Tabelle 1). Je nachdem, wie sie mit Ground (Logisch 0) oder der positiven Versorgungsspannung (Logisch 1) wie in der Tabelle dargestellt verbunden werden, wird eine eindeutige I2C-Adresse erzeugt, sodass maximal 23=8 MCP2017 angesprochen und Adresskollisionen mit anderen Chips auf diesem Bus verhindert werden können. Damit sollte ausreichend Potential für eine problemlose Erweiterung zum Auslesen von Tastern und dem Schalten von Geräten zur Verfügung stehen. Die einmal aufgebaute Grundschaltung kann also problemlos nachträglich um weitere Chips ergänzt werden. Die Ansteuerung der Ausgänge und Auswertung der Eingaben erfolgt durch Ergänzung des Programms im ESP12-E Modul.

A0 A1 A2 Adresse
0 0 0 0x20
1 0 0 0x21
0 1 0 0x22
1 1 0 0x23
0 0 1 0x24
1 0 1 0x25
0 1 1 0x26
1 1 1 0x27

Tabelle 1: Adressen für den I2C-Bus

Es gibt zwei Arten, wie der MCP23017 von der Arduino-IDE aus angesprochen werden kann:

  1. Direkte Ansteuerung der Register über die wire.h-Bibliothek
  2. Ansteuerung über die Adafruit-MCP23017-Bibliothek

Zunächst versuchte ich es über die Adafruit-Bibliothek, musste aber leider feststellen, dass sie nicht mit dem ESP12-E funktionierte. Möglicherweise liegt es daran, dass die Bibliothek für Arduinos konzipiert ist. Die direkte Ansteuerung ist aber kaum komplizierter, so dass es problemlos möglich ist, den Chip nach Methode eins zu steuern. Damit können die Schalterstellungen am Eingangsbereich einfach ausgelesen und die Beschaltungen am Ausgang ebenso einfach angesteuert werden. In diesem Zusammenhang haben sich die Befehle bitRead(x, n) und bitWrite(x, n, b) als äußerst hilfreich herausgestellt. Diese Befehle funktionieren wie folgt:

bitRead(x, n)

Mit diesem Befehl können die Schalterstellungen an einer Eingangsseite des MCP23017 abgefragt werden. Da ich mir zunächst nicht sicher war, ob die Schalter direkt an die Pins oder mit einem Spannungsteiler als Pull-Down-Widerstand angeschlossen werden sollten, verwendete ich zunächst die letztere Alternative. Dazu legte ich die Pins mittels eines 10k-Widerstandes auf Ground, der Schalter/Taster schloss im gedrückten Zustand zum Pluspol. Das ist jedoch gar nicht erforderlich, da, wie ich später gelesen habe, der Chip bereits intern mit Pull-Down-Widerständen ausgestattet ist. Das Argument x steht für die Variable, in der alle Eingangsstati ausgelesen werden. n gibt an, über welches Bit der Status eines Pins verfügte. Die Zählung startet bei dem rechtesten Bit (least-significant Bit) mit 0.

Ein Beispiel verdeutlicht, wie das gemeint ist: Standardmäßig sind zunächst alle Pins auf Eingabe gesetzt. Wir lesen in x beispielsweise die Eingänge von Register B aus und erhalten folgenden binären Wert in x=b00001011. Das bedeutet, dass die Eingänge GPB0, GPB1 und GPB3 auf High geschaltet sind. Somit erhält man folgende Ergebnisse: bitRead(x, 0)=1, bitRead(x, 1)=1, bitRead(x, 2)=0, bitRead(x, 3)=1, bitRead(x, 4)=0, usw.

Wie mit diesen Ergebnisse im Programm entsprechende Aktionen wie z. B. dem Schalten oder Abschalten eines Relais ausgelöst werden können, zeigt der nächste Befehl:

bitWrite(x, n, b)

Mit diesem Befehl können an der Ausgangsseite des MCP23017 vom Microcontroller Pins auf High oder Low gesetzt werden und damit die im vorigen Punkt genannten Aktionen umgesetzt werden. x steht in diesem Fall für die Variable, die beschrieben werden soll. n gibt wieder an, an welcher Stelle ein Status (Logisch High oder Low) gesetzt werden soll. Auch hier startet die Zählung bei dem rechtesten Bit (least-significant Bit) mit 0. b besteht für den Status High=1 oder Low=0.

Nehmen wir wieder unser Beispiel von eben: Die Pins von Register A sind als Ausgänge definiert und sollen folgende Zustände annehmen x=b00001011:

bitWrite(x, 0, 1) setzt den GPA0 auf High
bitWrite(x, 1, 1) setzt den GPA1 auf High
bitWrite(x, 2, 0) setzt den GPA2 auf Low
bitWrite(x, 3, 1) setzt den GPA3 auf High
bitWrite(x, 4, 0) setzt den GPA4 auf Low
usw.

Damit das Ganze richtig funktioniert, ist wie bereits gesagt, die wire.h-Bibliothek in den Sketch einzubinden. Die Variable x ist als byte zu definieren. Im Setup folgen die Befehle:

Serial.begin(9600);
wire.begin();
wire.beginTransmission(0x20); Das Argument entspricht der Adresse des Chips, wie sie über die Beschaltung von A0, A1 und A2 wie oben beschrieben vorgenommen wurde.
wire.write(0x00); Register A ansprechen
wire.write(0x00); Alle Pins auf Ausgabe setzen
wire.endTransmission();

Sollen die Register A und B auf Ausgabe gesetzt werden, so sind alle Befehle ab wire.beginTransmission(0x20) zu wiederholen. Der erste wire.write-Befehl zum Ansprechen des B-Registers muss dann aber lauten: wire.write(0x01);
Im Loop erfolgt das Auslesen wie folgt:

wire.beginTransmission(0x20);
wire.write(0x13); Spricht die B-Register an
wire.endTransmission();
wire.requestFrom(0x20, 1); Fragt ein Byte ab
x=wire.read(); Überträgt das Byte an die Variable x... Hier folgt dann die Auswertung, wie oben beschrieben

Das Setzen der Ausgänge verlangt folgendes Vorgehen in der Schleife:

wire.beginTransmission(0x20);
wire.write(0x12); Spricht die A-Register an
wire.write(x); Die Beschaltung übermitteln
wire.endTransmission();

Mit diesem Wissen sollte es jedem Leser möglich sein, mein Programm zu lesen und eigene Anwendungen kreieren zu können.

Was sonst noch wichtig im Umgang mit dem Chip ist:

  • Die Stromversorgung erfolgt über Pin 9 an Plus (Vdd) und Pin 10 (Vss) an Ground (Minus)
  • Der Reset-Ausgang an Pin 18 muss an den Plus-Anschluss gelegt werden
  • Für eine sichere Datenübertragung vom ESP-12E zum Chip über die I2C-Schnittstelle sind die Datenleitungen zusätzlich über je einen 4,7k-Widerstand gegen Vdd zu legen (Pullup-Widerstand)
  • Zu beachten ist auch, dass die Nummerierung des A- Registers rechts von unten nach oben und die des B-Registers links von oben nach unten erfolgt!

Wer mehr über den MCP23017-Chip erfahren möchte, findet in den der Kurzinfo Links zu einem umfangreiche Datenblatt und weitere Information.

Videos by heise

(caw)