Statt der Kommunikation über ein verbundenes WLAN-Netzwerk können Module des Typ ESP8266, ESP32, ESP32-S
und ESP32-C auch direkt miteinander Daten austauschen. Dies geschieht mittels einem von
Espressif entwickelten Protokoll namens "ESP-NOW".
Hierbei wird kein Router benötigt, denn die Kommunikation erfolgt über die
MAC-Adressen der jeweils beteiligten Module.
Der Verbindungsaufbau zwischen den Modulen erfolgt durch das vereinfachte Protokoll deutlich schneller
und reduziert damit auch den Stromverbrauch der Module. Allerdings ist Datenmenge pro Paket ist auf
250 Bytes begrenzt. Ein Master kann mit bis zu 20 Slaves gepaart werden. Will man das ESP-Now Netzwerk
verschlüsseln (ECDH und AES128-CCM), so reduziert sich die maximale Anzahl der Slaves auf 10.
Es gibt die Übertragungsmöglichkeiten als "unicast" und "broadcast", somit ist
sowohl eine 1:1 als auch eine 1:n-Kommunikation möglich.
Da die Identifizierung der Module in ESP-NOW über die MAC-Adresse funktioniert, muss man diese zunächst
von den beteiligten Modulen ermitteln und am besten separat notieren.
Die folgenden Programme ermitteln die MAC-Adresse des angeschlossenen Moduls und schreiben diese auf
die serielle Konsole. Die Ausgabe sollte beispielsweise so aussehen:
MAC Address: 8C:9E:1F:E9:F5:50
#include "WiFi.h"
// enable for ESP32-CAM
// #include "soc/rtc_cntl_reg.h"
void setup()
{
// Disable brownout detector (enable for ESP32-CAM)
// WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
Serial.begin(115200);
WiFi.mode(WIFI_MODE_STA); // "station mode"
Serial.print("MAC Address: ");
Serial.println(WiFi.macAddress());
}
void loop() {}
#include <ESP8266WiFi.h>
void setup()
{
Serial.begin(9600);
}
void loop()
{
Serial.print("MAC Address: ");
Serial.println(WiFi.macAddress());
delay(5000);
}
Im folgenden Versuch werden zwei ESP32-Module verwendet, um eine unidirektionale Kommunikation mit dem ESP-NOW-Protokoll aufzubauen. Dabei fungiert Modul #1 als Sender und Modul #2 als Empfänger. Für diesen Test werden verschiedene Datentypen verschickt (Char, Int, Float und Bool).
#include <esp_now.h>
#include <WiFi.h>
// custom MAC address of the responder module
uint8_t responderAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
struct messageStruct {
char myString[32];
int myInt;
float myFloat;
bool myBool;
};
messageStruct messageData;
esp_now_peer_info_t peerInfo;
void onDataSent(const uint8_t *macAddress, esp_now_send_status_t sendStatus)
{
Serial.print((int)macAddress + ": ");
if (sendStatus == ESP_NOW_SEND_SUCCESS) {
Serial.println("sent");
} else {
Serial.println("ERROR: sent failed!");
}
}
void setup()
{
Serial.begin(115200);
WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK) {
Serial.println("Error init ESP-NOW");
return;
}
esp_now_register_send_cb(onDataSent);
memcpy(peerInfo.peer_addr, responderAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
Serial.println("Failed to add peer");
return;
}
}
void loop()
{
strcpy(messageData.myString, "This is a ESP-NOW sending test");
messageData.myInt = random(1, 100);
messageData.myFloat = messageData.myInt * 2.41;
messageData.myBool = (bool)random(0, 2);
esp_err_t result = esp_now_send(responderAddress, (uint8_t *) &messageData, sizeof(messageData));
if (result != ESP_OK) {
Serial.println("Sending error");
}
delay(5000);
}
#include <esp_now.h>
#include <WiFi.h>
struct messageStruct {
char myString[32];
int myInt;
float myFloat;
bool myBool;
};
messageStruct messageData;
void onDataReceive(const uint8_t *macAddress, const uint8_t *incomingData, int dataLength)
{
memcpy(&messageData, incomingData, sizeof(messageData));
Serial.println("Data received: " + String(dataLength));
Serial.println("String: " + String(messageData.myString));
Serial.println("Int: " + String(messageData.myInt));
Serial.println("Float: " + String(messageData.myFloat));
Serial.println("Bool: " + String(messageData.myBool));
Serial.println("----------------------------");
}
void setup()
{
Serial.begin(115200);
WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK) {
Serial.println("Error init ESP-NOW");
return;
}
esp_now_register_recv_cb(onDataReceive);
}
void loop() {}
Wenn beide Sketches auf jeweils ein ESP32-Modul geladen wurden, dann sollte in der seriellen Konsole des Empfängers folgende Ausgabe der empfangenden Daten erscheinen: