
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:
Board installieren
Als Mikrocontroller können beliebige Module aus der Familie der ESP32-Mikrocontroller verwendet werden.
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.

#include "WiFi.h"
void setup()
{
Serial.begin(9600);
delay(1000);
WiFi.mode(WIFI_STA);
WiFi.begin();
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.
#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.
#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
}Sensordaten 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



#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..
#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
#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
}Sensordaten 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.
#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
#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.
#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 LaengeDaten)
{
// 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:
