
Ziele des Projekts
Mit ESP-NOW sollen ESP32-Mikrocontroller
- Textnachrichten senden, empfangen und im Seriellen Monitor anzeigen
- Daten von Temperatursensoren messen und auf einem LCD/einem OLED anzeigen
ESP-NOW
ESP-NOW ist ein drahtloses Kommunikationsprotokoll für die Kommunikation zwischen zwei oder mehreren ESP32-Controllern, das die Übertragung kurzer Datenpakete erlaubt. Die beteiligten ESP32-Mikrocontroller können ohne Verwendung von vorhandenen WiFi-Netzen direkt miteinander kommunizieren. ESP-NOW ähnelt zwar der klassischen WLAN-Kommunikation, es kommt jedoch ohne Router oder andere typische Netzwerkkomponenten aus.
Vor dem Aufbau einer Kommunikation müssen die teilnehmenden Geräte gekoppelt werden. Nach Abschluss der Kopplung besteht eine sichere Verbindung zwischen den kommunizierenden Geräten.
Die Geräte identifizieren sich untereinander durch den Austausch ihrer MAC (=Media Access Control)-Adressen.
Die Reichweite ist natürlich sehr von den baulichen Gegebenheiten abhängig. Ich habe eine Kombination von ESP32-C6 und ESP32-C3 sowohl als Sender als auch als Empfänger verwendet. Alle können die Daten vom Erdgeschoss bis ins zweite Obergeschoss senden und empfangen.
Die Hardware
Der Einfachheit halber habe ich ausschließlich Geräte verwendet, die über den I²C-Bus angesteuert werden:
Natürlich kannst du auch andere Sensoren verwenden.
I²C-Pins der Mikrocontroller:
- ESP32-Wroom
- ESP32C6
- Arduino Nano ESP32
- XIAO-ESP32-C3
- ESP32-C3 Zero
- ESP32-C3 Super Mini
- ESP32-C6 Zero
Board installieren
Als Mikrocontroller können beliebige Module aus der Familie der ESP32-Mikrocontroller verwendet werden.
- ESP32-Wroom
- Arduino Nano ESP32
- ESP32-C6
- XIAO-ESP32-C3
- ESP32-C3 Zero
- ESP32-C3 Super Mini
- ESP32-C6 Zero
MAC-Adresse ermitteln
Den Kommunikationspartnern müssen die jeweiligen MAC-Adressen bekannt sein. Jedes Netzwerkgerät hat eine individuelle MAC-Adresse.
Das Programm ermittelt die MAC-Adresse und zeigt sie im Seriellen Monitor an. Die formatierte MAC-Adresse kannst du anschließend kopieren und direkt in den Programmen verwenden.

|
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 |
#include "WiFi.h" void setup() { Serial.begin(9600); delay(1000); WiFi.mode(WIFI_STA); Serial.print("MAC-Adresse: "); // MAC-Adresse ermitteln String MACAdresse = WiFi.macAddress(); Serial.println(MACAdresse); String FormatierteMACAdresse; Serial.print("Formatierte MAC-Adresse: "); int index = 0; // MAC-Adresse besteht aus 6 durch : getrennte Elemente for (int i = 0; i < 6; i++) { // index: Abstand zum nächsten Wert 2 Ziffern + : FormatierteMACAdresse += "0x" + MACAdresse.substring(index, index + 3); index += 3; } FormatierteMACAdresse.replace(":", ", "); Serial.println("{" + FormatierteMACAdresse + "}"); } void loop() { // bleibt leer, Programm läuft nur einmal } |
Funktionen ESP-NOW
| Funktion | Beschreibung | Parameter |
|---|---|---|
| esp_now_init(); | startet ESP-NOW | Rückgabewert bei Erfolg: ESP_OK |
| esp_now_add_peer(); | fügt einen ESP als Kommunikationspartner hinzu | struct esp_now_peer_info &peer_info peer_info.channel -> legt den Übertragungskanal fest (0 = aktueller Kanal) peer_info.peer_addr -> MAC-Adresse des Kommunikationspartners peer_info.encrypt -> Nachricht verschlüsseln (true/false) Rückgabewert bei Erfolg: ESP_OK |
| esp_now_send(); | Nachricht senden | Parameter: MAC-Adresse Nachricht Größe der Nachricht |
| esp_now_register_send_cb(FunktionsName); | definiert eine Funktion, die überprüft, ob eine Nachricht erfolgreich gesendet wurde | Rückgabewert bei Erfolg: ESP_NOW_SEND_SUCCESS |
| esp_now_register_recv_cb(FunktionsName); | definiert eine Funktion, die überprüft, ob eine Nachricht erfolgreich empfangen wurde wertet den Inhalt der Nachricht aus | Parameter: MAC-Adresse Nachricht Größe der Nachricht |
Textnachricht senden und empfangen
Sender
In einem ersten Schritt soll eine kurze Textnachricht von einem ESP32 an einen anderen ESP32 gesendet werden. Der Text enthält eine zufällig erzeugte Zahl.

- Es müssen keine zusätzlichen Bibliotheken installiert werden, es werden die „Bordmittel“ verwendet.
- Die MAC-Adresse des Empfängers muss dem Sender bekannt gemacht werden.
- Die Variable EmpfaengerInfo vom Typ esp_now_peer_info_t enthält die benötigten Informationen über den Empfänger:
peer_address -> MAC-Adresse
channel -> Kanal der Verbindung (0-13) Standard ist 0
Wenn der Kanal nicht korrekt ist, wird beim Senden eine Fehlermeldung ausgegeben:
Peer channel is not equal to the home channel, send fail!
encrypt = false -> keine Verschlüsselung - Die CallBack-Funktion esp_now_register_send_cb überprüft, ob die Nachricht gesendet wurde.
- esp_now_add_peer fügt die Adresse des Empfängers hinzu.
- esp_now_send sendet die Nachricht und überprüft gleichzeitig mit esp_err_t, ob das Senden erfolgreich war. Der Funktion werden die Adresse des Empfängers, die Daten und die Länge der Daten übergeben.
|
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 |
#include "esp_now.h" #include "WiFi.h" // MAC-Adresse des Empfängers -> muss angepasst werden uint8_t EmpfaengerAdresse[] = {0x10, 0xB4, 0x1D, 0x14, 0x72, 0x00}; // enthält die Information über den ESP mit dem kommuniziert werden soll esp_now_peer_info_t EmpfangerInfo; void NachrichtGesendet(const uint8_t *EmpfaengerAdresse, esp_now_send_status_t Status) { if(Status == ESP_NOW_SEND_SUCCESS) Serial.println("Nachricht gesendet"); } void setup() { Serial.begin(9600); // Stations-Modus WiFi.mode(WIFI_STA); // ESP-NOW initialisieren if (esp_now_init() != ESP_OK) { Serial.println("ESP-NOW konnte nicht gestartet werden!"); return; } else Serial.println("ESP_NOW erfolgreich initialisiert! "); /* Informationen zum ESP hinzufügen (esp_now_peer_info_t) peer_address -> MAC-Adresse channel -> Kanal der Verbindung (0-13) Standard: 0 encrypt = false -> keine Verschlüsselung */ // MAC-Adresse des ESPs nach peer_addr kopieren memcpy(EmpfangerInfo.peer_addr, EmpfaengerAdresse, 6); EmpfangerInfo.channel = 0; EmpfangerInfo.encrypt = false; if (esp_now_add_peer(&EmpfangerInfo) != ESP_OK) { Serial.println("Empfänger konnte nicht hinzugefügt werden!"); return; } // anzeigen, ob Nachricht erfolgreich gesendet wurde esp_now_register_send_cb((esp_now_send_cb_t) NachrichtGesendet); } void loop() { int Zahl = random(1, 1000); // Zahl in char-Array umwandeln String Zufallszahl = String(Zahl); Serial.println(Zufallszahl); char Daten[Zufallszahl.length() + 1]; Zufallszahl.toCharArray(Daten, Zufallszahl.length() + 1); // Nachricht an Empfänger senden esp_err_t Fehler = esp_now_send(EmpfaengerAdresse, (uint8_t *) &Daten, sizeof(Daten) - 1); if (Fehler != ESP_OK) Serial.println("Fehler beim Senden an Empfänger "); else Serial.println("Nachricht gesendet!"); delay(5000); } |
Empfänger
Auf der Seite des Empfängers wird im setup-Teil eine CallBack-Funktion DatenEmpfangen definiert: sie wertet die empfangenen Daten aus.
|
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 |
#include "esp_now.h" #include "WiFi.h" /* Funktion DatenEmpfangen Parameter: MACAdresse empfangeneDaten LaengeDaten */ void DatenEmpfangen(const uint8_t * MACAdresse, const uint8_t * empfangeneDaten, int LaengeDaten) { Serial.println("Nachricht vom Sender ..."); Serial.print("Zufallszahl: "); for(int i = 0; i < LaengeDaten; i++) { Serial.print((char)empfangeneDaten[i]); } Serial.println(); Serial.println("------------------------"); } void setup() { Serial.begin(9600); // WiFi im Stations-Modus starten WiFi.mode(WIFI_STA); // ESP-NOW initialisieren if (esp_now_init() != ESP_OK) { Serial.println("ESP-NOW konnte nicht gestartet werden!"); return; } else Serial.println("ESP_NOW erfolgreich initialisiert! "); // Funktion DatenEmpfangen mit Rückgabewert registrieren esp_now_register_recv_cb(esp_now_recv_cb_t(DatenEmpfangen)); } void loop() { // bleibt leer, Programm reagiert nur auf die Funktion DatenEmpfangen } |
Daten an zwei Empfänger senden
Ein ESP32 sendet Messdaten an zwei Empfänger. Ein DHT20 liefert die Daten, sie werden auf einem OLED und einem LCD angezeigt.

Sender
- Die MAC-Adressen der Empfänger werden in einem ⇒Array definiert.
- Die Messdaten werden in einer ⇒Struktur abgelegt.
- Die Variable EmpfaengerInfo vom Typ esp_now_peer_info_t enthält die benötigten Informationen über den Empfänger. Sie wird in einer for-Schleife den jeweiligen Empfängern zugewiesen.
- Die Messdaten des DHT werden den Elementen des Arrays zugeordnet:
0 -> erster Empfänger, 1 -> zweiter Empfänger
Daten[0].Temperatur = dht.getTemperature();
Daten[0].Luftfeuchtigkeit = dht.getHumidity();
Daten[1].Temperatur = dht.getTemperature();
Daten[1].Luftfeuchtigkeit = dht.getHumidity(); - esp_now_send sendet die Daten in einer for-Schleife an die Empfänger.
Benötigte Bibliotheken



|
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 |
#include "Adafruit_BME280.h" #include "esp_now.h" #include "WiFi.h" #define MeeresHoehe (1013.25) // Name des BME280 Adafruit_BME280 bme; // MAC-Adressen der Empfänger uint8_t EmpfangerAdresse[2][6] = { { 0xEC, 0xDA, 0x3B, 0xBD, 0x2F, 0x14 }, { 0x10, 0xB4, 0x1D, 0x14, 0x72, 0x00 } }; // Datenstruktur // muss mit allen Empfängern übereinstimmen struct Daten_Struktur { float Temperatur; float Luftfeuchtigkeit; }; // Daten: Array mit 2 Elementen Daten_Struktur Daten[2]; // enthält die Information über die ESPs mit denen kommuniziert werden soll esp_now_peer_info_t EmpfangerInfo[2]; void setup() { Serial.begin(9600); // BME280 starten, bei Misserfolg Meldung anzeigen if (!bme.begin(0x77)) { Serial.println("BME280 nicht verbunden"); Serial.println("Verkabelung und/oder HEX-Adresse prüfen!"); Serial.println("Start mit möglichen HEX-Adressen:"); Serial.println("bme.begin(0x76);"); Serial.println("bme.begin(0x77);"); Serial.println("Programm wird beendet!"); while (1); } else Serial.println("BME280 erfolgreich gestartet!"); // Stations-Modus WiFi.mode(WIFI_STA); // ESP-NOW initialisieren if (esp_now_init() != ESP_OK) { Serial.println("ESP-NOW konnte nicht gestartet werden!"); return; } else Serial.println("ESP_NOW erfolgreich initialisiert! "); /* Informationen zu den ESPs hinzufügen (esp_now_peer_info_t) peer_address -> MAC-Adresse channel -> Kanal der Verbindung (0-13) Standard: 0 encrypt = false -> keine Verschlüsselung Durchlauf für alle mit MAC-Adresse definierten ESPs */ for (int i = 0; i < 2; i++) { // MAC-Adresse des jeweiligen ESPs nach peer_addr kopieren memcpy(EmpfangerInfo[i].peer_addr, EmpfangerAdresse[i], 6); EmpfangerInfo[i].channel = 0; EmpfangerInfo[i].encrypt = false; // konnte die MAC-Adresse zugeordnet werden if (esp_now_add_peer(&EmpfangerInfo[i]) != ESP_OK) { Serial.println("Empfänger konnte nicht hinzugefügt werden!"); return; } } } void loop() { // Daten des bme280 den Elementen des Arrays zuordnen Daten[0].Temperatur = bme.readTemperature(); Daten[0].Luftfeuchtigkeit = bme.readHumidity(); Daten[1].Temperatur = bme.readTemperature(); Daten[1].Luftfeuchtigkeit = bme.readHumidity(); // Nachricht an 2 Empfänger senden for(int i = 0; i < 2; i++) { // Daten senden und Fehlercode abfragen esp_err_t Fehler = esp_now_send(EmpfangerAdresse[i], (uint8_t *) &Daten[i], sizeof(Daten[i])); if (Fehler != ESP_OK) { Serial.print("Fehler beim Senden an Empfänger "); Serial.println(i); } } delay(5000); } |
Empfänger mit LCD
- Die Definition der struct Daten_Struktur muss beim Sender und den Empfängern übereinstimmen.
- Die Registrierung der Funktion DatenEmpfangen über die CallBack-Funktion esp_now_register_recv_cb sorgt für die Darstellung der Daten..
|
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 |
#include "esp_now.h" #include "WiFi.h" #include "LCDIC2.h" // 4-zeiliges LCD LCDIC2 lcd(0x27, 20, 4); // muss mit der Struktur beim Sender übereinstimmen struct Daten_Struktur { float Temperatur; float Luftfeuchtigkeit; }; // Name für die definierte struct Daten_Struktur Daten; /* Funktion DatenEmpfangen Parameter: MACAdresse empfangeneDaten LaengeDaten */ void DatenEmpfangen(const uint8_t * MACAdresse, const uint8_t * empfangeneDaten, int LaengeDaten) { // struct Daten nach empfangeneDaten kopieren memcpy(&Daten, empfangeneDaten, sizeof(Daten)); Serial.print("Temperatur: "); String Temperatur = String(Daten.Temperatur); Temperatur.replace(".", ","); Serial.println(Temperatur +"°C"); String Luftfeuchtigkeit = String(Daten.Luftfeuchtigkeit); Luftfeuchtigkeit.replace(".", ","); Serial.print("Luftfeuchtigkeit: "); Serial.println(Luftfeuchtigkeit + "%"); Serial.println("------------------------"); lcd.setCursor(0, 0); lcd.print("Temperatur: "); lcd.setCursor(0, 1); lcd.print(Temperatur); lcd.print("\337C"); lcd.setCursor(0, 2); lcd.print("Luftfeuchtigkeit: "); lcd.setCursor(0, 3); lcd.print(Luftfeuchtigkeit); lcd.print("%"); } void setup() { // LCD starten lcd.begin(); // Cursor "verstecken" lcd.setCursor(false); Serial.begin(9600); // WiFi im Stations-Modus starten WiFi.mode(WIFI_STA); // ESP-NOW initialisieren if (esp_now_init() != ESP_OK) { Serial.println("ESP-NOW konnte nicht gestartet werden!"); return; } else Serial.println("ESP_NOW erfolgreich initialisiert! "); // Funktion DatenEmpfangen mit Rückgabewert registrieren esp_now_register_recv_cb((esp_now_recv_cb_t) DatenEmpfangen); } void loop() { // bleibt leer, Programm reagiert nur auf die Funktion DatenEmpfangen } |
Empfänger mit OLED
|
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 |
#include "esp_now.h" #include "WiFi.h" #include "U8g2lib.h" /* Typbezeichnung mit Bildschirmgröße in Pixeln F = full screen buffer mode Hardware I2C Name des OLEDs Rotation R0 (keine) */ U8G2_SSD1306_128X64_NONAME_F_HW_I2C oled(U8G2_R0); // muss mit der Struktur beim Sender übereinstimmen struct Daten_Struktur { float Temperatur; float Luftfeuchtigkeit; }; // Name für die definierte struct Daten_Struktur Daten; /* Funktion DatenEmpfangen Parameter: MACAdresse empfangeneDaten LaengeDaten */ void DatenEmpfangen(const uint8_t *MACAdresse, const uint8_t *empfangeneDaten, int LaengeDaten) { // struct Daten nach empfangeneDaten kopieren memcpy(&Daten, empfangeneDaten, sizeof(Daten)); Serial.print("Temperatur: "); String Temperatur = String(Daten.Temperatur); Temperatur.replace(".", ","); Serial.println(Temperatur +"°C"); String Luftfeuchtigkeit = String(Daten.Luftfeuchtigkeit); Luftfeuchtigkeit.replace(".", ","); Serial.print("Luftfeuchtigkeit: "); Serial.println(Luftfeuchtigkeit + "%"); Serial.println("------------------------"); oled.setCursor(1, 15); oled.print("Temperatur: "); oled.setCursor(1, 30); oled.print(Temperatur); oled.print((char)176); oled.print("C"); oled.setCursor(1, 45); oled.print("Luftfeuchtigkeit: "); oled.setCursor(1, 60); oled.print(Luftfeuchtigkeit); oled.print("%"); oled.sendBuffer(); oled.clearBuffer(); } void setup() { oled.begin(); // Schriftart oled.setFont(u8g2_font_helvB12_tf); Serial.begin(9600); // WiFi im Stations-Modus starten WiFi.mode(WIFI_STA); // ESP-NOW initialisieren if (esp_now_init() != ESP_OK) { Serial.println("ESP-NOW konnte nicht gestartet werden!"); return; } else Serial.println("ESP_NOW erfolgreich initialisiert! "); // Funktion DatenEmpfangen mit Rückgabewert registrieren esp_now_register_recv_cb((esp_now_recv_cb_t) DatenEmpfangen); } void loop() { // bleibt leer, Programm reagiert nur auf die Funktion DatenEmpfangen } |
Daten von zwei Sendern an Empfänger übermitteln
Zwei Sender werden jeweils mit einem BME280 bestückt, sie liefern die gemessenen Daten an einen Empfänger.


Benötigte Bibliothek

Sender 0
- Die struct Daten_Struktur beinhaltet die ID des Senders als int und Temperatur, Luftfeuchtigkeit und Luftdruck als float.
- Im loop-Teil werden die ID des Senders und die Messwerte der Datenstruktur (Nachricht) zugeordnet.
|
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 |
#include "esp_now.h" #include "WiFi.h" #include "Adafruit_BME280.h" #define MeeresHoehe (1013.25) // Name des BME280 Adafruit_BME280 bme; // MAC-Adresse des Empfängers -> muss angepasst werden uint8_t EmpfaengerAdresse[] = { 0xEC, 0xDA, 0x3B, 0xBD, 0x2F, 0x14 }; // enthält die Information über den ESP mit dem kommuniziert werden soll esp_now_peer_info_t EmpfangerInfo; // ID -> Kennung des Controllers // Temperatur/Luftfeuchtigkeit/Luftdruck -> Daten des jeweiligen Sensors struct Daten_Struktur { int ID; float Temperatur; float Luftfeuchtigkeit; float Luftdruck; }; Daten_Struktur Nachricht; void NachrichtGesendet(const uint8_t *EmpfaengerAdresse, esp_now_send_status_t Status) { if(Status == ESP_NOW_SEND_SUCCESS) Serial.println("Nachricht gesendet"); } void setup() { Serial.begin(9600); delay(1000); // BME280 starten, bei Misserfolg Meldung anzeigen if (!bme.begin(0x77)) { Serial.println("BME280 nicht verbunden"); Serial.println("Verkabelung und/oder HEX-Adresse prüfen!"); Serial.println("Start mit möglichen HEX-Adressen:"); Serial.println("bme.begin(0x76);"); Serial.println("bme.begin(0x77);"); Serial.println("Programm wird beendet!"); while (1); } else Serial.println("BME280 erfolgreich gestartet!"); WiFi.mode(WIFI_STA); // ESP-NOW initialisieren if (esp_now_init() != ESP_OK) { Serial.println("ESP-NOW konnte nicht gestartet werden!"); return; } // anzeigen, ob Nachricht erfolgreich gesendet wurde (cb = callback) esp_now_register_send_cb((esp_now_send_cb_t)NachrichtGesendet); /* Informationen zum ESP hinzufügen (esp_now_peer_info_t) peer_address -> MAC-Adresse channel -> Kanal der Verbindung (0-13) Standard: 0 encrypt = false -> keine Verschlüsselung */ // MAC-Adresse des ESPs nach peer_addr kopieren memcpy(EmpfangerInfo.peer_addr, EmpfaengerAdresse, 6); EmpfangerInfo.channel = 0; EmpfangerInfo.encrypt = false; // Empfänger hinzufügen if (esp_now_add_peer(&EmpfangerInfo) != ESP_OK) { Serial.println("Empfänger konnte nicht hinzugefügt werden!"); return; } } void loop() { // ID des Controllers Nachricht.ID = 0; // Daten lesen Nachricht.Temperatur = bme.readTemperature(); Nachricht.Luftfeuchtigkeit = bme.readHumidity(); Nachricht.Luftdruck = bme.readPressure() / 100.0; // Nachricht an Empfänger senden esp_err_t Fehler = esp_now_send(EmpfaengerAdresse, (uint8_t *)&Nachricht, sizeof(Nachricht)); if (Fehler == ESP_OK) { Serial.println("Nachricht erfolgreich gesendet!"); } else { Serial.println("Fehler beim Senden der Nachricht!"); } delay(5000); } |
Sender 1
|
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 |
#include "esp_now.h" #include "WiFi.h" #include "Adafruit_BME280.h" #define MeeresHoehe (1013.25) // Name des BME280 Adafruit_BME280 bme; // MAC-Adresse des Empfängers -> muss angepasst werden uint8_t EmpfaengerAdresse[] = { 0xEC, 0xDA, 0x3B, 0xBD, 0x2F, 0x14 }; // enthält die Information über den ESP mit dem kommuniziert werden soll esp_now_peer_info_t EmpfangerInfo; // ID -> Kennung des Controllers // Temperatur/Luftfeuchtigkeit/Luftdruck -> Daten des jeweiligen Sensors struct Daten_Struktur { int ID; float Temperatur; float Luftfeuchtigkeit; float Luftdruck; }; Daten_Struktur Nachricht; void NachrichtGesendet(const uint8_t *EmpfaengerAdresse, esp_now_send_status_t Status) { if(Status == ESP_NOW_SEND_SUCCESS) Serial.println("Nachricht gesendet"); } void setup() { Serial.begin(9600); delay(1000); // BME280 starten, bei Misserfolg Meldung anzeigen if (!bme.begin(0x76)) { Serial.println("BME280 nicht verbunden"); Serial.println("Verkabelung und/oder HEX-Adresse prüfen!"); Serial.println("Start mit möglichen HEX-Adressen:"); Serial.println("bme.begin(0x76);"); Serial.println("bme.begin(0x77);"); Serial.println("Programm wird beendet!"); while (1); } else Serial.println("BME280 erfolgreich gestartet!"); WiFi.mode(WIFI_STA); // ESP-NOW initialisieren if (esp_now_init() != ESP_OK) { Serial.println("ESP-NOW konnte nicht gestartet werden!"); return; } // anzeigen, ob Nachricht erfolgreich gesendet wurde (cb = callback) esp_now_register_send_cb((esp_now_send_cb_t)NachrichtGesendet); /* Informationen zum ESP hinzufügen (esp_now_peer_info_t) peer_address -> MAC-Adresse channel -> Kanal der Verbindung (0-13) Standard: 0 encrypt = false -> keine Verschlüsselung */ // MAC-Adresse des ESPs nach peer_addr kopieren memcpy(EmpfangerInfo.peer_addr, EmpfaengerAdresse, 6); EmpfangerInfo.channel = 0; EmpfangerInfo.encrypt = false; // Empfänger hinzufügen if (esp_now_add_peer(&EmpfangerInfo) != ESP_OK) { Serial.println("Empfänger konnte nicht hinzugefügt werden!"); return; } } void loop() { // ID des Controllers Nachricht.ID = 1; // Daten lesen Nachricht.Temperatur = bme.readTemperature(); Nachricht.Luftfeuchtigkeit = bme.readHumidity(); Nachricht.Luftdruck = bme.readPressure() / 100.0; // Nachricht an Empfänger senden esp_err_t Fehler = esp_now_send(EmpfaengerAdresse, (uint8_t *)&Nachricht, sizeof(Nachricht)); if (Fehler == ESP_OK) { Serial.println("Nachricht erfolgreich gesendet!"); } else { Serial.println("Fehler beim Senden der Nachricht!"); } delay(5000); } |
Empfänger
- Der Datenstruktur werden drei Bezeichnungen zugeordnet (Sender, Sender1, Sender2).
- Das Array AnzahlController enthält als Elemente die beiden Sender.
- die empfangenen Daten müssen den jeweiligen Sendern zugeordnet werden:
AnzahlSender[Sender.ID].Temperatur = Sender.Temperatur;
AnzahlSender[Sender.ID].Luftfeuchtigkeit = Sender.Luftfeuchtigkeit;
AnzahlSender[Sender.ID].Luftdruck = Sender.Luftdruck; - Anschließend wird die ID des Senders abgefragt und die Messdaten im Seriellen Monitor und auf dem LCD dargestellt.
|
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 |
#include "esp_now.h" #include "WiFi.h" #include "LCDIC2.h" // 4-zeiliges LCD LCDIC2 lcd(0x27, 20, 4); struct Daten_Struktur { int ID; float Temperatur; float Luftfeuchtigkeit; float Luftdruck; }; Daten_Struktur Sender; Daten_Struktur Sender1; Daten_Struktur Sender2; Daten_Struktur AnzahlSender[2] = { Sender1, Sender2 }; void DatenEmpfangen(const uint8_t *MACAdresse, const uint8_t *EmpfangeneDaten, int LangeDaten) { // Messdaten in das Array Sender kopieren memcpy(&Sender, EmpfangeneDaten, sizeof(Sender)); // die empfangenen Daten anhand der ID (Sender.ID) // den Sendern zuordnen AnzahlSender[Sender.ID].Temperatur = Sender.Temperatur; AnzahlSender[Sender.ID].Luftfeuchtigkeit = Sender.Luftfeuchtigkeit; AnzahlSender[Sender.ID].Luftdruck = Sender.Luftdruck; // in String umwandeln umd . durch , ersetzen zu können String AnzeigeTemperatur = String(AnzahlSender[Sender.ID].Temperatur); String AnzeigeLuftfeuchtigkeit = String(AnzahlSender[Sender.ID].Luftfeuchtigkeit); // float zu int konvertieren -> Nachkommastellen entfernen // String AnzeigeLuftdruck = String(int(AnzahlSender[Sender.ID].Luftdruck)); // oder mit Nachkommastellen String AnzeigeLuftdruck = String(AnzahlSender[Sender.ID].Luftdruck); // Sensoren anhand der Sender-Nummer identifizieren // und Daten anzeigen if (Sender.ID == 0) { // . durch , ersetzen AnzeigeTemperatur.replace(".", ","); AnzeigeLuftdruck.replace(".", ","); AnzeigeLuftfeuchtigkeit.replace(".", ","); Serial.print("Esszimmer: "); Serial.println(AnzeigeTemperatur + "°C"); Serial.println(AnzeigeLuftfeuchtigkeit + "% "); Serial.println(AnzeigeLuftdruck + " hPA"); lcd.setCursor(0, 0); lcd.print("Esszimmer: "); lcd.print(AnzeigeTemperatur); lcd.print("\337C "); lcd.setCursor(0, 1); lcd.print(AnzeigeLuftfeuchtigkeit +"% "); lcd.print(AnzeigeLuftdruck + " hPA"); } if (Sender.ID == 1) { AnzeigeTemperatur.replace(".", ","); AnzeigeLuftdruck.replace(".", ","); AnzeigeLuftfeuchtigkeit.replace(".", ","); Serial.print("Wohnzimmer: "); AnzeigeTemperatur.replace(".", ","); Serial.println(AnzeigeTemperatur + "°C"); Serial.println(AnzeigeLuftfeuchtigkeit + "%"); Serial.println(AnzeigeLuftdruck + " hPA"); lcd.setCursor(0, 2); lcd.print("Wohnzimmer: "); lcd.print(AnzeigeTemperatur); lcd.print("\337C "); lcd.setCursor(0, 3); lcd.print(AnzeigeLuftfeuchtigkeit + "% "); lcd.print(AnzeigeLuftdruck + " hPA"); } Serial.println("-----------------"); } void setup() { Serial.begin(9600); delay(1000); // LCD starten lcd.begin(); // Cursor "verstecken" lcd.setCursor(false); WiFi.mode(WIFI_STA); // ESP-NOW initialisieren if (esp_now_init() != ESP_OK) { Serial.println("ESP-NOW konnte nicht gestartet werden!"); return; } else Serial.println("ESP_NOW erfolgreich initialisiert! "); esp_now_register_recv_cb((esp_now_recv_cb_t)DatenEmpfangen); } void loop() { // bleibt leer, das Programm reagiert nur auf die Funktion DatenEmpfangen } |
Quellen
Letzte Aktualisierung:
