Nachdem der Server bereits läuft und die Definitionen für die Topics festliegen, kann jetzt die Entwicklung der Software folgen. Das Einbinden der Bibliothek erfolgt wie üblich über die IDE.
Aus dem Beispiel mqtt_basic entnehme ich die Grundform für die Clientfunktion für MQTT.
Software
…
// PubSubClient
IPAddress pscsrv(192, 168, 188, 28);
unsigned int pscport = 1883;
PubSubClient pscclient(Ether);
// Funktionen —————————————————————
void setup()
{
DebugPrintInit();
DebugPrint(„Projekt Messtechnik1“);
// LCD
lcd.begin(16, 2); // Anzahl Spalten und Zeilen vom Display setzen
lcd.setBacklight(ON); // Beleuchtung einschalten
lcd.clear(); // erstmal alles loeschen
lcd.home(); // Cursor nach links oben
ActualizeDisplay(); // Werte ausgeben
// RTC
RTCActivate(); // RTC aktivieren
RTCCheckStatus(); // RTC Status einlesen
RTCRead(); // RTC einlesen
ActualizeDisplay(); // eingelesene Werte ausgeben
SaveTimeToFallback(); // aktuelle Zeit merken
RTCStart(); // RTC Clock starten
// DHT11
DHT11Activate(); // Temp-/Feuchtesensor aktivieren
dht.begin(); // Schnittstelle init
DHT11GetInfoTemperature(); // Sensorinformation einlesen
DHT11GetInfoHumidity(); // Sensor Messwerte einlesen
DebugPrint(„———-„);
delayMS = sensor.min_delay / 1000; // Wartezeit berechnen
temperatur = DHT11ReadTemperature(); // Temperaturwert
feuchte = DHT11ReadHumidity(); // relative Luftfeuchte
DebugPrintLongValueUnit(„Verzoegerungszeit: „,delayMS,“ ms“);
ActualizeDisplay(); // eingelesene Werte ausgeben
// Ethernet2
if (Ethernet.begin(mac) == 0)
{
DebugPrint(„Ethernet Fehler – DHCP nicht erfolgreich“);
}
else
{
DebugPrint(„- Ethernet aktiviert -„);
#ifdef DEBUG
Serial.print(„Die IP Adresse ist: „);
for (byte thisbyte = 0; thisbyte < 4; thisbyte++)
{
Serial.print(Ethernet.localIP()[thisbyte],DEC);
if (thisbyte < 3)
{
Serial.print(„.“);
}
}
Serial.println();
#endif
// NTP Abfrage
Udp.begin(localPort);
NTPsendpacket(ip); // Sende NTP paket zum Zeit Server
delay(1000); // Warte auf Antwort
DebugPrint(„- NTP Abfrage -„);
NTPGetTime(); // Antwort einlesen
RTCWrite(); // RTC mit neuer Zeit setzen
// MQTT
pscclient.setServer(pscsrv, pscport); // Client initialisieren
}
starttime = actualtime = millis(); // naechste Minute Wartezeit starten
DebugPrint(„*** Setup abgeschlossen ***“);
}
void loop()
{
uint8_t buttons = (uint8_t)0;
if ((actualtime – starttime) > MINUTE) // Eine Minute ist abgelaufen
{
DebugPrint(„\n– Minute abgelaufen: RTC und Messwerte einlesen“);
RTCRead(); // RTC einlesen
// Messwerte einlesen
temperatur = DHT11ReadTemperature(); // Temperaturwert
feuchte = DHT11ReadHumidity(); // relative Luftfeuchte
CursorBlinkAus(); // Cursor und Blinken aus
ActualizeDisplay(); // Werte ausgeben
starttime = millis(); // Start fuer naechste Minute
MQTTConnectAndPublish(); // Messwerte zum MQTT Server senden
if (buttonpressed == false)
{
RestoreFallbackToTime(); // keine neuen Werte uebernommen
}
else
{
buttonpressed = false; // zurueck auf kein Button gedrueckt
}
} // Innerhalb der minute
actualtime = millis(); // aktuelle Zeit einlesen
CheckTimeOverrun(); // Ueberlauf von millis() oder Programmfehler
buttons = GetButtons(); // Tasten einlesen
CheckButtons(buttons); // Tasten vorauswerten
if (selectbuttonpressed == true) // Select Taste wurde gedrueckt
{
selectbuttonpressed = false; // Select Taste fertig ausgewertet
RTCWrite(); // RTC mit neuer Zeit setzen
CursorBlinkAus(); // Cursor und Blinken aus
ActualizeDisplay(); // Werte ausgeben
curpos = (byte)CURSORMARGINLEFT; // Cursor auf Startposition
lcd.setCursor(curpos,0); // auf Startposition setzen
}
}
// Software – MQTT ————————————————————-
void MQTTConnectAndPublish(void)
{
char tmpstr[4];
char stamp[17];
if (pscclient.connect(„JGE-TL“))
{
DebugPrint(„MQTT verbunden“);
// Den Zeitstempel erzeugen
sprintf(stamp, „%02i.%02i.20%02i %02i:%02i“, tag, monat, jahr, stunde, minut);
// Nach dem connect folgen die Topics
sprintf(tmpstr,“%02i“,feuchte); // Messwert umwandeln in ASCII String
pscclient.publish(„Wohnung/Raum1/Luftfeuchte/Messwert“,tmpstr);
pscclient.publish(„Wohnung/Raum1/Luftfeuchte/Messzeit“,stamp);
#ifdef DEBUG
Serial.print(„Luftfeuchte Messwert: „);
Serial.println(tmpstr);
Serial.print(„Luftfeuchte Messzeit: „);
Serial.println(stamp);
#endif
sprintf(tmpstr,“%02i“,temperatur); // Messwert umwandeln in ASCII String
pscclient.publish(„Wohnung/Raum1/Temperatur/Messwert“,tmpstr);
pscclient.publish(„Wohnung/Raum1/Temperatur/Messzeit“,stamp);
#ifdef DEBUG
Serial.print(„Temperatur Messwert: „);
Serial.println(tmpstr);
Serial.print(„Temperatur Messzeit: „);
Serial.println(stamp);
#endif
}
else
{
#ifdef DEBUG
Serial.print(„MQTT failed, status = „);
Serial.print(pscclient.state());
Serial.println();
#endif
}
}
…
Nun muss die Firewall auf dem Rechner mit dem Server für MQTT auf dem TCP Protokoll noch freigegeben bzw. geöffnet werden. Dann öffne ich für alle vier Topics eine Kommandozeile / Eingabeaufforderung im mosquitto Verzeichnis und starte jeweils für das Topic ein mosquitto_sub -t jeweiligerTopic.
Nachdem ich dann den Client starte, sehe ich jede Minute einen neuen Wert in den Subscriber Kommandozeilen / Eingabeaufforderungen.
Links
MQTT Client für Arduino
http://pubsubclient.knolleary.net/
Mosquitto Dokumentation
https://mosquitto.org/documentation/