In questo post vedremo due brevi programmi per testare sul campo la rete ESP-NOW, di cui abbiamo già scritto in questo articolo introduttivo del nostro blog. Vedremo come usare due ESP32-CAM per creare una rete “mesh” con portata di 40~50 metri sfruttando l’antenna incorporata di circa 10 cm. La ESP32-CAM è un microcontroller interessantissimo che unisce alla velocità dell’ESP32 “classico” una webcam 1600X1200 px, il tutto ad un prezzo assai allettante. E’ disponibile su Aliexpress a meno di dieci euro.
Nel dettaglio vedremo due brevi programmi per inviare e ricevere una sequenza numerica senza WI-FI ma sfruttando le qualità radio “native” della scheda. Si tratta di un vantaggio importante perchè permette di far funzionare tutta la rete presso nuovi utenti senza impostare manualmente login e password. Il protocollo di comunicazione di Espressif sostituisce il normale WI-FI ma ne conserva certamente molti dettagli tecnici: infatti i nostri programmi sorgenti useranno questa istruzione:
#include "WiFi.h"
per settare lo “scope” del WI-FI classico ed ereditarne variabili e strutture dati. Per creare la rete faremo inoltre uso di un mini programma per trovare l’indirizzo MAC della scheda ESP ricevente. Il protocollo ESP-NOW prevede, infatti, di specificare il MAC di ogni scheda abilitata alla ricezione. In questo modo possiamo indirizzare caso per caso tutte le destinazioni. Tutte le schede entro 30~40 metri diverranno così accessibili a patto che abbiano completato l’accesso con queste istruzioni:
if (esp_now_add_peer(&peerInfo) != ESP_OK){
Serial.println("Non riesco ad aggiungere il dispositivo");
return;
}
Il programma è brevissimo e prevede la “include” a WIFI.h e l’uso della funzione “WiFi.macAddress()”. Per usarlo serve fare l’upload nell’IDE di Arduino e annotare il valore che appare nel “serial monitor”. Se invece usate il programma con PlatformIO potete compilare il programma con “make upload” e quindi lanciare la utility minicom per visualizzare l’output.
#include "WiFi.h"
void setup(){
Serial.begin(115200);
WiFi.mode(WIFI_MODE_STA);
Serial.print("indirizzo MAC=");
Serial.println(WiFi.macAddress());
}
void loop(){
}
Usando PlatformiIO potete usare questo file di settaggio per riconoscere in automatico la ESP32-CAM:
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:esp32cam]
platform = espressif32
board = esp32cam
framework = arduino
monitor_speed=115200
lib_ldf_mode=deep
build_flags =
-I../lib/esp32-camera
lib_deps =
Nella immagine sopra puoi vedere l’indirizzo MAC E0:5A:1B:6C:E4:B0 che useremo nel programma di trasmissione.
In questo programma useremo l’indirizzo MAC scoperto in precedenza per selezionare il dispositivo ricevente. Il protocollo mesh di Espressif prevede di usare il sistema degli indirizzi hardware anche quando i dispositivi sono solo due.
#include <esp_now.h>
#include <WiFi.h>
// Indirizzo MAC del dispositivo di destinazione
// Sostituire nella riga in basso indirizzo MAC
// trovato con la utility apposita
uint8_t broadcastAddress[] = {0xE0, 0x5A, 0x1B, 0x6C, 0xE4, 0xB0};
// Struct per definire il formato dei dati
typedef struct struct_messaggio {
int contatore;
} struct_messaggio;
struct_messaggio Dati;
esp_now_peer_info_t peerInfo;
int ix;
// funzione callback da invocare dopo invio
void suInvioDati(const uint8_t *mac_addr, esp_now_send_status_t status) {
Serial.print("\r\nStatus invio:\t");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Consegna positiva" : "Errore di consegna");
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
// Inizializza ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Errore di inizializzazione per ESP-NOW");
return;
}
esp_now_register_send_cb(suInvioDati);
ix= 0;
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
// Aggiungi dispositivo
if (esp_now_add_peer(&peerInfo) != ESP_OK){
Serial.println("Non riesco ad aggiungere il dispositivo");
return;
}
}
void loop() {
// Valori da inviare
Dati.contatore = ix;
ix=ix+1;
// invio del messaggio
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &Dati, sizeof(Dati));
if (result == ESP_OK) {
Serial.println("Messaggio inviato con successo");
}
else {
Serial.println("Errore di invio");
}
delay(2000);
}
Questo è il sorgente per ricevere i dati in arrivo dalla scheda trasmittente. Fai attenzione alla struct messaggio: sia pure semplicissima deve corrispondere alla struct del programma in trasmissione. In un prossimo post useremo questa stessa struttura per invocare molteplici dati.
typedef struct struct_messaggio {
int b;
} struct_messaggio;
#include <esp_now.h>
#include <WiFi.h>
// Struttura di esempio
typedef struct struct_messaggio {
int b;
} struct_messaggio;
struct_messaggio Dati;
// Funzione di callback dopo invio dati
void suDatiRicevuti(const uint8_t * mac, const uint8_t *incomingData, int len) {
memcpy(&Dati, incomingData, sizeof(Dati));
Serial.print("Conteggio dei bytes ricevuti: ");
Serial.println(len);
Serial.print("Int: ");
Serial.println(Dati.b);
Serial.println();
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
// Inizializza la rete ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Errore nella inizializzazione della rete ESP-NOW");
return;
}
esp_now_register_recv_cb(suDatiRicevuti);
}
void loop() {
}
Nella immagine sopra puoi vedere la sequenza automatica generata dal primo ESP32-CAM e ricevuta dalla seconda ESP32-CAM (619,620,621, etc..).
Con soli tre brevissimi programmi abbiamo impostato la struttura di funzionamento della rete mesh. Nei prossimi articoli vedremo come usare questa struttura per realizzare dei compiti utili, con l’utilizzo di 3 o 4 schede ESP32 di modello diverso.
Robotdazero.it - post - R.123.3.6.0