ESP NOW – One-to-many Kommunikation – ESP Basics

ESP-NOW ist ein Protokoll, welches die Möglichkeit bietet, mehrere Geräte zu verbinden, ohne das lokale Netzwerk nutzen zu müssen. Hiermit sind ESP8266 oder ESP32 in der Lage autark zu kommunizieren. In diesem Beitrag betrachten wir eine One-to-many Kommunikation zwischen zwei ESP8266.

Für mehr Details zu den Funktionen und Rollen von ESP-NOW schau Dir unseren Beitrag ESP NOW – One-way Kommunikation – ESP Basics an.

ESP-NOW-one-to-many
ESP-NOW One-to-many Kommunikation

Code Beispiel

Sender

Hinweis
Strings mit variabler Länge sollten nicht im zu übertragenden struct verwendet werden. Der Grund hierfür ist, dass zur Übertragung die Größe der Daten benötigt wird. Bei einem Arduino-String ist diese Größe allerdings variabel und würde den Versand der Daten deutlich komplizierter machen. Aus diesem Grund verwenden wir ein char[] mit einer festen Länge von 64 Zeichen.

Gleiche Nachricht

Wenn Du mehr Informationen zum Thema MAC-Adressen beim ESP wissen möchtest, schau bei unserem Beitrag ESP Basics – MAC-Adresse herausfinden vorbei.

#include <ESP8266WiFi.h>
#include <espnow.h>

// Trage hier die MAC-Adressen der Empfaenger ein 
uint8_t macAddress1[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
uint8_t macAddress2[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

// struct welches übertragen wird
// Muss mit Empfaenger uebereinstimmen
typedef struct message {
  long number;
  // Speicher reserviert
  char string[64];
} message;

// Erzeuge struct
message myMessage;

// Wird aufgerufen wenn die Nachricht gesendet wurde
void messageSend(uint8_t *reciverMacAddress, uint8_t status) {
  if (status == 0){
    Serial.println("Erfolgreich gesendet");
  } else {
    Serial.println("Fehler beim senden");
  }
}

// Callback when data is sent
void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) {
  char macStr[18];
  Serial.print("Packet to:");
  snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
         mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
  Serial.print(macStr);
  Serial.print(" send status: ");
  if (sendStatus == 0){
    Serial.println("Delivery success");
  }
  else{
    Serial.println("Delivery fail");
  }
}
 
void setup() {
  // Starte seriellen Monitor
  Serial.begin(115200);
 
  // Setze Geraet in Station mode
  WiFi.mode(WIFI_STA);

  // Init ESP-NOW
  if (esp_now_init() != 0) {
    Serial.println("Error initializing ESP-NOW");
  }

  // Setze Rolle das Geraetes
  esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);
  
  // Setze callback Funktion
  esp_now_register_send_cb(messageSend);
  
  // Koppeln auf Chanel 1 
  // null und 0 können durch Passwort und Passwortlenge ersetzt werden 
  // betrachten wir in diesem Fall aber nicht
  esp_now_add_peer(macAddress1, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);
  esp_now_add_peer(macAddress2, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);

}
 
void loop() {
  // setze Werte
  myMessage.number = random(100); // zufaellige Zahl

  char string[32] = "Das ist ein String";
  memcpy(&myMessage.string, string, sizeof(string));

  // Sende Nachricht ueber ESP-NOW
  esp_now_send(0, (uint8_t *) &myMessage, sizeof(myMessage));

  // 2 Sekunden warten
  delay(2000);

}Code-Sprache: PHP (php)

Wenn die gleiche Nachricht an mehere Geräte gesendet werden soll, kann dies mit dieser Funktion geschehen.

// Sende Nachricht ueber ESP-NOW
  esp_now_send(0, (uint8_t *) &myMessage, sizeof(myMessage));Code-Sprache: JavaScript (javascript)

Wenn dies nicht benötigt wird, kann man auf klassische Weise (Siehe Abschnitt “Sender (verschiedene Nachrichten)”) zwei verschiedene Nachrichten an den jeweiligen ESP senden

Verschiedene Nachrichten

#include <ESP8266WiFi.h>
#include <espnow.h>

// Trage hier die MAC-Adressen der Empfaenger ein 
uint8_t macAddress1[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
uint8_t macAddress2[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

// struct welches übertragen wird
// Muss mit Empfaenger uebereinstimmen
typedef struct message {
  long number;
  // Speicher reserviert
  char string[64];
} message;

// Erzeuge struct
message myMessage1;
message myMessage2;

// Wird aufgerufen wenn die Nachricht gesendet wurde
void messageSend(uint8_t *reciverMacAddress, uint8_t status) {
  if (status == 0){
    Serial.println("Erfolgreich gesendet");
  } else {
    Serial.println("Fehler beim senden");
  }
}

// Callback when data is sent
void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) {
  char macStr[18];
  Serial.print("Packet to:");
  snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
         mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
  Serial.print(macStr);
  Serial.print(" send status: ");
  if (sendStatus == 0){
    Serial.println("Delivery success");
  }
  else{
    Serial.println("Delivery fail");
  }
}
 
void setup() {
  // Starte seriellen Monitor
  Serial.begin(115200);
 
  // Setze Geraet in Station mode
  WiFi.mode(WIFI_STA);

  // Init ESP-NOW
  if (esp_now_init() != 0) {
    Serial.println("Error initializing ESP-NOW");
  }

  // Setze Rolle das Geraetes
  esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);
  
  // Setze callback Funktion
  esp_now_register_send_cb(messageSend);
  
  // Koppeln auf Chanel 1 
  // null und 0 können durch Passwort und Passwortlenge ersetzt werden 
  // betrachten wir in diesem Fall aber nicht
  esp_now_add_peer(macAddress1, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);
  esp_now_add_peer(macAddress2, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);

}
 
void loop() {
  // setze Werte
  myMessage1.number = random(100); // zufaellige Zahl
  myMessage2.number = random(100); // zufaellige Zahl

  char string[32] = "Das ist ein String";
  memcpy(&myMessage1.string, string, sizeof(string));
  memcpy(&myMessage2.string, string, sizeof(string));

  // Sende Nachricht ueber ESP-NOW
    esp_now_send(macAddress1, (uint8_t *) &myMessage1, sizeof(myMessage1));
    esp_now_send(macAddress2, (uint8_t *) &myMessage2, sizeof(myMessage2));

  // 2 Sekunden warten
  delay(2000);

}Code-Sprache: PHP (php)
ESP-NOW-one-to-many-eingehende-Nachrichten
Vom gleichen Sender verschiedene Nachrichten

Empfänger

Tipp
Der serielle Monitor der Arduino IDE kann nur einmal pro Instanz benutzt werden. Wenn man den seriellen Monitor parallel auf zwei COM-Ports nutzen möchte, muss man die Arduino IDE mehrfach gestartet werden.

#include <ESP8266WiFi.h>
#include <espnow.h>

// struct welches übertragen wird
// Muss mit Sender uebereinstimmen
typedef struct message {
  long number;
  char string[64];
} message;

// Erzeuge struct
message myMessage;

// Callback function that will be executed when data is received
void OnDataRecv(uint8_t * mac, uint8_t *incomingData, uint8_t len) {
  memcpy(&myData, incomingData, sizeof(myData));
  Serial.print("Bytes received: ");
  Serial.println(len);
  Serial.print("x: ");
  Serial.println(myData.x);
  Serial.print("y: ");
  Serial.println(myData.y);
  Serial.println();
}
 
void setup() {
  // Starte seriellen Monitor
  Serial.begin(115200);
  delay(100);

  // Gibt MAC-Adresse aus
  Serial.print("MAC Address:  ");
  Serial.println(WiFi.macAddress());
  
  // Setze Geraet in Station mode
  WiFi.mode(WIFI_STA);

  // Init ESP-NOW
  if (esp_now_init() != 0) {
    Serial.println("Error initializing ESP-NOW");
  }
  
  // Setze Rolle
  esp_now_set_self_role(ESP_NOW_ROLE_SLAVE);

  // Sezte Callback Funktion
  esp_now_register_recv_cb(recive);
}

void loop() {
  
}Code-Sprache: PHP (php)

Kommentare