Giovedì, 27 Febbraio 2020 22:05

Accendere un led da remoto con ESP8266

Scritto da

Lo ESP8266 è una sorta di basetta di prototipazione simile ad Arduino ma con una serie di varianti hardware fondamentali che lo rendono accattivante per molti esperimenti, il WiFi su tutte! Vediamo un primo esempio semplice di base per introdurre alcune delle funzionalità che possiamo usare da remoto.

Una delle prime esperienze che si fa con Arduino è quello di accendere e spegnere un led, per introdurre gli elementi fondamentali di uno "sketch" e le funzioni predefinite fondamentali per lavorare con i pin digitali e la loro caratteristica fondamentale di acceso/spento. L'idea è quello di riproporre qualcosa di analogo ma questa volta con un pizzico di difficoltà in più. Lo ESP8266 infatti è dotato di pin digitali con cui potremmo ripetere l'esperinza descritta ne più ne meno come con una qualsiasi basetta Arduino, ma con una basetta WiFi come la nostra vogliamo realizzare un piccolo server web connesso alla rete locale WLAN che rimane in ascolto di una istruzione per accendere o spegnere un led a cui è collegata. L'istruzione la richiederemo al nostro server web con una semplice pagina HTML che ci farà da GUI con un paio di bottoni ad hoc per pilotare il led. Vediamo come.

Cosa ci occorre

  • una basetta ESP8266
  • un cavetto micro-usb
  • un diodo led (colore a piacere)
  • due cavetti dupont femmina-maschio (colore a piacere)
  • una breadboard (a piacere da 830 o 400 fori)
  • una resistenza da 220 ohm (opzionale)
  • software Arduino (scarica qui versione di test 1.8.12)

Prepariamo l'IDE

Prepariamo prima l'ambiente di sviluppo ovvero il nostro IDE Arduino per riconoscere la scheda. Se non lo abbiamo fatto in altre esercitazioni, ci occorre aggiungere al nostro IDE la il software della scheda. Andiamo in File->Impostazioni->URL Aggiuntive per il gestore Schede e incolliamoci questo URL ufficiale e sempre aggiornato:

https://arduino.esp8266.com/stable/package_esp8266com_index.json

Selezioniamo la porta. Su linux la porta di default è la /dev/ttyUSB0. Su Windows, a second della versione che usate, potrebbe essere una tra le COM1, COM2 o la più probabile COM3. Selezionatela nella voce di menù Strumenti->Porta avendo cura di provare anche le altre se lo sketch desse errore in fasi di upload. In genere, su Windows, la porta viene riconosciuta automaticamente o compare una voce di fianco nella tendina che indica il nome del dispositivo.

Selezioniamo il dispositivo, ovvero scheda, corretto. Qui ci sono due possibilità: o usiamo la versione ESP8266 nuda e creda che fa uso di una architettura GPIO per la numerazione dei pin oppure ricorriamo ad una semplificazione con scheda NodeMCU 1.0 (ESP12E-Module) che nomina i pin con le lettere che sono stampate direttamente sulla basetta. Lasciamo ad altri post la spiegazione, vantaggi e svantaggi dei due approcci. Per la nostra esperienza ci basta configurare al meglio il tutto in modo semplice. Usate la voce di menù sull'IDE Strumenti->Scheda e cercate nella tendina la voce indicata NodeMCU 1.0 (ESP12E-Module). Notiamo che alcune librererie aggiuntive sono spesso scritte per ragionare con la scheda ESP8266, altre volte con la NodeMCU: il discrimine si evidenzia in fase di compilazione poiché avremo un errore sul nome utilizzato per pilotare i pin. Se tra le schede non compare il nome indicato, niente paura, dobbiamo aggiungerlo da libreria. Andate quindi  Strumenti->Scheda->Gestore Schede e nella finestrella in alto a destra cercate ESP8266, vi comparirà un risultato ESP8266 by ESP8266 Community che, mentre scriviamo, è arrivata alla versione 2.6.3.

In Strumenti->Gestione librerie assicuriamoci che sia installata la libreria che ci fornisce funzioni e strumenti vari per gestire le connessioni senza fili. Scorrete la lista fino a trovare WiFi built-in Arduino, giunto alla versione 1.2.7. Stessa cosa, cercate ed installate Arduino Uno WiFi Dev ed by Arduino.

Assemblaggio

esp8266led

Assemblare il nostro esperimento è semplicissimo e rapido. Basta collegare i cavetti dupont al pin digitale D0 e al catodo del led, l'anodo in modo analogo ad una delle porte GND del ESP8266 (ce ne sono due equivalenti). Potete valutare di appoggiare direttamente lo ESP8266 sulla breadboard, ma in questo caso vi serviranno cavetti dupont maschio-maschio per creare i collegamenti. Ovviamente ci servirà un cavetto usb per collegare la basetta ad un pc ed avere anche l'alimentazione. Se il led è poco potente, potrebbe essere opportuno proteggerlo dalla tensione di alimentazione con una resistenza, magari anche piccolina da 220ohm facilmente reperibile.

 IMG20200228185119IMG20200228185042

Il codice

 A questo punto dovremmo essere pronti per scrivere il nostro codice ed inviarlo alla scheda. Per test, possiamo riproporre un frammento di codice che accende e spegne il led esattamente come faceva il più classico degli arduino senza scomodare funzionalità particolari.

void setup() {
  pinMode(D0, OUTPUT);    //Dichiaro il pin D0 in Output
}
 
void loop() {
  digitalWrite(D0, HIGH);   //Imposto Alto il pin D0
  delay(1000);              //Attendo 1 secondo
  digitalWrite(D0, LOW);    //Imposto Basso il pin D0
  delay(1000);              //Attend0 1 secondo
}

 Ovviamente verifichiamo e carichiamo il nostro sketch con i pulsanti relativi sull'IDE. Se tutto è andato per il verso giusto avremo il nostro led lampeggiante.

Complichiamo la struttura ed aggiungiamo le funzionalità wireless. Ci occorre prima di tutto un include alle librerie su misura ed ottimizzate per la nostra basetta e le funzioni WiFi. Stessa cosa per l'include della libreria ESP8266WebServer che ci servirà per costruire un server in ascolto. Dopo, ci andiamo a dichiarare una variabile stringa che conterrà il codice ssid della rete WiFi ed una stringa per la password. Tralasciamo la problematica dei dati di accesso scritti in chiaro e l'opportunità di sostituire la definizione String con const char* che, come vettore di caratteri, ha una occupazione di memoria a runtime minore di una dichiarazione del tipo String più compatto da usare. Andiamo quindi a inizializzare il nostro server web sulla porta 80. Su sketch ed esempi online potrete trovare analoga ma generica dichiarazione WiFiServer server(80). Nella parte di setup, apriamoci una console per avere dei messaggi di debug aprendo la tendina Strumenti->Monitor seriale assicurandoci che la banda della console sia uguale tra codice e valore nella tendina in basso a destra della finestra della console stessa per non far apparire caratteri strani e incomprensibili.

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

String ssid     = "tuossidwifi";
String password = "tuapassword";

ESP8266WebServer server(80);

void setup() {
Serial.begin(115200);
}

void loop() {

}

Bene, passiamo a creare il nostro server web. Arricchiamo il nostro codice

void setup() {
  Serial.begin(115200);
  
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("Sei collegato alla rete LAN");
  Serial.println(WiFi.localIP());
}

void loop() {

}

Viene richiesta una connessione alla rete WiFi con tanto di puntini di attesa stampati a video e, a collegamento effettuato, la stampa dell'IP impostato.  Facciamo un ulteriore passettino ed impostiamo il pin per il nostro led come nel frammento di codice senza wifi, con un pinmode in output e impostiamolo di default a spento/basso.

void setup() {
  Serial.begin(115200);
  
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("Sei collegato alla rete LAN");
  Serial.println(WiFi.localIP());
  
  pinMode(D0,OUTPUT); 
  digitalWrite(D0,LOW); 
  
}

Il codice richiede un IP privato col DHCP. Se avete necessità di testing su rete con IP fisso, aggiungete sempre nel setup prema del WiFi.begin le seguenti righe di codice dove andrete a modificare i vari valori secondo le necessità della vostra rete.

IPAddress ip(192, 168, 1, 108); 
IPAddress gateway(192, 168, 1, 1); 
IPAddress subnet(255, 255, 255, 0); 

WiFi.config(ip, gateway, subnet);

Adesso la parte più ostica ma fondamentale del nostro sketch: la gestione del server e della pagina web. L'idea alla base è fondamentalmente semplice: un servizio attivo rimane in ascolto sulla porta scelta e, a seconda dell'URL inviatogli con modalità REST, restituisce una pagina HTML. Se viene chiamato il server senza URL, si restituisce al client una pagina con dei semplici bottoni per controllare il led. Se cliccati, i bottoni chiamano delle risorse che obbligano il server ad accendere o spegnere il led e ritornare una pagina HTML con lo status del led.

Per inizializzare il server, nel setup aggiungiamo un frammento di codice che mette su il server e imposta gli URL che accetta con le conseguenti azioni da scatenare nelle relative funzioni che ho chiamato pagina, paginaon e paginaoff

  server.begin();  
  Serial.println("Server online");

  //gestiamo le azione passate col GET nell'url
  server.on("/",    pagina);    //pagina base
  server.on("/ledon",  paginaon);  //pagina cliccato acceso
  server.on("/ledoff", paginaoff); //pagina cliccato spento

Nel loop invece andremo ad inserire un "ascoltatore" che rimane in attesa di una qualche richiesta da un browser

void loop() {
  server.handleClient(); 
}

Andiamoci a definire le funzioni pagina, paginaon e paginaoff e tutti gli annessi necessari. Lo andiamo a fare nella parte precedente il loop. Per prima cosa ci prepariamo una pagina HTML che visualizzerà i bottoni per accendere e spegnere il led. Uso quattro variabili stringa che andremo ad assemblare "su misura" in modo modulare a seconda di cosa dobbiamo visualizzare e comporre nella nostra pagina web. La funzione pagina non farà altro che ricomporre queste stringhe per visualizzare la pagina con i bottoni senza altri fronzoli. Con una semplice funzione, il server  rimanda "send"  la stringa con lo status HTTP e il tipo di documento.

String head = "<!DOCTYPE html><html><head><title>ESP8266 LED</title></head>";
String body  = "<body><h1>Controllo LED</h1><a href=\"/ledon\"><button class=\"button\">ON</button></a>  <a href=\"/ledoff\"><button class=\"button\">OFF</button></a>";
String footer= "</body></html>";
String html;


void pagina()
{
  html = head + body + footer;
  server.send(200, "text/html", html);   
}

Una schermata della pagina principale richiamata semplicemente inserendo l'IP nella barra del browser

Il codice e la sua resa estetica sono decisamente minimali, ma si lascia al lettore l'opportunità di aggiungere descrizioni e fogli di stile magari inline.

Le funzioni paginaon e paginaoff sono molto simili. Prima cosa accendono o spengono il led con la funzione digitalWrite e poi restituiscono una pagina HTML che però è assemblata aggiungendo, ai frammenti String precedenti, una stringa che visualizza anche sulla pagina lo stato del led se acceso o spento.

void paginaon()
{
 digitalWrite(D0,HIGH); 
 String stato = "<br>LED acceso";
 html = head + body + stato + footer;
 server.send(200, "text/html", html );
}

void paginaoff()
{
 digitalWrite(D0,LOW); 
 String stato = "<br>LED spento";
 html = head + body + stato + footer;
 server.send(200, "text/html", html );
}

IMG20200228190127 IMG20200228190209

 

 

Il codice intero che trovate anche con estensione compatibile arduino tra gli allegati

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

String ssid     = "tuossidwifi";
String password = "tuapassword";

ESP8266WebServer server(80);

String head = "<!DOCTYPE html><html><head><title>ESP8266 LED</title></head>";
String body  = "<body><h1>Controllo LED</h1><a href=\"/ledon\"><button class=\"button\">ON</button></a>  <a href=\"/ledoff\"><button class=\"button\">OFF</button></a>";
String footer= "</body></html>";
String html;



void pagina()
{
  html = head + body + footer;
  server.send(200, "text/html", html);   
}

void paginaon()
{
 digitalWrite(D0,HIGH); 
 String stato = "<br>LED acceso";
 html = head + body + stato + footer;
 server.send(200, "text/html", html );
}

void paginaoff()
{
 digitalWrite(D0,LOW); 
 String stato = "<br>LED spento";
 html = head + body + stato + footer;
 server.send(200, "text/html", html );
}

void setup() {
  Serial.begin(115200);
  
  IPAddress ip(192, 168, 1, 108); 
  IPAddress gateway(192, 168, 1, 1); 
  IPAddress subnet(255, 255, 255, 0); 
  WiFi.config(ip, gateway, subnet);

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("Sei collegato alla rete LAN");
  Serial.println(WiFi.localIP());
  
  pinMode(D0,OUTPUT); 
  digitalWrite(D0,LOW); 
  
  server.begin();  
  Serial.println("Server online");

  //gestiamo le azione passate col GET nell'url
  server.on("/",    pagina);    //pagina base
  server.on("/ledon",  paginaon);  //pagina cliccato acceso
  server.on("/ledoff", paginaoff); //pagina cliccato spento
}

void loop() {
  server.handleClient(); 
}
Letto 359 volte
Prof. Alfredo Centinaro

Docente di "Scienze e tecnologie informatiche", "Tecnologie e progettazione di sistemi informatici", "Sistemi e Reti" presso IIS Alessandrini-Marino (Teramo), consulente e sviluppatore web. Ha collaborato per anni come sviluppatore presso MHT - Treviso, assistente Sistemi ed elaborazione dell'informazione in UniTE Corso di laurea in Scienze del turismo culturale, tutor presso Telecom Italia Learning Services (L'Aquila)

Joomla SEF URLs by Artio