
Wstęp
Zdalnie sterowany robot z komunikacją radiową o niskiej latencji i dużym zasięgu – bez potrzeby korzystania z sieci WiFi czy dodatkowych urządzeń. Czy da się to zbudować na ESP8266 lub ESP32 bez dodatkowych modułów? Oczywiście!
Do tej pory pokazywałem wiele projektów opartych na ESP8266 i ESP32, głównie wykorzystujących połączenie z siecią WiFi. Tym razem przedstawię protokół stworzony przez Espressif, który pozwala na bezpośrednią komunikację między tymi modułami, bez konieczności używania routera. Urządzenia parują się na podstawie adresów MAC, a cała reszta zależy od naszej implementacji. Opiszę tutaj jego zalety, wady oraz podzielę się swoimi doświadczeniami i przykładami zastosowania.

Czym jest ESP now
ESP-NOW wykorzystuje wbudowany w moduły ESP8266 i ESP32 układ radiowy 2,4 GHz, omijając przy tym wiele warstw klasycznej komunikacji WiFi. W przeciwieństwie do standardowego połączenia z siecią, nie wymaga zestawiania sesji TCP/IP, logowania do routera ani stosowania protokołów takich jak HTTP czy MQTT, które wcześniej omawiałem.
Zalety ESP-NOW:
✅ Minimalne opóźnienia – transmisja może trwać poniżej 10 ms, co może mieć znaczenie np. w projekcie zdalnie sterowanego autka.
✅ Niski pobór mocy – idealne rozwiązanie do czujników bateryjnych czy systemów IoT.
✅ Bezpośrednia komunikacja – urządzenia komunikują się bez infrastruktury sieciowej.
✅ Elastyczna topologia sieci – ESP-NOW obsługuje różne schematy komunikacji:
– Punkt-punkt (one-to-one) – jedno urządzenie wysyła dane do drugiego.
– Jeden do wielu (one-to-many) – jeden nadajnik wysyła dane do wielu odbiorców.
– Wiele do jednego (many-to-one) – wiele urządzeń wysyła dane do jednego odbiornika, np. centralnego serwera ESP.
✅ Możliwość równoczesnego korzystania z WiFi – ESP-NOW nie wyklucza połączenia z siecią WiFi. Moduł może jednocześnie odbierać dane przez ESP-NOW i wysyłać je np. do chmury przez WiFi.
✅ESP-NOW obsługuje szyfrowanie AES-CCM, co zwiększa bezpieczeństwo transmisji. Dzięki temu nie jest to rozwiązanie całkowicie otwarte, a przesyłane dane mogą być chronione przed nieautoryzowanym dostępem.
Ograniczenia ESP-NOW:
❌ Maksymalny rozmiar pakietu to 250 bajtów, co uniemożliwia przesyłanie dużych ilości danych, np. wideo.
❌ Brak mechanizmu potwierdzenia odbioru (ACK) – nie mamy pewności, że pakiet dotarł, chyba że zaimplementujemy własną metodę retransmisji.
❌ Brak routingu – urządzenia muszą być w zasięgu bezpośredniej komunikacji radiowej.
Porównanie z innymi rozwiązaniami
Jak to będzie wyglądało z innymi komunikacjami, o których tutaj już mowiłem, np. Bluetooth i LoRa.
Cecha | ESP-NOW | Bluetooth (BLE) | LoRa/LoRaWAN |
---|---|---|---|
Pasmo | 2,4 GHz | 2,4 GHz | Sub-GHz (np. 433 MHz) |
Zasięg | ~100 m (otwarta przestrzeń) | ~50 m (BLE), ~10 m (klasyczny BT) | Nawet kilkanaście km (w terenie otwartym) |
Przepustowość | do 1 Mbps | BLE: ~1 Mbps | ~0,3–50 kbps |
Opóźnienia | <10 ms | ~10–50 ms (BLE) | LoRa 10-500 ms / LoRaWAN sekundy |
Pobór mocy | Niski | Bardzo niski (BLE) | Bardzo niski |
Topologia | Punkt-punkt, jeden-do-wielu, wiele-do-jednego | Punkt-punkt, siatka (BLE Mesh) | Punkt-punkt, jeden-do-wielu lub gwiazda w przypadku LoRaWAN |
Wymagana infrastruktura | Brak (bezpośrednia komunikacja) | Zazwyczaj wymagany centralny moduł (np. telefon, ESP BLE) | Wymaga bramy (gateway) w przypadku LoRaWAN |
Bezpieczeństwo | AES-CCM | AES-128 | AES-128, szyfrowanie na poziomie LoRaWAN |
W kodzie
Teraz przejdę do części praktycznej. Będę opierał się na przykładach, które znajdziecie w repozytorium tutaj. Ten zestaw może się w przyszłości rozwijać – jeśli macie jakieś pomysły, piszcie! Możecie także postawić mi kawę tutaj, jeśli chcecie wesprzeć rozwój projektu.
ESP-NOW działa zarówno z ESP-IDF, jak i Arduino. Póki co skupię się na tej drugiej opcji. Do obsługi ESP-NOW potrzebna jest osobna biblioteka – niestety inna dla ESP8266 i ESP32. Na szczęście ktoś już przygotował wrapper, który ułatwia przenoszenie kodu między platformami. Dlatego podzieliłem repozytorium na foldery odpowiadające poszczególnym bibliotekom.
Używam, jak zwykle, PlatformIO. Jeśli nie znacie tego środowiska, zapraszam do notki tutaj.
Poznanie adresu MAC urządzenia
Pierwszym krokiem jest poznanie adresu MAC płytki. W repozytorium znajduje się specjalny przykład, który po wgraniu na ESP wyświetla jego MAC na serial monitorze. Możemy go potem wykorzystać w kodzie, określając, do jakiej płytki wysyłamy pakiety.
W ESP-NOW istnieje także opcja broadcastu, czyli wysyłania wiadomości do wszystkich urządzeń w zasięgu. Wystarczy wysłać pakiet na adres MAC: FF:FF:FF:FF:FF:FF
.
Dlaczego używam biblioteki WiFi?
Możecie zauważyć, że w kodzie pojawia się biblioteka do WiFi – czy jest ona konieczna do ESP-NOW? Technicznie rzecz biorąc, nie. Jednak ESP-NOW może współpracować z WiFi pod pewnymi warunkami. Urządzenie nie może działać w trybie Access Point, dlatego na wszelki wypadek zawsze przełączam je w tryb Station:
#include <Arduino.h>
#ifdef ESP8266
#include <ESP8266WiFi.h>
#elif ESP32
#include <WiFi.h>
#endif
#ifdef ESP8266
WiFi.mode(WIFI_STA);
#elif ESP32
WiFi.mode(WIFI_MODE_STA);
#endif
Obsługa komunikacji
ESP-NOW działa w oparciu o callbacki – funkcje, które są wywoływane automatycznie w odpowiedzi na zdarzenia. Dzięki temu w pętli loop()
jest niewiele kodu.
Jednym z podstawowych callbacków jest funkcja obsługująca odebrane wiadomości. Rejestrujemy ją w następujący sposób:
esp_now_register_recv_cb(received_msg_callback);
A sama funkcja wygląda tak:
void received_msg_callback(const uint8_t* mac, const uint8_t* incomingData, int len)
W jej wnętrzu możemy wykorzystać parametry: adres MAC nadawcy oraz treść odebranej wiadomości. Nie musimy ręcznie sprawdzać, czy przyszły nowe dane – ESP-NOW automatycznie wywoła naszą funkcję, co jest bardzo wygodne.
Przykłady projektów
Point to point
Przykad komunikacji punkt–punkt, znajduje się w trzech wersjach (dla ESP8266, ESP32 i wspólnego wrappera esp noww). Można przez to łączyć np. ESP32 i ESP8266. Jeden moduł (sender) wysyła prostą wiadomość do drugiego (receiver) na podstawie jego adresu MAC, który musimy podać w kodzie. Wiadomość ma prostą strukturę i jest wyświetlana w Serial Monitorze po przyjściu. To najprostszy przykład dobry na start, żeby sprawdzić czy wszystko działa.
ESP8266 jako centralny moduł
Przykład dla ESP8266 – central został przygotowany dla projektu, w którym do płytki EVW-008 (o której już wspominałem) podłączyłem ekran OLED oraz czytnik RFID. Projekt ten współpracuje z przykładem slave oraz web_server na ESP32, które ma podłączony czujnik BME280 oraz serwer działający na innym ESP32.

Trzy wersje komunikacji centralnej
- central_to_select
Wysyła wiadomość do konkretnych płytek. Adresy MAC są definiowane w plikuconfig.h
:const uint8_t slave_address_1[] = {0x3C, 0xE9, 0x0E, 0x7F, 0x30, 0x80};
const uint8_t slave_address_2[] = {0x3C, 0xE9, 0x0E, 0x7F, 0x30, 0x58};
Po przyłożeniu odpowiedniego taga RFID wysyłana jest wiadomość do konkretnej płytki. Może ona odpowiedzieć np. temperaturą, którą następnie wyświetlamy na ekranie. // zdjęcie ekranu - central_broadcast
Wysyła wiadomość na adres broadcastFF:FF:FF:FF:FF:FF
, co oznacza, że każda płytka w zasięgu ją otrzyma. - central_to_server
Jest to specyficzny przypadek, ponieważ współpracuje z serwerem działającym na ESP32. Musimy podać nazwę sieci WiFi, do której podłączony jest serwer, lub ręcznie określić kanał WiFi. Dlaczego? Żeby ESP mogło korzystać jednocześnie z WiFi i ESP-NOW, musi działać na tym samym kanale WiFi. Serwer podczas inicjalizacji WiFi wypisuje numer kanału i adres IP na Serial Monitorze. Możemy wpisać ten adres w przeglądarce i zobaczyć efekty działania systemu. Po przyłożeniu taga RFID jego kod pojawi się na stronie hostowanej przez serwer.

To wszystko, myślę że jest dobrą bazą do modyfikacji w inne projekty.
Ważne jest tutaj to, że w kodzie sami musimy zwrócić uwagę na format wiadomości i utrzymać go na obu urządzeniach. Żeby to sobie uprościć możemy korzystać np. z rozwiązań jakim jest protobuf, co za jakiś czas będę chciał pokazać 😉
Mam nadzieję, że już z tymi projektami,dacie sobie radę i będziecie mogli zbudować coś swojego. Jeśli macie jakieś pytania, piszcie!