Drahtlose Kommunikation ist ein spannendes Thema, besonders wenn es um das Internet der Dinge (IoT) geht. Aber seien wir ehrlich: Oft gibt es Herausforderungen wie hohe Latenzzeiten, einen hohen Energieverbrauch oder die Abhängigkeit von Routern. Genau hier kommt ESP-NOW ins Spiel. Das ist ein Protokoll von Espressif, das dir erlaubt, zwei oder mehr ESP-Geräte direkt miteinander kommunizieren zu lassen – schnell, effizient und ohne einen Router.
In diesem Beitrag zeige ich dir, wie du mit ESP-NOW und deinem ESP32-S3-Zero von Waveshare loslegst. Ich erkläre dir, wie das Ganze funktioniert, wie du deine Geräte einrichtest und wie du Schritt für Schritt zwei ESP32-Boards miteinander sprechen lässt. Dabei nutze ich ein simples Beispiel, das dir die ersten Schritte leicht macht.
Inhaltsverzeichnis
- Was ist ESP-NOW?
- Wichtiger Hinweis: Erwärmung des ESP32-S3-Zero bei WiFi-Betrieb
- Beispiel – Einseitige Kommunikation zwischen zwei ESP32
- Abschluss und Ausblick
Was ist ESP-NOW?
ESP-NOW ist ein Peer-to-Peer (P2P) Protokoll, das eine direkte Kommunikation zwischen zwei ESP8266- oder ESP32-Geräten ermöglicht – und das ganz ohne zentrale Infrastruktur wie einen Server oder Router. Jedes ESP-Gerät besitzt eine eindeutige MAC-Adresse, die zur Identifikation des Empfängergeräts genutzt wird.
ESP-NOW bietet verschiedene Möglichkeiten, die Kommunikation zwischen Geräten zu gestalten:
Zweiseitige Kommunikation:
Hier können beide Geräte Daten in beide Richtungen austauschen. Das ermöglicht eine interaktive und reaktionsschnelle Kommunikation zwischen den Geräten. Dieser Modus eignet sich besonders für Anwendungen, bei denen die Geräte sowohl senden, als auch empfangen müssen, wie etwa in Fernsteuerungssystemen oder bei interaktiven IoT-Geräten. Beispiel: Eine Fernbedienung steuert ein Gerät und erhält gleichzeitig Rückmeldungen, etwa den Status oder aktuelle Werte.
Einfache (einseitige) Kommunikation:
In diesem Modus sendet ein Gerät (der Sender) Daten an ein anderes Gerät (den Empfänger), ohne eine Antwort zu erwarten. Das ist besonders praktisch für Szenarien wie das Übertragen von Sensordaten oder das Senden von Steuerbefehlen, bei denen eine Rückmeldung nicht notwendig ist. Beispiel: Ein Temperatur-Sensor überträgt regelmäßig die aktuellen Messwerte an ein Display.
Unterstützte Mikrocontroller
ESP-NOW ist auf verschiedenen Mikrocontrollern verfügbar, was es zu einem vielseitigen Protokoll für IoT-Entwicklungen macht. Hier ist eine Liste der unterstützten Geräte:
- Arduino Nano ESP32: Perfekt für kompakte IoT-Projekte mit integriertem ESP32-Modul.
- Generische ESP8266-Module: Ein Klassiker unter den Mikrocontrollern, der nach wie vor für ESP-NOW genutzt werden kann.
- Generische ESP32-Module: Die Allrounder mit leistungsstarker Dual-Core-Architektur und vielfältigen Einsatzmöglichkeiten.
- Generische ESP32-S-Module: Erweiterte Varianten des ESP32 mit zusätzlichen Features, z. B. verbesserter Sicherheit oder Energieeffizienz.
- ESP32-C-Serie (ESP32-C3, C6): Besonders geeignet für energieeffiziente Anwendungen dank RISC-V-Architektur und moderner Konnektivitätsoptionen.
Diese Geräte bieten dir eine breite Palette an Möglichkeiten, um drahtlose Kommunikation mit ESP-NOW zu realisieren – vom einfachen Sensor-Netzwerk bis hin zu komplexeren IoT-Systemen.
Begrenzungen von ESP-NOW
Kompatibilität
ESP-NOW ist primär für ESP8266- und ESP32-Mikrocontroller entwickelt. Es funktioniert möglicherweise nicht nahtlos mit nicht-ESP-Plattformen, was bei der Systemgestaltung berücksichtigt werden sollte.
Begrenzte Reichweite
Die Signalreichweite von ESP-NOW beträgt unter idealen Bedingungen etwa 220 Meter. Tatsächliche Werte können jedoch variieren, abhängig von Umgebungsstörungen, der Antennengestaltung und Hindernissen im Übertragungsweg.
Interferenzen
Da ESP-NOW im 2,4-GHz-Band arbeitet, kann es, wie andere drahtlose Technologien, durch andere Geräte und Wi-Fi-Netzwerke gestört werden. Eine sorgfältige Wahl der Kommunikationskanäle ist entscheidend, um Interferenzen zu minimieren und eine zuverlässige Kommunikation zu gewährleisten.
Keine Netzwerkinfrastruktur
ESP-NOW ist für Punkt-zu-Punkt- und Punkt-zu-Mehrpunkt-Kommunikation konzipiert, bietet jedoch keine Unterstützung für komplexe Netzwerktopologien. Anwendungen, die eine umfassende Netzwerkstruktur oder Internetverbindung erfordern, müssen durch zusätzliche Netzwerk-Tools ergänzt werden.
Begrenzte Datenmenge
ESP-NOW ist auf die Übertragung kleiner Datenmengen ausgelegt, mit einer maximalen Nutzlast von etwa 250 Bytes. Anwendungen, die eine hohe Bandbreite oder den Transfer großer Dateien benötigen, sind mit anderen Lösungen wie der Arduino Cloud besser bedient.
Sicherheitsaspekte
Obwohl ESP-NOW eine gewisse Datensicherheit bietet, ist es nicht so robust wie Protokolle wie HTTPS oder MQTT mit starker Verschlüsselung. Projekte, die sensible Daten verarbeiten, sollten zusätzliche Sicherheitsmaßnahmen implementieren, um Abhören oder unbefugten Zugriff zu verhindern.
Keine automatische Bestätigung
ESP-NOW verfügt nicht über eine eingebaute Mechanik, um die erfolgreiche Zustellung von Nachrichten zu bestätigen. Für Anwendungen, bei denen Zuverlässigkeit entscheidend ist, müssen eigene Mechanismen für Bestätigungen und Fehlerbehandlung entwickelt werden.
Wichtiger Hinweis: Erwärmung des ESP32-S3-Zero bei WiFi-Betrieb
Der ESP32-S3-Zero, den ich als Sender für ESP-NOW-Daten nutze, neigt dazu, im WiFi-Betrieb warm zu werden. Laut Datenblatt von Espressif beträgt die maximale Leistungsaufnahme im WiFi-Betrieb bis zu 355 mA. Bei einer Betriebsspannung von 3,3 V entspricht dies einer Leistungsaufnahme von etwa 1,17 Watt.
Wenn der Mikrocontroller häufig Daten sendet, kann dies zu einer erheblichen Erwärmung führen, die sich negativ auf die Langlebigkeit des Geräts auswirken könnte. In extremen Fällen kann der Chip sogar heiß werden. Daher empfehle ich, die Sendehäufigkeit sinnvoll zu regulieren und bei Bedarf Kühlmaßnahmen wie passive Kühlkörper oder eine bessere Belüftung zu integrieren, um die Wärmeentwicklung zu reduzieren.
Dieser Hinweis ist besonders wichtig für Anwendungen, die eine kontinuierliche oder sehr häufige Datenübertragung erfordern.
Beispiel – Einseitige Kommunikation zwischen zwei ESP32
Für die Programmierung von ESP-NOW benötigst du keine zusätzliche Software, du kannst dieses bereits mit den Boardmitteln der Arduino IDE umsetzen. Dieses macht es besonders Anfänger recht einfach, diese drahtlose Kommunikation in kleine IoT Projekte einzusetzen.
Für dieses Beispiel bediene ich mich aus der offiziellen englischen Dokumentation zu ESP-NOW in der Arduino IDE.
Durch die geringe (250 Byte) Paketgröße von ESP-NOW können nur kleine Datenpakete gesendet werden. Im Nachfolgenden zeige ich dir erst einmal Beispielhaft wie man eine LED via Taster von einem ESP32 schalten kann.
Auslesen der MAC-Adresse
Wir benötigen vom Empfänger die MAC-Adresse. Diese können wir entweder über das esptool auslesen oder wir verwenden ein kleines Programm, welches wir auf den Mikrocontroller aufspielen.
esptool
Mit dem esptool kann man den ESP32 / ESP8266 flashen und auch die Informationen vom Mikrocontroller auslesen. Das Kommandozeilentool kannst du dir unter https://github.com/espressif/esptool/releases als ZIP-Datei für Linux, Windows und macOS herunterladen.
C:\develop>esptool --port COM28 read_mac
esptool.py v3.3
Serial port COM28
Connecting...
Detecting chip type... ESP32-C3
Chip is ESP32-C3 (revision 4)
Features: Wi-Fi
Crystal is 40MHz
MAC: 40:4c:ca:f6:03:cc
Uploading stub...
Running stub...
Stub running...
MAC: 40:4c:ca:f6:03:cc
Hard resetting via RTS pin...
Upload eines leeres Sketches über die Arduino IDE
Alternativ können wir wie erwähnt ein leeres Programm auf den Mikrocontroller überspielen und können beim Upload die Informationen vom Mikrocontroller erhalten.
Datenstruktur für das Schalten einer LED
Für das Schalten einer LED oder ein Relais reicht ein einfaches boolsches Flag völlig aus. Die nachfolgende Struktur müssen wir beim Sender & Empfänger implementieren. Da diese Daten serialisiert & deserialisiert werden müssen.
struct Message { bool isActive; // Speichert den Status des Tasters (an/aus) };
Möchtest du Sensordaten senden so kannst du diese Struktur um weitere Felder erweitern, bedenke jedoch den maximalen Speicherplatz von 250 Byte pro Nachricht.
Sender
Im ersten Beispiel möchte ich lediglich eine LED schalten und verzichte zunächst auf eine Rückantwort, frei nach dem Motto „Fire and Forget“.
Der Sender muss hier lediglich ein Signal abschicken, welches eine 1 oder 0 sendet, für das Schalten einer LED reicht dieses aus.
Wenn du Sensordaten sendest dann hast du wie erwähnt die 250 Byte platz.
#include <esp_now.h> #include <WiFi.h> // Definiere den Pin für den Taster #define taster 1 // MAC-Adresse des Zielgeräts (Empfänger) uint8_t broadcastAddress[] = { 0x40, 0x4C, 0xCA, 0xF6, 0x03, 0xCC }; // Struktur für die zu übertragenden Daten struct Message { bool isActive; // Speichert den Status des Tasters (an/aus) }; // Erstelle eine Instanz der Nachrichtenstruktur Message message; // Definiert Informationen über den ESP-NOW-Peer (den Empfänger) esp_now_peer_info_t peerInfo; // Callback-Funktion, die aufgerufen wird, wenn eine Nachricht gesendet wurde void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) { Serial.print("\r\nStatus:\tZustellung "); // Gibt den Status der Nachricht aus: erfolgreich oder fehlerhaft Serial.println(status == ESP_NOW_SEND_SUCCESS ? "erfolgreich!" : "fehlerhaft!"); } void setup() { Serial.begin(115200); // Starte die serielle Kommunikation für Debugging-Ausgaben pinMode(taster, INPUT_PULLUP); // Setze den Taster-Pin als Eingang mit Pull-Up-Widerstand WiFi.mode(WIFI_STA); // Setze das WiFi-Modul in den Station-Modus (verhindert Störungen) // Initialisiere ESP-NOW und prüfe, ob die Initialisierung erfolgreich ist if (esp_now_init() != ESP_OK) { Serial.println("Error initializing ESP-NOW"); return; } // Registriere die Callback-Funktion für den Versandstatus esp_now_register_send_cb(OnDataSent); // Füge die Zieladresse und weitere Einstellungen zur Peer-Info-Struktur hinzu memcpy(peerInfo.peer_addr, broadcastAddress, 6); // MAC-Adresse des Empfängers peerInfo.channel = 0; // Verwende den Standardkanal peerInfo.encrypt = false; // Keine Verschlüsselung // Füge den Peer zur ESP-NOW-Peer-Liste hinzu if (esp_now_add_peer(&peerInfo) != ESP_OK) { Serial.println("Failed to add peer"); return; } } void loop() { // Prüfe, ob der Taster gedrückt wurde (LOW = gedrückt, da Pull-Up aktiviert ist) if (digitalRead(taster) == LOW) { // Ändere den Status in der Nachricht (umschalten zwischen true und false) message.isActive = !message.isActive; // Sende die Nachricht über ESP-NOW esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *)&message, sizeof(message)); // Überprüfe, ob das Senden erfolgreich war if (result == ESP_OK) { Serial.println("Senden erfolgreich!"); } else { Serial.println("Fehler beim absenden der Daten!"); } delay(250); // Entprellzeit für den Taster } delay(50); // Kurze Pause, um die Hauptschleife zu entlasten }
Empfänger
Der Empfänger muss ebenso die selbe Struktur haben um die Daten zu deserialisieren. Diese Struktur enthält in meinem Fall lediglich eine boolsche Variable welche entweder true oder false ist.
Informationen zum Sender benötigt dieser in diesem Beispiel nicht da wir keine Rückantwort senden.
#include <esp_now.h> #include <WiFi.h> // Definiere den Pin für die LED #define led 21 // Struktur für die empfangenen Daten struct Message { bool isActive; // Status der LED: an (true) oder aus (false) }; // Erstelle eine Instanz der Nachrichtenstruktur Message message; // Callback-Funktion, die aufgerufen wird, wenn Daten empfangen werden void OnDataRecv(const uint8_t *mac, const uint8_t *incomingData, int len) { // Kopiere die empfangenen Daten in die lokale Nachrichtenstruktur memcpy(&message, incomingData, sizeof(message)); // Ausgabe der Anzahl empfangener Bytes Serial.print("Bytes received: "); Serial.println(len); // Ausgabe des empfangenen LED-Status Serial.print("isActive: "); Serial.println(message.isActive); // Logik zum Umschalten der LED: // Wenn `isActive` false ist, wird die LED eingeschaltet (invertiert das Signal) bool isLEDActive = message.isActive == 0 ? true : false; // Setze den LED-Status basierend auf den empfangenen Daten digitalWrite(led, isLEDActive); } void setup() { Serial.begin(115200); // Starte die serielle Kommunikation für Debugging pinMode(led, OUTPUT); // Setze den LED-Pin als Ausgang WiFi.mode(WIFI_STA); // Setze den Wi-Fi-Modus auf Station (verhindert Störungen) // Initialisiere ESP-NOW und prüfe, ob die Initialisierung erfolgreich ist if (esp_now_init() != ESP_OK) { Serial.println("Error initializing ESP-NOW"); return; } // Registriere die Callback-Funktion für empfangene Daten esp_now_register_recv_cb(esp_now_recv_cb_t(OnDataRecv)); } void loop() { // Die Hauptschleife ist leer, da die LED-Steuerung ausschließlich im Callback erfolgt }
Abschluss und Ausblick
Mit ESP-NOW hast du nun einen einfachen und leistungsstarken Weg kennengelernt, drahtlose Kommunikation zwischen ESP32-Geräten zu realisieren – ganz ohne Router oder komplexe Netzwerke. Wir haben die Grundlagen behandelt, einen ESP32-S3-Zero als Sender eingerichtet und die ersten Daten erfolgreich übertragen. Du siehst, wie unkompliziert es sein kann, Geräte miteinander zu verbinden und so eine solide Basis für viele spannende IoT-Projekte zu schaffen.
Im nächsten Beitrag gehen wir einen Schritt weiter: Wir senden Sensordaten von einem ESP32-S3-Zero zu einem ESP8266 mit OLED-Display. Dabei lernst du, wie du Messwerte von einem Sensor ausliest, drahtlos überträgst und diese auf einem Display visualisierst. Das macht deine Projekte nicht nur funktional, sondern auch anschaulich – perfekt für Anwendungen wie Wetterstationen, Smart-Home-Geräte oder Überwachungssysteme. Bleib dran!
Danke, mal wieder ein sehr interessantes Projekt. Habe es sofort auf meine Projektliste gesetzt und werde es so schnell wie möglich umsetzten. bin gespannt auf die Fortsetzung.
Wünsche schon mal ein ruhiges und besinnliches Fest.
MfG M. Jacke