Um die Daten von Messstationen im Rahmen einer Wetterstation einzusammeln bietet sich MQTT als ein genial einfaches Protokoll an. Man braucht lediglich einen MQTT-Broker , der auf einem Server läuft. Die Messstation sendet dann in festgelegten Zeitintervallen die jeweiligen Messwerte an den Broker.
Bei mir läuft der MQTT-Broker Mosquitto auf einem alten Raspberry Pi. Wer (noch) keinen eigenen MQTT-Broker einrichten möchte, kann auch einen öffentlichen Broker im Internet nutzen, z.B. iot.eclipse.org.
Um die Meldungen des ESP anzuzeigen, kann man z.B. das Programm mqtt-spy benutzen, das es z.B. auf GITHUB gibt.
Hat man ohnehin Mosquitto auf einem Raspi installiert, so kann man die Meldungen auch mithilfe von mosquitto_sub abonnieren.
Im meinem Beispiels-Sketch sendet der ESP in 10-Sekunden-Intervallen unter dem topic esp/uptime die jeweilige Uptime. Das Intervall in Sekunden lässt sich über die Konstante interval einstellen.
Wer gerne zusätzlich Statusmeldungen im Seriellen Monitor sehen möchte, muss die Zeilen mit Serial. … wieder einkommentieren.
Hier nun das Programm (auch zum Download):
#include <PubSubClient.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#define FAKTOR 1000 // 60.000 ms = 1 min
//**** Diese Daten müssen angepasst werden *********************
#define WIFI_AP "meinWLAN"
#define WIFI_PASSWORD "meinPasswort"
#define TOKEN "ESP8266_MQTT_TOKEN"
char clientID[] = "MQTT_UPTIME";
char mqttBroker[] = "192.168.1.5"; // Adresse des MQTT-Brokers
int subNetIP = 1; //IP des Subnets
int myIP = 23; //nur der letzte Block der IP ändert sich
String myHostname = "ESP8266_MQTT";
String mqttSubject = "esp/uptime";
unsigned long lastMessage;
const int interval = 10;
//****** Ende Anpassung *****************************************
WiFiClient wifiClient;
PubSubClient client(wifiClient);
int status = WL_IDLE_STATUS;
void setup()
{
//Serial.begin(115200);
InitWiFi();
client.setServer( mqttBroker, 1883 );
}
void loop() {
if ( !client.connected() ) {
reconnect();
}
if ( millis() - lastMessage > interval * FAKTOR ) { // Update and send only after 30 Seconds
sendMQTTMessage(mqttSubject, upTime());
lastMessage = millis();
}
client.loop();
}
String niceStr(int i) { //Zahlen ggf. mit führender Null
String out = "";
if (i < 10) out += "0";
out += String(i);
return out;
}
String upTime() {
String out = "";
unsigned long up = millis();
up = up / 1000;
int d = up / 86400L; // days
out = niceStr(d) + " d ";
up = up % 86400;
d = up / 3600L; // hours
out += niceStr(d) + " h ";
up = up % 3600;
d = up / 60L; // minutes
out += niceStr(d) + " m ";
d = up % 60;
out += niceStr(d) + " s";
return out;
}
void sendMQTTMessage(String subject, String message) { //hier könnte der Fehler liegen?
char payload[100];
char sub[100];
message.toCharArray( payload, 100 );
subject.toCharArray(sub, 100);
//Serial.print("MQTT-Payload: ");
//Serial.println(message);
//Serial.print("MQTT-Subject: ");
//Serial.println(sub);
client.publish( sub, payload , true);
}
void connectToWiFi() {
WiFi.begin(WIFI_AP, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
// Serial.print(".");
}
//Serial.println("Connected to AccessPoint");
}
void InitWiFi()
{
//Serial.println("Connecting to AccessPoint ...");
// attempt to connect to WiFi network
IPAddress ip(192, 168, subNetIP, myIP);
IPAddress gateway(192, 168, subNetIP, 1);
IPAddress subnet(255, 255, 255, 0);
IPAddress dns(192, 168, subNetIP, 1);
WiFi.config(ip, dns, gateway, subnet); // auf feste IP einstellen
WiFi.hostname(myHostname); //Hostnamen setzen
WiFi.persistent(false);
WiFi.mode(WIFI_OFF);
WiFi.mode(WIFI_STA);
connectToWiFi();
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
status = WiFi.status();
if ( status != WL_CONNECTED) {
connectToWiFi();
}
//Serial.print("Connecting to MQTT_Broker ...");
// Attempt to connect (clientId, username, password)
if ( client.connect(clientID, TOKEN, NULL) ) {
//Serial.println( "[DONE]" );
} else {
//Serial.print( "[FAILED] [ rc = " );
//Serial.print( client.state() );
//Serial.println( " : retrying in 5 seconds]" );
// Wait 5 seconds before retrying
delay( 5000 );
}
}
}
Pingback: Der ESP8266 (ESP-01) – Blog aus der Nordheide