ESP-NOW: comunicazione tra ESP32 senza router WiFi

Pubblicato il 02/05/2026 ESP32

Quando ESP-NOW batte WiFi/MQTT

WiFi + MQTT richiedono un router e un broker. ESP-NOW comunica direttamente tra ESP32, senza access point. Casi d'uso ideali:

  • Telecomandi DIY (pulsantiera → attuatore)
  • Reti di sensori in serra/cantina senza copertura WiFi
  • Mesh tra rover/droni
  • Sincronizzazione di striscioni LED a parete

Latenza tipica: 2-5 ms (vs 50-200 ms con MQTT). Portata: 100-200 m all'aperto, 30-50 m in casa.

MAC address: il "numero di telefono"

Ogni ESP32 si identifica con il MAC. Ottienilo con uno sketch banale:

#include <WiFi.h>
void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  Serial.println(WiFi.macAddress());
}
void loop() {}

Annota il MAC del ricevitore: ti serve per configurare il mittente.

Sketch RICEVITORE

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

typedef struct {
  int sensor_id;
  float temperatura;
  int batteria_pct;
} Messaggio;

Messaggio dati;

void onReceive(const esp_now_recv_info* info, const uint8_t *data, int len) {
  memcpy(&dati, data, sizeof(dati));
  Serial.printf("Sensor %d: %.2f°C (batt %d%%)\n",
    dati.sensor_id, dati.temperatura, dati.batteria_pct);
}

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  if (esp_now_init() != ESP_OK) { Serial.println("Init fallito"); return; }
  esp_now_register_recv_cb(onReceive);
}

void loop() {}

Sketch MITTENTE

Sostituisci RECEIVER_MAC con il MAC del ricevitore:

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

uint8_t RECEIVER_MAC[] = {0x24, 0x0A, 0xC4, 0x12, 0x34, 0x56};

typedef struct {
  int sensor_id;
  float temperatura;
  int batteria_pct;
} Messaggio;

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  esp_now_init();

  esp_now_peer_info_t peer = {};
  memcpy(peer.peer_addr, RECEIVER_MAC, 6);
  peer.channel = 0;
  peer.encrypt = false;
  esp_now_add_peer(&peer);
}

void loop() {
  Messaggio m = {1, 22.5, 87};
  esp_now_send(RECEIVER_MAC, (uint8_t*)&m, sizeof(m));
  delay(2000);
}

Broadcast a tutti i nodi

Usa il MAC FF:FF:FF:FF:FF:FF come indirizzo destinazione: tutti gli ESP32 sulla stessa rete ricevono. Utile per "spegni tutte le luci".

Cifratura dei messaggi

Per dati sensibili abilita la cifratura PMK/LMK (chiavi a 16 byte):

const uint8_t PMK[16] = "iLbAr0n3-12345678";
esp_now_set_pmk(PMK);

peer.encrypt = true;
memcpy(peer.lmk, PMK, 16);

Combinare ESP-NOW + WiFi normale

È possibile far convivere ESP-NOW e una connessione WiFi standard sullo stesso ESP32, ma devono essere sullo stesso canale. Trucco: dopo WiFi.begin() leggi WiFi.channel() e configura il peer ESP-NOW con quel canale.

Limiti

  • Massimo 250 byte per messaggio (ok per telemetria, no per file)
  • Massimo 20 peer per dispositivo (con cifratura: 6)
  • Niente conferma applicativa: implementa tu retry/ack se serve
  • Nessun routing: tutti devono essere in raggio del trasmettitore

Quando NON usarlo

Se hai già un router WiFi e Home Assistant, MQTT è più flessibile (web dashboard, automazioni, persistenza). ESP-NOW vince in scenari isolati, batteria critica o latenza minima.