ESP-NOW to protokół opracowany przez firmę Espressif. Umożliwia urządzeniom komunikację między sobą bez konieczności korzystania z sieci WiFi. Protokół wykorzystuje moduł komunikacji bezprzewodowej.
Protokół umożliwia w jednym cyklu przesłanie 256 baitów. Jedno urządzenie mogą komunikować się nawet z 20 bez szyfrowania a 10 z szyfrowaniem. Urządzenia są adresowane za pomocą adresu MAC.
Urządzenia mogą wysyłać dane na 3 sposoby:
- Dwukierunkowo pomiędzy urządzeniami.
- Jeden kontroler wysyła dane do wielu.
- Odbieranie danych z wielu kontrolerów
Program
Nadajnik pobiera dane z czujnika DHT11. Program tworzy strukturę zawierającą temperaturę oraz wilgotność. Dane są wysyłane poprzez ESP-NOW
Odbiornik pobiera dane i wyświetla je w monitorze portu szeregowego.
Pobranie adresu MAC
Schemat
Schemat przedstawia podłączenie diody LED oraz czujnika DHT11 (moduł lub sam sensor).
W przypadku podpięcia czujnika DHT11 z 4 pinami należy użyć rezystora 4,7kΩ.

Kod pobranie MAC
#include <ESP8266WiFi.h>
void setup(){
Serial.begin(9600);
}
void loop(){
Serial.println();
Serial.print("MAC: ");
Serial.println(WiFi.macAddress());
delay(5000);
}
Kod nadajnika
Urządzenie za pośrednictwem adresu MAC (odbiorcy) wysyła dane z czujnika DHT11. Dane wysyłane są w formie struktury, która musi być taka sama, jak na urządzeniu odbierającym.
#include <ESP8266WiFi.h>
#include <espnow.h>
#include "DHT.h"
//Wybór pinu i rodzaj czujnika DHT
#define DHTPIN D3
#define DHTTYPE DHT11
//Deklaracja czujnika
DHT dht(DHTPIN, DHTTYPE);
// Adres MAC odbiornika //(2c:6f:6f:56:32:26)
uint8_t broadcastAddress[] = {0x2c, 0x6f, 0x6f, 0x56, 0x32, 0x26};
// Struktura do wysłania
// Musi pokrywać się z strukturą odbiornika
typedef struct struct_message {
float temperature;
float humidity;
} struct_message;
struct_message Data;
unsigned long lastTime = 0;
unsigned long timerDelay = 2000; // Interwał wysyłania danych
//Potwierdzenie wysłania
void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) {
Serial.print("Stan pakietu: ");
if (sendStatus == 0){
Serial.println("Dostarczono");
}
else{
Serial.println("Nie dostarczono!");
}
}
void setup() {
//Inicjalizacja czujnika
dht.begin();
Serial.begin(9600);
// Ustawienie urządzenia jako stacja WiFi
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != 0) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Rejestracja w celu wysłania
// pobranie status przetransmitowanego pakietu
esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);
esp_now_register_send_cb(OnDataSent);
//Rejestracja odbiornika
esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);
}
void loop() {
if ((millis() - lastTime) > timerDelay) {
//Dane do wysłania
Data.temperature = dht.readTemperature();
Data.humidity = dht.readHumidity();
Data.text = "ESP8266 ESP-NOW";
//Wysłanie danych przez ESP-NOW
esp_now_send(broadcastAddress, (uint8_t *) &Data, sizeof(Data));
lastTime = millis();
}
}
Kod odbiornika
Kontroler odbierający strukturę od urządzenia nadawczego wyświetla dane za pośrednictwem monitora portu szeregowego.
#include <esp_now.h>
#include <WiFi.h>
//Struktura danych odbieranych
//Musi być taka sama jak nadawane
typedef struct Struct {
float temperature;
float humidity;
} Struct;
Struct Data;
//Funkcja wykonana po odebraniu danych
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
memcpy(&Data, incomingData, sizeof(Data));
Serial.print("Otrzymane Bajty: ");
Serial.println(len);
Serial.print("Temperatura: ");
Serial.println(Data.temperature);
Serial.print("Wilgotność: ");
Serial.println(Data.humidity);
Serial.println();
}
void setup() {
Serial.begin(9600);
//Urządzenie jako stacja WiFi
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Błąd inicjalizacji ESP-NOW");
return;
}
//Wysłanie informacji o pomyślnym zainicjowaniu ESP-NOW
//pobranie informacji z recv packer
esp_now_register_recv_cb(OnDataRecv);
}
void loop() {
}
Monitor portu szeregowego (Odbiornik)
Odczyt przesłanych danych. Zawiera dane z czujnika oraz pokazuje ile bitów danych przesłano.
