Für die Serie Mein Weg in das IoT habe ich mit zwei kleinen Eval-Boards gearbeitet, die mit einem 32-Bit-Controller ESP32, einer Antenne und einer Micro-USB-Buchse ausgestattet waren (letztere dient gleichzeitig zur Stromversorgung und zum Upload von Programmen). Der Controller lässt sich einsteigerfreundlich über die Arduino-IDE programmieren, denn der Hersteller Espressif stellt hierfür ein Bibliothekspaket (ESP32 Arduino Core) zur Verfügung. Man bekommt somit über die bekannten Arduino-Funktionen wie digitalWrite(...) und analogRead(...) Zugriff auf die ESP32-Pins, die praktischerweise auf Stiftleisten geführt sind. Auch für die WLAN-Funktionalität wurden Wrapper geschrieben, so dass sich ein ESP32 zum Beispiel mit der üblichen Arduino-Methode WifiClient.connect(server,port) mit einem Server verbinden kann.

Um den Zustand eines kleinen IoT-Prototypen zu visualisieren, kann man natürlich LEDs (auf einem Steckbrett) benutzen, was ich in der Serie auch vielfach getan habe. Mehr Möglichkeiten hat man mit einem Display. Und so wurde ich neugierig, als ich hörte, dass wir im Elektor-Shop auch ein ESP32-Entwicklungsboard mit integriertem OLED anbieten. Das OLED auf dem „Wemos Lolin ESP32 OLED“ wird von einem SSD1306-Controller gesteuert, der seine Befehle vom ESP32 via I²C erhält. Das monochrome OLED kann 128 x 64 Pixel darstellen.

Auf das Steckbrett damit

Das Foto zeigt das kompakte Board, Stiftleisten werden mitgeliefert.
 

Nach dem Einlöten kann das Board auf ein Steckbrett aufgesteckt werden; allerdings ist es so breit, dass bei den üblichen Steckbrettern (die bei uns im Labor zu finden sind) leider nur eine Reihe von Löchern frei bleibt, über die man Pins des ESP32 erreichen kann. Ich musste mich bei der Kontaktierung also für eine Seite des Boards entscheiden.



Ein Blick auf das Pinout (siehe Bild) zeigt, dass die obere Seite für viele Experimente genügen sollte; hier stehen genug analoge und digitale I/Os zur Verfügung. Der Reset-Button befindet sich übrigens auf der Unterseite, er ist nur zugänglich, wenn Sie das kleine Board wie ich über den Rand des Steckbrettes herausragen lassen. Allerdings habe ich den Reset-Button im Betrieb nicht benötigt. Programme laufen zuverlässig nach jedem neuen Hochladen sowie nach jeder Unterbrechung der Stromversorgung an.

Das OLED wacht auf

Ich war gespannt, das OLED zum ersten Mal in Betrieb zu nehmen. Beim Googeln nach Demo-Programmen stieß ich zuerst auf das Projekt von johnnyfrx. An einem analogen Eingang wird die Spannung gesampelt, die über einem Fotowiderstand abfällt; der Wert wird anschließend auf dem OLED-Display angezeigt. Um das OLED anzusprechen, nutzte Johnny die Library SSD1306.h, die auf GitHub bereitsteht. Um die Bibliothek zu „installieren“, musste ich lediglich das ZIP (esp8266-oled-ssd1306-master) von GitHub herunterladen, entpacken und in den Libraries-Ordner der Arduino-IDE ziehen.
Danach habe ich einen Fotowiderstand an den GPIO-Pin 39 angeschlossen (von 3,3 V aus, an Pin 39 kommt noch ein 10-k-Widerstand nach Masse).
Nach dem Kompilieren und Hochladen des Demo-Programms von johnnyfrx zeigte das OLED-Display (hurra!) die gesampelten Werte an, brilliant und scharf, wie man es von den selbstleuchtenden Displays gewöhnt ist.

Einfache OLED-Steuerung

Nun konnte ich mir einmal den Code des Sketches ansehen. Um einen Text-String darzustellen, wurden folgende Funktionen der SSD1306-Lib aufrufen:
 
display.clear();
display.setColor(WHITE);
display.setTextAlignment(TEXT_ALIGN_CENTER);
display.drawString(64, 5, DisplayText);
display.setFont(ArialMT_Plain_24);
display.display();

Das Ganze habe ich mir natürlich gleich in einer Funktion void DisplayPrint(String DisplayText) gekapselt.
Ein Blick in die Library zeigte, dass diese nur die Schrift Arial unterstützt, allerdings mit drei Schriftgrößen; sie sind über die Schlüsselworte ArialMT_Plain_24, ArialMT_Plain_16 und ArialMT_Plain_10 erreichbar. Verwendet man ArialMT_Plain_16, dann sind 3 Zeilen a 12 Zeichen gut darstellbar. Und prima ablesbar ist das Ganze auch noch, selbst wenn man wie der Autor nicht mehr der Allerjüngste ist.
Einen Zeilenumbruch kann man einfach erreichen, indem man das Zeichen „\n“ an die entsprechende Stelle des Strings einfügt.

MQTT und OpenSenseMap

Jetzt wollte ich natürlich auch noch „was mit WLAN“ probieren. Ich bin ja nicht faul, aber effizient, und so griff ich einfach zur Demoanwendung meines letzten Reviews, bei dem ich das ESP32 Pico Kit benutzt habe. Die Werte, die der ESP32 über einen Fotowiderstand (Zufall) sampelte, wurden dort über MQTT zum frei zugänglichen Testbroker test.mosquitto.org geschickt. Auf openSenseMap.org hatte ich eine „SenseBox“ angelegt, mit einem Sensor namens „Light_ESP32“. Dort kann man einstellen, dass die Werte per MQTT von einem beliebigen Broker abgeholt und angezeigt werden, auf Wunsch auch in einem Diagramm über der Zeit.
Sie erinnern sich vielleicht auch, dass ich die Adresse des Testbrokers, die SensorID für OpenSenseMap sowie das Topic und das Format der Payload für die MQTT-Messages auf einer kleinen Konfigurationswebseite eingeben konnte. Diese liefert der ESP32 über einen Webserver in einem selbst aufgespannten WLAN aus (per Browser über die Adresse 192.168.4.1 zu erreichen).

Einen Fotowiderstand hatte ich ja nun schon angeschlossen, nach Anpassung der Pinnummer sollte meine damalige Anwendung auch auf dem Lolin-Board laufen. Nach dem Upload des Programms stellte ich fest, dass Werte zum MQTT-Broker liefen (MQTT Dash ist eine nützliche Smartphone-App, um das zu checken). Die Werte wurden auf OpenSenseMap aber nicht aktualisiert; das Icon meiner bisher verwendeten SenseBox zeigte sich auf der Karte auch ausgegraut. Ich legte deshalb eine neue SenseBox an, die ich in unserem Redaktionsbüro in Aachen lokalisierte. Nach Eingabe der neuen SensorID in mein Konfigurationsformular wurden die Werte auf OpenSenseMap dargestellt. Der Screenshot zeigt meine SenseBox in Aachen (direkt neben der Wetterstation-SenseBox meiner Labor-Kollegen).


 

Status-Infos auf dem OLED

Was ich noch nicht angeschlossen hatte, war eine RGB-LED, die mir bis jetzt immer so schön den Status der Verbindung angezeigt hatte. Doch ich hatte ja jetzt ein OLED-Display! Ich schrieb das Programm so um, dass die momentanen Werte der globalen Variablen
 
byte RouterNetworkDeviceState;  // eingeloggt oder nicht

und
 
byte MQTTClient_Connected;       // mit dem Testbroker verbunden?

regelmäßig auf dem OLED-Display dargestellt wurden. Dazu kam die neue Variable TCPClient_Connected, welche anzeigt, ob die TCP-Verbindung zu test.mosquitto.org erfolgreich zustande kam. In MQTTClient_LastCommand wird gespeichert, welches MQTT-Kommando gerade ausgeführt wurde (CONNECT, PUBLISH oder das regelmäßige PING). Außerdem auf dem OLED dargestellt werden noch ein Zähler für die bis jetzt publizierten Nachrichten (MQTTClient_PublishCount) sowie der letzte aufgenommene Sensor-Wert (SENSOR_LastValue).
Bei jedem Durchlauf der loop-Schleife zähle ich außerdem einen Byte-Zähler hoch; das letzte Bit (0 oder 1) wird ebenfalls fortlaufend auf dem Display dargestellt. Dies ersetzt das Dimmen der RGB-LED, was bisher das Zeichen war, dass der ESP32 auch zwischen dem Versenden der MQTT-Nachrichten noch „lebt“.

Um für zukünftige Projekte gerüstet zu sein, wo eventuell wieder eine oder mehrere LEDs oder vielleicht ein anderes Display als „Graphical User Interface“ dienen werden, habe ich mir noch drei Funktionen geschrieben, welche diese Statusanzeige kapseln. GUI_Setup() bereitet das GUI vor, in diesem Fall das OLED. GUI_Update() gibt aufgefrischte Statusinformationen aus, während GUI_Heartbeat() irgendeine Ausgabe tätigt, die als Lebenszeichen für den ESP32 dient. In diese Funktionen kommt der eigentliche Code der Anzeige. In allen Funktionen, welche mit TCP, MQTT oder dem Verbindungsstatus zu tun haben, werden dann nur noch diese GUI-Funktionen aufgerufen, aber beispielsweise keine RGB-LED mehr direkt angesprochen.

Wie immer können Sie mein kleines IoT-Gerät nachbauen. In meinem letzten Review finden Sie Hinweise zum Anlegen einer SenseBox und zur Einstellung des ESP32-Sensorknotens über die Konfigurationswebseite.
Den neuen Arduino-Sketch kann man unten herunterladen. Sie müssen die im Unterordner liegenden Bibliotheksfiles in den Arduino-Unterordner libraries ziehen. Auch die SSD1306-Library brauchen Sie natürlich, laden Sie wie ich das ZIP von GitHub herunter und legen Sie den extrahierten Ordner ebenfalls in libraries.
Viel Spaß beim Ausprobieren und Abwandeln meines IoT-OLED-Projektes!