2.2.2. ESP8266 MQTT Publisher
Als einen Publisher haben wir uns für einen ESP entschieden, da dieser sehr interessant zu programmieren ist und perfekt für Datenerfassung etc. geeignet ist. Ich habe durch meine 2.Projektarbeit beim Prof. Brovkov einen bereits gebrauchten ESP8266 erhalten, der mit einem kleinen Temperaturmesser von Dallas ausgestattet ist. Jedoch funktioniert dieser nicht und ich musste zum alten ESP greifen, der jedoch ungelötet ist und deshalb nur die genaue Uhrzeit, aber nicht die genaue Temperatur ausgeben kann. Der ESP8266 vom Prof. Brovkov sieht so aus:
Hier werden wir auf die verschiedenen verwendeten Bibliotheken und deren Methoden eingehen:
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
<...>
2.2.2.1. ESP8266WiFi Bibliothek
Die ESP8266WiFi Bibliothek erlaubt eine einfache Verbindung zum Internet. Ebenfalls gibt sie einige interessante Methoden mit, bei denen man auf die lokale IP-Adresse oder auch auf den Stats des WLAN-Netzwerks zugreifen kann.
const char* SSID = "WLANNAME"; //addWLAN SSID here (name)
const char* PSK = "WLANPASSWORD"; //Password of your WLAN
Serial.println(SSID);
WiFi.begin(SSID, PSK);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
2.2.2.2. PubSubClient Bibliothek
Diese stellt Funktionen herbei, um eine MQTT-Verbindung herzustellen und zu verwalten. Diese ermöglicht in unserem Programm ein einfaches publishen.
const char* MQTT_BROKER = "141.82.144.70";
Hier wird die gewünschte Broker Adresse eingegeben.
if (!client.connected()) {
Serial.println("Attempting MQTT connection...");
// Connect to the MQTT broker with the device ID
if (client.connect("ESP8266Client")) {
Serial.println("Connected to MQTT broker!");
} else {
Serial.print("Failed MQTT connection, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
return;
}
}
Hier wird erstmal die Verbindung aufgebaut und falls diese nicht aufgebaut wird, versucht er dies nochmal in 5 Sekunden.
client.publish("tel/arduino", jsonString.c_str());
Hiermit published unser ESP8266 die gewünschte Json mit den Daten an den MQTT-Broker. Die Adresse des Brokers wurde vor Beginn der Anwendung festgelegt.
2.2.2.3. ArduinoJson Bibliothek
Mit dieser Json Bibliothek lassen sich einfache JSON-Daten verwalten und erstellt. Diese Json Files werden über das ESP mit Werten wie der Temperatur und der Uhrzeit gesendet.
//json is made
DynamicJsonDocument configJson(1024);
configJson["temperature"] = temperatureStr;
configJson["timestamp"] = epochTimeInSeconds;
//prints json in Serial Monitor
serializeJson(configJson, Serial);
Serial.println();
String jsonString;
serializeJson(configJson, jsonString);
// Publish a test message to the topic "tel/arduino"
client.publish("tel/arduino", jsonString.c_str());
Hier wird ein configJson erstellt, welches eine Temperatur und einen Timestamp beinhaltet. Der Timestamp ist ein Epos-Timestamp. Dieser zählt die Sekunden seit 1970 und ermöglicht den Subscribern, den Zeitpunkt der ermittelten Daten einzusehen. Dazu wird auch im Serial Monitor, quasi als Livefeed, die Json-Dateien zur Schau gestellt. Zum Ende wird diese noch als String verpackt, weil die publish()-Methode nur Strings annimmt.
2.2.2.4. NTPClient Bibliothek
Diese Bibliothek verbindet sich über UDP mit einem Zeitserver, mit dem unser ESP8266-Modul die Uhrzeit erfährt. Dies geschieht übers Internet.
timeClient.begin();
Zu Beginn muss sich nur einmal mit dem timeClient verbunden werden.
timeClient.update();
String currentTime = String(timeClient.getHours()) + ":" + String(timeClient.getMinutes()) + ":" + String(timeClient.getSeconds());
Hier sollte, bei jeder Abfrage der timeClient geupdated werden, sonst wird nur die Startzeit festgehalten und mitgegeben.
2.2.2.5. WiFiUdp Bibliothek
Hier wird diese Bibliothek verwendet um ein UDP-Socket zu erstellen und eine Verbindung zu einem NTP-Server herzustellen. Mit diesem Server lässt sich dann immer die genaue Zeit bestimmen.
const long utcOffsetInSeconds = 7200;//Wintertime its 3600
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds);
Hier wird sich mit pool.ntp.org verbunden. Diese gibt die UTC Zeit an. Da wir in Deutschland UTC +1 haben, muss hier +3600, eine ganze Stunde drauf, gerechnet werden. In der Winterzeit muss mit +7200, also 2h drauf addiert werden.