
Ziel des Projekts
Ein ESP-Mikrocontroller misst die Temperatur. Die Daten werden an einen MQTT-Server gesendet, ein zweiter ESP32 empfängt die Daten und zeigt sie auf einem OLED an.
Im Beispiel sendet ein ESP32-Wroom die Daten, ein NodeMCU und ein Arduino Nano ESP32 empfangen die Daten und zeigen sie auf einem OLED an.

MQTT
MQTT (Message Queue Telemetry Transport) ist ein Protokoll für die Übertragung von Daten nach dem Publisher-Subscriber-Modell. Es besteht aus dem Server (Broker) und verschiedenen Klienten. Einer dieser Klienten veröffentlicht (Publish) zu einem Thema (Topic) eine Nachricht und schickt sie an den Broker. Ein anderer Klient sendet eine Anfrage (Subscribe) zum Broker und fragt nach Daten (Payload) zum festgelegten Thema. Sind Daten vorhanden, werden sie übermittelt.

Öffentliche Broker
| Broker | Port | Benutzername | Passwort |
|---|---|---|---|
| test.mosquitto.org | 1883 | ||
| public.mqtthq.com | 1883 | ||
| broker.emqx.io | 1883 | emqx | public |
Benötigte Bauteile
- ESP32 oder ESP8266-Mikrocontroller als Messgerät
- ESP32 oder ESP8266-Mikrocontroller für die Anzeige
- Leitungsdrähte
- OLED
- DHT22
Konfiguration der Mikrocontroller
Der Schaltplan
ESP32-Wroom als Sender, NodeMCU als Empfänger

Das Programm
Benötigte Bibliotheken
![]() | ![]() |
Funktionen der Bibliothek u8g2
| Schlüsselwort | Parameter | Aktion |
|---|---|---|
| begin(); | OLED starten | |
| getDisplayWidth(); | Bildschirmbreite feststellen | |
| getDisplayHeight(); | Bildschirmhöhe feststellen | |
| clearDisplay(); | Bildschirm dunkel schalten | |
| setdrawColor(Parameter) | 0 → schwarz 1 → weiß | Zeichenfarbe festlegen |
| setContrast(Parameter) | 0 … 255 | Kontrast einstellen |
| setDisplayRotation(U8G2_R*); | U8G2_R0 → 0 Grad U8G2_R1 → 90 Grad U8G2_R2 → 180 Grad U8G2_R3 → 270 Grad | Anzeige drehen |
| flipMode(Parameter); | 0 → normale Ausrichtung 1 → 180 Grad drehen wirksam erst bei einer Rotation | Anzeige spiegeln (180 Grad) |
| home(); | Cursor in die linke obere Ecke setzen | |
| drawPixel(x‑Achse, y‑Achse) | einzelnen Pixel zeichnen | |
| drawLine(StartX, StartX, EndeX, EndeY); | Linie zeichnen | |
| drawHLine(StartX, StartY, Länge); | horizontale Linie zeichnen | |
| drawVLine(StartX, StartY, Länge); | vertikale Linie zeichnen | |
| drawFrame(StartX, StartY„ Breite, Höhe); | Rechteck zeichnen | |
| drawRFrame(StartX, StartY, Breite, Höhe, Eckenradius); | abgerundetes Rechteck zeichnen | |
| drawBox(StartX, StartY, Breite, Höhe); | ausgefülltes Rechteck zeichnen | |
| drawCircle(MittelpunkX, MittelpunktY, Radius, Kreisausschnitt); | U8G2_DRAW_UPPER_RIGHT U8G2_DRAW_UPPER_LEFT U8G2_DRAW_LOWER_RIGHT U8G2_DRAW_LOWER_LEFT U8G2_DRAW_ALL | Kreis zeichnen Viertelkreis oben rechts Viertelkreis oben links Viertelkreis unten rechts Viertelkreis unten links voller Kreis |
| drawDisc(MittelpunkX, MittelpunktY, Radius); | Ausgefüllten Kreis zeichnen | |
| drawEllipse(StartX, StartY, RadiusX, RadiusY); | Ellipse zeichnen | |
| drawXBM(StartX, StartY, Breite, Höhe, Array_Bilddatei); | XBM-Bild anzeigen | |
| setCursor(x‑Achse, y‑Achse); | Cursor setzen | |
| setFont(Schriftart) | Beispiele für funktionierende Schriftarten: Schrifthöhe in Pixeln (px) 6px: u8g2_font_5x7_tr 7px: u8g2_font_torussansbold8_8r 8px: u8g2_font_ncenB08_tr 10px: u8g2_font_t0_15b_me 12px: u8g2_font_helvB12_tf 13px: u8g2_font_t0_22_te 14px: u8g2_font_helvB14_tf 17px: u8g2_font_timB18_tf 18px: u8g2_font_lubB18_tr 20px: u8g2_font_courB24_tf 23px: u8g2_font_timB24_tf 25px: u8g2_font_helvR24_tf 32px: u8g2_font_logisoso32_tf 42px: u8g2_font_fub42_tf 58px: u8g2_font_logisoso58_tf 62px: u8g2_font_logisoso62_tn | Schriftart |
| print(“Text”); drawStr(StartX, StartY ‚“Text”); | Text schreiben | |
| setFontDirection(Wert); | 0 → normal ausgerichtet 1 → 90 ° gedreht 2 → 180 ° gedreht 3 → 270 ° gedreht | Schreibrichtung |
Funktionen der Bibliothek ArduinoMqtt
| Schlüsselwort | Parameter | Aktion |
|---|---|---|
| connect() | Name des Brokers, Port des Brokers | Broker verbinden |
| poll(); | Broker abfragen | |
| beginMessage(); print(); endMessage(); | Mindestens Inhalt der Nachricht optional: Länge der Nachricht, auf dem Broker behalten (true/false) Qualität der Übermittlung der Nachricht 0 = Nachricht wird einmal versendet eine Überprüfung des Empfangs durch den Broker findet nicht statt 1 = die Nachricht wird solange versendet, bis der Broker den Empfang bestätigt hat 2 = die Nachricht wird einmal gesendet es wird sicher gestellt, dass die Nachricht beim Broker angekommen ist Duplikat senden (true/false) | Nachricht senden starten und mit print() übermitteln |
| beginWill(); print(); endWill(); | Thema Länge der Nachricht, auf dem Broker behalten (true) Qualität der Nachricht (0 .. 2) | versucht eine getrennte Verbindung neu aufzubauen muss vor dem eigentlichen Verbindungsaufbau gestartet werden |
| onMessage(); | Funktion für die Auswertung der empfangen Daten | Daten auswerten |
| subscribe() | Mindestens das Thema optional: Qualität der Übermittlung der Nachricht | nachfragen ob Daten zum Thema vorhanden sind |
Der Sender
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | #include “ArduinoMqttClient.h” #ifdef ESP8266 #include “ESP8266WiFi.h” #else #include “WiFi.h” #endif #include “DHT.h” // Pin des DHT-Sensors int SENSOR_DHT = 4; // DHT11 // #define SensorTyp DHT11 // DHT22 #define SensorTyp DHT22 // dht-Sensor einen Namen und Typ zuweisen DHT dht(SENSOR_DHT, SensorTyp); char Router[] = “Router_SSID”; char Passwort[] = “xxxxxxxx”; WiFiClient wifiClient; // wifiClient MqttClient zuordnen MqttClient mqttClient(wifiClient); const char broker[] = “test.mosquitto.org”; int port = 1883; /* öffentliche Broker const char broker[] = “public.mqtthq.com”; int port = 1883; const char broker[] = “test.mosquitto.org”; int port = 1883; const char broker[] = “broker.emqx.io”; const char *mqtt_username = “emqx”; const char *mqtt_password = “public”; int port = 1883; */ // Thema für Senden/Empfangen const char Messdaten[] = “Messdaten”; // Thema für die “will”-Nachricht für den Versuch die Verbindung // neu aufzubauen const char getrennteVerbindung[] = “getrennteVerbindung”; // Intervall zwischen den Messungen const long Interval = 5000; unsigned long vorherigeZeit = 0; void setup() { Serial.begin(9600); while (!Serial); delay(1000); WiFi.mode(WIFI_STA); WiFi.begin(Router, Passwort); while (WiFi.status() != WL_CONNECTED) { delay(200); Serial.print(“.”); } Serial.println(); Serial.print(“Verbunden mit ”); Serial.println(Router); Serial.print(“IP über DHCP: ”); Serial.println(WiFi.localIP()); /* will-Nachricht: wird an den Broker gesendet und versucht eine getrennte Verbindung neu aufzubauen Parameter: Thema, Länge des gesendeten Strings, Behalten der Anforderung, Qualität der Verbindung muss vor dem Aufbau der Verbindung zum Broker festgelegt werden */ String willDaten = “getrennt”; bool Behalten = true; int willQualitaetService= 2; // will-Nachricht senden mqttClient.beginWill(getrennteVerbindung, willDaten.length(), Behalten, willQualitaetService); mqttClient.print(getrennteVerbindung); mqttClient.endWill(); Serial.println(“Versuche mit dem Broker ” + String(broker) + ” zu verbinden … ”); delay(1000); // Verbindungsversuch if (!mqttClient.connect(broker, port)) { Serial.print(“Verbindung zum Broker gescheitert”); // Programm anhalten while (1); } Serial.println(); Serial.println(“Mit dem Broker ” + String(broker) + ” verbunden!”); Serial.println(); // dht-Sensor starten dht.begin(); } void loop() { // Broker abfragen mqttClient.poll(); unsigned long aktuelleZeit = millis(); // Intervall zwischen den Sendezeiten if (aktuelleZeit - vorherigeZeit >= Interval) { // letzte Sendezeit sichern vorherigeZeit = aktuelleZeit; // gemessene Temperatur dht in String umwandeln String Temperatur = String(dht.readTemperature(), 1); // . durch , ersetzen Temperatur.replace(“.”, “,”); // gemessene Luftfeuchtigkeit in String umwandeln String Luftfeuchtigkeit = String(dht.readHumidity(), 1); // . durch , ersetzen Luftfeuchtigkeit.replace(“.”, “,”); // String Senden zusammenbauen / als Trennzeichen String Senden = Temperatur + “/” + Luftfeuchtigkeit; Serial.println(“Nachricht gesendet:”); // Anzeige im Seriellen Monitor: String Senden am / trennen int Suche = Senden.indexOf(“/”); // String bis zum / Temperatur = Senden.substring(0, Suche); // String vom ersten Zeichen hinter / bis zum Ende Luftfeuchtigkeit = Senden.substring(Suche + 1, Senden.length()); // Daten im Seriellen Monitor anzeigen Serial.println(Temperatur + “°C”); Serial.println(Luftfeuchtigkeit + “%”); Serial.println(“———————”); // Messdaten senden bool Behalten = false; int ServiceQualitaet = 2; bool Duplikat = false; mqttClient.beginMessage(Messdaten, Senden.length(), Behalten, ServiceQualitaet, Duplikat); mqttClient.print(Senden); mqttClient.endMessage(); } } |
Der Empfänger
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | #include “ArduinoMqttClient.h” #ifdef ESP8266 #include “ESP8266WiFi.h” #else #include “WiFi.h” #endif #include “U8g2lib.h” /* Typbezeichnung mit Bildschirmgröße in Pixeln 1 = page buffer mode, F = full screen buffer mode Hardware I2C/Hardware SPI Name des OLEDs Rotation R0 (keine) */ U8G2_SSD1306_128X64_NONAME_1_HW_I2C oled(U8G2_R0, U8X8_PIN_NONE); // Router SSID/Passwort char Router[] = “Router_SSID”; char Passwort[] = “xxxxxxxx”; WiFiClient wifiClient; MqttClient mqttClient(wifiClient); const char broker[] = “test.mosquitto.org”; int port = 1883; /* öffentliche Broker const char broker[] = “public.mqtthq.com”; int port = 1883; const char broker[] = “test.mosquitto.org”; int port = 1883; const char broker[] = “broker.emqx.io”; const char *mqtt_username = “emqx”; const char *mqtt_password = “public”; int port = 1883; */ // Thema für Senden/Empfangen const char Messdaten[] = “Messdaten”; /* Qualität der Verbindung (0 .. 2) 0 = Nachricht wird einmal versendet eine Überprüfung des Empfangs durch den Broker findet nicht statt 1 = die Nachricht wird solange versendet, bis der Broker den Empfang bestätigt hat 2 = die Nachricht wird einmal gesendet, es wird sicher gestellt, dass sie beim Broker angekommen ist */ int subscribeQoS = 2; void setup() { Serial.begin(9600); while (!Serial); delay(1000); WiFi.mode(WIFI_STA); WiFi.begin(Router, Passwort); while (WiFi.status() != WL_CONNECTED) { delay(200); Serial.print(“.”); } Serial.println(); Serial.print(“Verbunden mit ”); Serial.println(Router); Serial.print(“IP über DHCP: ”); Serial.println(WiFi.localIP()); Serial.print(“Versuche mit dem Broker ” + String(broker) + ” zu verbinden … ”); // Verbindung zum Broker aufbauen if (!mqttClient.connect(broker, port)) { Serial.print(“Verbindung zum Broker gescheitert”); // Programm anhalten while (1); } Serial.println(); Serial.println(“Mit dem Broker ” + String(broker) + ” verbunden!”); Serial.println(); // den Rückruf für den Nachrichtenempfang festlegen mqttClient.onMessage(empfangeneNachricht); // in das Thema Messdaten “einschreiben” mqttClient.subscribe(Messdaten, subscribeQoS); // OLED starten oled.begin(); // Kontrast maximal 255 oled.setContrast(200); oled.setFont(u8g2_font_helvR24_tf); // Zeichenfarbe weiß oled.setDrawColor(1); // horizontale Schrift oled.setFontDirection(0); } void loop() { // Broker abfragen mqttClient.poll(); } void empfangeneNachricht(int NachrichtGroesse) { Serial.println(“Nachricht empfangen: ”); // Thema der Nachricht empfangen und anzeigen String Nachricht = mqttClient.messageTopic(); Serial.println(Nachricht + ” ”); // Nachricht als String lesen String EmpfangeneNachricht = mqttClient.readString(); // String Anzeige am / trennen int Suche = EmpfangeneNachricht.indexOf(“/”); String Temperatur = EmpfangeneNachricht.substring(0, Suche); String Luftfeuchtigkeit = EmpfangeneNachricht.substring(Suche + 1, EmpfangeneNachricht.length()); // Anzeige im Seriellen Monitor Serial.println(Temperatur + “°C”); Serial.println(Luftfeuchtigkeit + “%”); Serial.println(“———————”); Serial.println(); // Anzeige OLED oled.clearDisplay(); oled.firstPage(); do { oled.setCursor(2, 30); oled.print(Temperatur); // Grad-Zeichen oled.print((char)176); oled.print(“C”); oled.setCursor(2, 60); oled.print(Luftfeuchtigkeit + “%”); } while (oled.nextPage()); } |
MQTT mit Raspberry Pi
Die Verbindung zu den öffentlichen Brokern ist nicht verschlüsselt und die Erreichbarkeit ist nicht garantiert. Als Lösung bietet sich an mit einem Raspberry Pi einen eigenen Broker zu betreiben.
letzte Aktualisierung:



