ESP Mikrocontroller 8266

Wifi und MQTT | Messwerte im Netz bereitstellen



Quellen: H. Baumgärtner, P. Kraut, R. Rahm, ZSL Esslingen, 2021
Ch. Götz, D. Obermaier, "PUB/SUB for the masses - An introduction to MQTT", Internet of Things Conference, 2014
J.-P. Mens, "MQTT dient dem Admin für viele ungewöhnliche, aber nützliche Anwendungen", Linux Magazin, 11/2015

Im Internet der Dinge werden physische Objekte im Internet vernetzt. Dies bedeutet bspw. das Sensordaten im Internet bereitgestellt werden oder Aktoren aus dem Internet gesteuert werden.

Um die Sensordaten im Netz bereitzustellen benötigen wir:

  1. eine Wifi-Verbingung des ESP-Controllers,
  2. MQTT, ein Protokoll mit dem die Daten versendet werden.

connect to Wifi ESP Wifi-Verbindung



Das Wifi-Modul befindet sich direkt neben der blauen LED. Für die Wifi-Verbindung müssen wir die Bibliothek ESP8266WiFi.h einbinden. Diese beinhaltet alle notwendigen Methoden für den Verbindungsaufbau mit SSID und Passwortes des Wifis:

  • WiFi.begin(ssid, password): baut die Verbindung zum Wifi auf,
  • WiFi.status(): liefert nach Verbindungsaufbau den Wert WL_CONNECTED,
  • WiFi.localIP(): liefert die IP-Adresse des ESP-Controllers.
ESP mit Wifi-Modul neben leuchtender blauer LED
#include <ESP8266WiFi.h>
const char* ssid = "IoT";
const char* password = "IofT2022"; 
WiFiClient espClient; 	// WiFi-Client Objekt erzeugen

void setup() {
  Serial.begin(9600);
  wifiConnect();
}
void loop() {
  if ( WiFi.status() != WL_CONNECTED ) wifiConnect();
  delay(2000);
}

void wifiConnect() {
  WiFi.begin(ssid, password);
  Serial.println("Wait for connection");
  while( WiFi.status() != WL_CONNECTED ){
    delay(500); Serial.print(".");
  }
  Serial.println();  Serial.print("Connected to ");  Serial.println(ssid);
  Serial.print("IP address: ");  Serial.println(WiFi.localIP());
}
				

Der Wifi-Verbindungsaufbau wird in einer eigenen Methode void wifiConnect(){..} ausgelagert. Diese startet mit WiFi.begin(ssid, password); den Verbindungsaufbau und wartet in einer while-Schleife solange, bis die Verbindung steht.

Der Verbindungsaufbau kann am Seriellen Monitor der Arduino IDE beobachtet werden. Am Ende der Methode wird noch die SSID und die IP-Adresse ausgegeben.

Beachte: Anstatt die SSID und das Passwort in einer Konstanten als Zeichenkette zu speichern, können diese auch als Makro hinterlegt werden:
#define SSID "IoT"

Arbeitsauftrag 1 Wifi connected

ESP Wifi Programm

Ein Programm für die Wifi-Verbindung wird geschrieben, verifiziert, kompiliert und auf den ESP-Mikrocontroller geladen.

  1. Gib den Code im geöffneten Sketch ein und speicher die Datei unter einem aussagekräftigen Namen.
  2. Verifiziere den Code und übertrage das Programm auf den Mikrocontroller.
  3. Teste die Funktion mit dem seriellen Monitor. Durch betätigen des Reset-Tasters kannst Du das Programm neu starten, um den Verbindungsaufbau am seriellen Monitor zu sehen.
  4. Ersetze eine Konstante mit dem Makro #define ....
  5. Ersetze die Methode Serialprint(..) durch die Methode printf(..), um einen kürzeren Quelltext zu erhalten.

MQTT Message Queuing Telemetry Transport



MQTT publish and subscribe

MQTT ist ein schlankes offenes IoT-Netzwerkprotokoll für die direkte Kommunikation zwischen Geräten im Netzwerk. Nachrichten benötigen eine geringe Bandbreite und funktionieren auch auf eingeschränkten Geräten. Für MQTT-Nachrichten ist der Port 1883 reserviert.

Clients verbinden sich mit einem Server, dem sogenannten MQTT-Broker und können Nachrichten publizieren (publish) oder Nachrichten abonnieren (subscribe) und so auf das Eintreffen von Nachrichten warten. Später werden wir einen Broker auf dem Raspberry Pi installieren. Zu Beginn arbeiten wir einfach mit dem öffentlichen Broker HiveMQ (broker.hivemq.com). Der Broker empfängt, verwaltet und versendet alle Nachrichten.

Im Gegensatz zu HTTP gibt es kein Polling durch den Client, sondern der Broker informiert den wartenden Client, sobald eine Nachricht vorliegt. Damit nicht jeder jede Nachricht erhält, werden die Nachrichten anhand von Topics unterschieden und ein Broker kann diese anhand von Access Control Listen (ACL) regeln.

Nachrichten sind sogenannte Payloads, welche häufig als einfache Strings versendet werden: "T = 23 °C". Will ein Client eine Temperatur vom Wohnzimmer im EG erfahren, abonniert er die Topics: temperatur/wohnen/eg. Mit temperatur/+/eg abonniert er alle Temperaturen im EG und mit temperatur/wohnen/# abonniert er die Temperatur aller Wohnzimmer. Man beachte, dass + für eine Topic Ebene steht und mehrfach verwendet werden darf, während # für diese und alle folgenden Ebenen steht und einmalig verwendet wird. Ob ein Client alle Nachrichten sieht entscheidet allerdings die Broker-ACL.

Benötigte Software:
Der MQTT Explorer ist ein MQTT Client, mit dem Topics gesendet, empfangen und visualisiert werden können.

MQTTool ist ein MQTT Client für IOS.

MQTT Dash ist ein MQTT Client für Android.

use MQTT with your ESP MQTT Nachrichten versenden



Um mit dem ESP MQTT Nachrichten zu versenden, benötigen wir folgende Bibliothek

Werkzeuge>Bibliotheken verwalten...>
by Nick O'Leary PubSubClient
Boardverwalter Installation
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include "DHT.h"

const char* ssid = "piwifi-a0xx";
const char* password = "piuserwifi";
const char* mqtt_client = "schule1";      // hier eindeutigen Namen vergeben!!
const char* broker = "broker.hivemq.com"; // Adresse des MQTT-Brokers

#define DHTPIN  02
#define DHTTYPE DHT11

WiFiClient espClient;                     // WiFi-Client Objekt
PubSubClient client(broker, 1883, espClient);
DHT dht(DHTPIN,DHTTYPE);
				

Die drei Bibliotheken für Wifi, MQTT und DHT11 werden zuerst eingebunden.

Als nächstes werden SSID, Wifi-Passwort, MQTT-Client und Broker als konstante Werte hinterlegt. Dabei ist darauf zu achten, dass jeder Client eine einzigartigen Namen hat.

Dann wird noch ein Makro für den DHT-Pin (hier D4) und den DHTtyp hinterlegt. Abschließend werden noch die drei Objekte erzeugt.

Neben der Methode void wifiConnect(){..}, wird nun noch die Methode void mqttConnect(){..} für den MQTT-Verbindungsaufbau benötigt.

void mqttConnect(){
  while (!client.connected()) {
    Serial.println(); Serial.println("Connect to Broker..");
    if (client.connect(mqtt_client))        //Starte MQTT-Verbindung...
      Serial.println(mqtt_client);
  }
}
				
void setup() {
  Serial.begin(9600);
  dht.begin();
  wifiConnect();
}
				

Der Setup umfasst den Start der seriellen Verbindung, die Initialisierung des DHT-Sensors und den Wifi-Verbindungsaufbaus.

Im Loop wird nun der MQTT-Verbindungsaufbau gestartet und mit der Methode void client.publish(String topic, String message){..} eine Nachricht mit MQTT alle 5 s veröffentlicht.

void loop() {
  if (!client.connected())  mqttConnect();

  client.publish("klasse/messwerte/name", "T: 9°C");
  delay(5000);
}
				
  float hum   = dht.readHumidity();
  float temp = dht.readTemperature();            

  char messageBuffer[25];
  sprintf(messageBuffer,"%4.1f°C", temp);
  client.publish("klasse/messwerte/name", messageBuffer);
				

Möchte man die realen Messwerte verschicken, werden nach dem MQTT-Verbindungsaufbau im Loop, die Sensordaten ausgelesen, die Messwerte in einem Array mit der Methode sprintf(..) zwischengespeichert und anschließend mit MQTT alle 5 s veröffentlicht.

JSON Notation JavaScript Object Notation



JSON ist eine Notation in der Daten in einem kompakten Format bereit gestellt werden. Das Format ist unabhängig von der Programmiersprache und die Datei erhält die Endung "json".

{
  "Temperatur": 21.8,
  "Luftfeuchte": 32.0
}

Ein JSON-Dokument beginnt und endet mit der geschweiften Klammer. Jeder Schlüssel steht in Anführungszeichen und nach einem Doppelpunkt folgt der Wert des Schlüssels. Für die Werte gibt es unterschiedliche Datentypen.

  1. Zeichenkette: "Mustermann"
  2. Ganze Zahlen oder Kommazahlen: 21.8
  3. Array: [23, 21, 25]
  4. Objekte (untergeordnete Liste): {..}
  5. Nullwert: null

In der Notation sind die Absätze nicht erforderlich, erleichtern aber die Lesbarkeit. Wir können die Methode sprintf(...) nutzen um die Daten in das JSON-Format zu bekommen. Der Vorteil besteht nun darin, dass die Daten im MQTT-Explorer visualisiert werden können und die Daten so direkt in eine Datenbank exportierbar sind.

  //Messwerte im Json Format
  sprintf(messageBuffer,"{\"T\": %4.1f , \"H\": %4.1f}", cTemp,hum);
  client.publish("klasse/messwerte/supper", messageBuffer);
				

Arbeitsauftrag 2 MQTT publish

ESP MQTT Programm

Ein Programm für das versenden von MQTT-Nachrichten (publish) wird geschrieben, verifiziert, kompiliert und auf den ESP-Mikrocontroller geladen.

  1. Lies den Artikel "MQTT dient dem Admin für viele ungewöhnliche, aber nützliche Anwendungen" aus dem Linux-Magazin durch und notiere Dir die wesentlichen Inhalte.
  2. Installiere den MQTT-Explorer auf Deinem Rechner.
  3. Gib den Code für ein erstes MQTT-Programm in einem neuen Sketch ein und speicher die Datei unter einem aussagekräftigen Namen. Das Programm soll einfach eine Nachricht übertragen.
  4. Übertrage das Programm und teste die Funktion zuerst mit dem seriellen Monitor. Durch Betätigen des Reset-Tasters kannst Du das Programm neu starten, um den Verbindungsaufbau am seriellen Monitor zu sehen. In einem zweiten Schritt abonniere das Topic am MQTT-Explorer und prüfe, ob die Daten ankommen.
  5. Erweitere das Programm so, dass die Messwerte übertragen werden.
  6. Speicher die Meswertdaten in einem Array im JSON-Format. Wenn Du alles korrekt programmiert hast sollten die Daten im MQTT-Explorer als Diagramm darstellbar sein.

XML Notation Extensible Markup Language



XML ist eine Notation in der Daten in einer hierarchischen Struktur bereitgestellt werden. Die Daten werden in sogenannten Elementen in einer Baumstruktur angeordnet und in einer Datei mit der Endung "xml" gespeichert..

<!-- Ich bin die Kopfzeile -->
<?xml version="1.0"?>
<!-- Ich bin das Wurzelelement -->
<kunden>
  <!-- Ich bin ein Element mit Attribut -->
  <kunde id="1">
  </kunde>
</kunden>

Alle Elemente werden bis auf die Kopfzeile wie bei HTML in ein öffnendes und schließendes Tag geschrieben. Dabei hat jedes Dokument ein Wurzelelement und es können Attribute in Elementen vergeben werden. Auch Kommentare sind möglich.

DOM Document Object Model

DOM ist ein Standard der W3C, um auf XML-Dokumente zuzugreifen oder sie zu verändern. DOM stellt ein XML-Dokument als Baumstruktur dar und besteht aus Knoten.

XML DOM-Struktur

Wichtige Funktionen zum Programmieren des ESP



WiFi WLAN-Standard (engl. wireless fidelity)
SSID Name des Wifi
MQTT MQTT ist ein IoT-Netzwerkprotokoll für die direkte Kommunikation zwischen Geräten im Netzwerk (engl. Message Queuing Telemetry Transport)
der MQTT-Broker empfängt und verteilt die MQTT-Nachrichten
der MQTT-Client kann MQTT Nachrichten abbonieren und publizieren, wenn er mit dem Broker verbunden ist
Document Object Model
die JSON-Notation, -en JavaScript Object Notation ist ein kompaktes Datenformat.
die XML-Notation Extensible Markup Language ist eine hierarchisch strukturierte Notation von Daten.
Document Object Model Das Document Object Model (DOM) ist ein Standard für XML-Dokumente.