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:
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.#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"
Ein Programm für die Wifi-Verbindung wird geschrieben, verifiziert, kompiliert und auf den ESP-Mikrocontroller geladen.
#define ...
.Serialprint(..)
durch die Methode printf(..)
, um einen kürzeren Quelltext zu erhalten.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.
Um mit dem ESP MQTT Nachrichten zu versenden, benötigen wir folgende Bibliothek
by Nick O'Leary | PubSubClient |
#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 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.
"Mustermann"
21.8
[23, 21, 25]
{..}
null
{
"Name": "Mustermann",
"Vorname": "Max",
"Alter": 23,
"Hobbys": ["MTB", "Ski", "Lesen"],
"Kinder": [],
"Adresse":
{
"Straße": "Musterstr. 8",
"Ort": "71289 Musterstadt"
}
}
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);
sprintf(..)
Escapesequenzen in der Syntax erforderlich sind.
Ein Programm für das versenden von MQTT-Nachrichten (publish) wird geschrieben, verifiziert, kompiliert und auf den ESP-Mikrocontroller geladen.
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.
<?xml version="1.0"?>
<clients>
<client id="1">
<firstname>John</firstname>
<surname>Doe</surname>
<born>23.09.1992</born>
<address>
<street>232 Washington</street>
<city>San Diego</city>
<zip>92101</zip>
</address>
</client>
</clients>
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.
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 |
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
Document Object Model | Das Document Object Model (DOM) ist ein Standard für XML-Dokumente. |