Kabellose Kommunikation mit ESP-NOW ohne Router

Für meine Lärmschutzampel suche ich eine Möglichkeit, Signale drahtlos zu übertragen, ohne auf ein bestehendes Netzwerk angewiesen zu sein. Dabei bin ich auf eine Lösung gestoßen, die direkt vom Hersteller des Mikrocontrollers angeboten wird.
Somit geht es diesmal nicht um Lärm, sondern um die Technik dahinter:

Was ist ESP-NOW?

ESP-NOW ist eine Funktechnik von Espressif (Hersteller der ESP32-Boards) das auf dem 2,4 GHz-Band arbeitet – also dem gleichen Frequenzbereich wie WLAN oder Bluetooth.

  • Direkte Kommunikation: Geräte sprechen ohne Router direkt miteinander.
  • Bidirektionale Kommunikation: Jeder Sender kann auch gleichzeitig Empfänger sein
  • MAC-Adressen optional: Man kann gezielt an einzelne Geräte senden (mit MAC-Adresse) oder an alle gleichzeitig (Broadcast mit neutraler MAC)
  • Minimales Protokoll: Nur wenige Bytes pro Nachricht – perfekt für einfache Statusmeldungen wie „Laut“ oder „Leise“.
  • Schnell & effizient: Keine Verbindung wird aufgebaut, keine IP-Adresse nötig – einfach senden und empfangen.
  • Senden und Empfangen: Du kannst in einem Gerät sowohl senden, als auch Daten empfangen.

Warum ist es genial für Werkstattprojekte?

So kann nun bei der Lärmschutzampel auf Basis eines ESP32-Relaismoduls die Lärmmessung an der zentralen Ampel erfolgen, aber die Anzeige wird nun auch außerhalb der Werkstatt dadurch sichtbar. So kann frühzeitig Gehörschutz angelegt werden – gerade, wenn Maschinen spontan lauter werden. Dazu werden nun mehrere Ampeln eingesetzt:

  • Sensor-Ampel in der Werkstatt:
    Misst mit Mikrofon den aktuellen Lärmpegel.
  • Anzeige(n) außerhalb:
    Zeigen per LED/Relais, ob es laut/leise ist.

Quelle und weitere Details:
https://docs.arduino.cc/tutorials/nano-esp32/esp-now
ESP-NOW Wireless Communication Protocol | Espressif Systems


Testaufbau

Um zu testen ob und wie das mit ESP-Now geht, werde ich als Sender einen ESP32 mit Taste wählen und zwei Empfänger mit je einer LED, die nur leuchtet wenn Sender Taste drückt. Um die neuste ESP-Now Version zu verwenden, muss in der Board-Verwaltung die aktuelle Bibliothek installiert werden:

Hardware:

  • 3x ESP32-C6 Module 
  • Taster
  • Steckbrett mit Kabel
  • LEDs
  • Optional 3x Powerbank

ESP-NOW Sketche als Beispiel

Erstellte Sketche für Sender und Empfänger habe ich hier abgelegt: https://github.com/prilchen/ESP32-ESP-Now-SenderEmpfänger

Dort findest du zwei einfache Arduino-Sketches:

  • espnow_sender.ino: Sendet Daten (hier per Tasterdruck) per ESP-NOW Broadcast an alle Empfänger.
  • espnow_receiver.ino: Empfängt die Broadcast-Nachrichten und schaltet z.B. eine Anzeige-LED.

Sender mit Taster an Pin 4 und GND:

// verwendetes Entwicklungsboard ESP32-C6

#include <WiFi.h>
#include <esp_now.h>

#define BUTTON_PIN 4

typedef struct {
  bool tasterGedrueckt;
} struct_message;

struct_message daten;

uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

void setup() {
  Serial.begin(115200);
  pinMode(BUTTON_PIN, INPUT_PULLUP);

  WiFi.mode(WIFI_STA);
  if (esp_now_init() != ESP_OK) {
    Serial.println("ESP-NOW Init fehlgeschlagen!");
    return;
  }

  // Broadcast-Peer registrieren
  esp_now_peer_info_t peerInfo = {};
  memcpy(peerInfo.peer_addr, broadcastAddress, 6);
  peerInfo.channel = 0;
  peerInfo.encrypt = false;

  if (esp_now_add_peer(&peerInfo) != ESP_OK) {
    Serial.println("Fehler beim Hinzufügen des Broadcast-Peers!");
    return;
  }

  Serial.println("Sender bereit – Tasterstatus wird per Broadcast gesendet.");
}

void loop() {
  daten.tasterGedrueckt = digitalRead(BUTTON_PIN) == LOW;

  esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *)&daten, sizeof(daten));

  if (result == ESP_OK) {
    Serial.printf("Gesendet: %s\n", daten.tasterGedrueckt ? "GEDRÜCKT" : "NICHT gedrückt");
  } else {
    Serial.println("Sende-Fehler!");
  }

  delay(500);
}

Empfänger mit LED an Pin 2 und GND:

// verwendetes Entwicklungsboard ESP32-C6

#include <WiFi.h>
#include <esp_now.h>

// Struktur für empfangene Daten
typedef struct {
  bool tasterGedrueckt;
} struct_message;

struct_message empfangeneDaten;

// Callback-Funktion bei Empfang 
void OnDataRecv(const esp_now_recv_info *recv_info, const uint8_t *incomingData, int len) {
  memcpy(&empfangeneDaten, incomingData, sizeof(empfangeneDaten));

  char macStr[18];
  snprintf(macStr, sizeof(macStr), "%02X:%02X:%02X:%02X:%02X:%02X",
           recv_info->src_addr[0], recv_info->src_addr[1], recv_info->src_addr[2],
           recv_info->src_addr[3], recv_info->src_addr[4], recv_info->src_addr[5]);

  Serial.printf("Empfangen von %s → Tasterstatus: %s\n",
                macStr,
                empfangeneDaten.tasterGedrueckt ? "GEDRÜCKT" : "NICHT gedrückt");

  // Beispielhafte Reaktion: LED an GPIO 2 schalten
  digitalWrite(2, empfangeneDaten.tasterGedrueckt ? HIGH : LOW);
}

void setup() {
  Serial.begin(115200);

  // GPIO 2 als Ausgang für LED oder Relais
  pinMode(2, OUTPUT);
  digitalWrite(2, LOW); // Initialzustand: aus

  // WiFi im Station Mode aktivieren
  WiFi.mode(WIFI_STA);

  // ESP-NOW initialisieren
  if (esp_now_init() != ESP_OK) {
    Serial.println("ESP-NOW Init fehlgeschlagen!");
    return;
  }

  // Empfangs-Callback registrieren
  esp_now_register_recv_cb(OnDataRecv);

  Serial.println("ESP-NOW Empfänger bereit.");
}

void loop() {
  // Keine aktive Logik im Loop nötig – alles passiert im Callback
  delay(1000);
}


Die Ausgabe im Seriellen Monitor funktioniert wie erwartet:

Hier mit einem Sender und zwei Empfänger. Das dazuschalten des zweiten Empfängers geht ohne merkliche Zeitverzögerung:


Die Broadcast Mac erlaubt das funken an alle Teilnehmer. Sollen aber nur gezielte Geräte angesprochen werden, wird die korrekte Mac-Adresse erwartet.

Auslesen der benötigten Mac-Adresse:

Um die MAC-Adresse eines ESP32-WROOM für die Verwendung mit ESP-NOW zu erhalten, kannst du folgenden Arduino-Code nutzen:

#include <WiFi.h>

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA); // Setzt den ESP32 in den Station-Modus
  delay(500); //kurz Zeit lassen, zur Initialisierung
  Serial.print("MAC-Adresse: ");
  Serial.println(WiFi.macAddress()); // Gibt die MAC-Adresse aus
}

void loop() {
  // Kein Code nötig
}

Somit kann dann die Broadcast-Adresse im Sender Sketch

uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

gegen die echte MAC-Adresse des Empfängers ersetzt werden:

uint8_t receiverAddress[] = {0x24, 0x6F, 0x28, 0xAB, 0xCD, 0xEF}; // Beispiel-MAC

Tipp: Beim ESP32-C6 diese Funktionen fehlerhafte Werte liefern. Dann mal mit esp_read_mac() probieren, um die korrekte Adresse zu erhalten.


Bidirektionale Kommunikation:

ESP-NOW erlaubt es auch, dass ein Gerät Daten sendet und gleichzeitig Daten empfängt.

Du musst lediglich:

esp_now_register_send_cb() // verwenden, um auf Sendebestätigungen zu reagieren.

esp_now_register_recv_cb() // verwenden, um empfangene Daten zu verarbeiten.

Beide Funktionen können im selben Sketch aktiv sein – du musst nur darauf achten, dass du Peers korrekt registrierst, wenn du gezielt senden willst.

Fazit

ESP-NOW ist eine einfache, schnelle und zuverlässige Funklösung für DIY-Projekte mit ESP32. Ob du Statusmeldungen senden, mehrere Geräte synchronisieren oder einfach kabellos kommunizieren willst – mit minimalem Code und ohne Netzwerkaufwand bist du sofort startklar.
Für meine Lärmschutzampel war ESP-NOW genau die richtige Wahl – und vielleicht auch für dein nächstes Projekt.

, ,
Datenschutz-Übersicht

Diese Website verwendet Cookies, damit wir dir die bestmögliche Benutzerkomfort bieten können. Cookie-Informationen werden in deinem Browser gespeichert und führen Funktionen aus, wie das Wiedererkennen von dir, wenn du auf unsere Website zurückkehrst und hilft uns zu verstehen, welche Abschnitte der Website für dich am interessantesten und nützlichsten sind.