Nella prima lezione è stata fatta una panoramica sul mondo della domotica mettendo in evidenza i principali problemi e ostacoli, legati principalmente al fatto di non avere uno standard di comunicazione unico, e si è visto inoltre come domotica e IoT stanno convergendo verso un'unica direzione. Proprio a partire da queste considerazioni è stato pensato e realizzato, attraverso l'utilizzo della scheda di sviluppo ESPertino, un sistema composto da dispositivi intelligenti che, oltre a eseguire funzioni specifiche come ad esempio il pilotaggio di un carico o l'invio di un comando per l'attivazione di una luce, sono in grado di interconnettersi e comunicare tra loro attraverso una rete Ethernet.
IMPLEMENTAZIONE PAGINA WEB
Per fare in modo che l'utente possa interagire con il sistema domotico occorre necessariamente che quest'ultimo metta a disposizione dell'utilizzatore un'interfaccia utente intuitiva, gradevole, che non sia complicata da installare e che magari faccia uso di software o sistemi comuni e già conosciuti dall'utente. Visto e considerato che la scheda ESPertino può essere configurata per funzionare come un WebServer, la soluzione ottimale per la realizzazione della GUI e che soddisfa le caratteristiche sopracitate, è sicuramente quella di utilizzare una pagina HTML con relativo foglio di stile e codice Javascript.
A tal proposito si è scelto di realizzare la GUI utilizzando proprio una pagina web e nella fattispecie il file che la realizza è "webpage.html", il quale merita una trattazione approfondita. Questo file, essendo a tutti gli effetti una pagina HTML, è divisa in tre parti:
- la prima parte è composta dagli stili CSS
- la seconda parte è composta dalle funzioni JavaScript
- la terza parte è il codice HTML
Risulta abbastanza chiaro che ai fini della comprensione del progetto, la parte più importante da descrivere è la seconda in quanto è composta dalle funzioni in JavaScript utili alla comunicazione con il dispositivo, mente invece la prima e la terza parte, oltre ad essere relativamente semplici, servono a dare struttura e gradevolezza alla pagina. Per questi motivi mi limiterò nella descrizione delle sole funzioni JavaScript; per chi volesse approfondire anche le altre parti le può trovare nei file in allegato al presente articolo.
La funzione più importante e che sta alla base di tutte le altre è "sendHttpAsync
". Questa funzione, utilizzando l'oggetto "XMLHttpRequest
", si occupa fondamentalmente di impacchettare in una richiesta HTTP i parametri (contenuti nella variabile "params
") da inviare e quindi di eseguire l'invio. Oltre ai parametri da inviare la funzione ha bisogno di sapere l'url a cui inviare la richiesta (parametro "url
"), la modalità di invio dei parametri se in GET o in POST (parametro "method
") e due funzioni da richiamare, la prima quando l'invio è terminato (parametro "callback"
) e la seconda quando scade il timeout di attesa (parametro "callbackTimeout
"). La presenza di un timeout di attesa risulta particolarmente utile per evitare che la pagina web rimanga bloccata, nel momento in cui per qualche ragione il dispositivo smettesse di rispondere alle richieste:
function sendHttpAsync(url,callback,callbackTimeout,params,method)
{
var http = new XMLHttpRequest();
objHttpTimeout=setTimeout(callbackTimeout,TIMEOUT_HTTPCONNECTION);
method=method||"GET";
if(method=="GET")
http.open(method,url+"?"+params,true);
else if(method=="POST")
{
http.open(method,url,true);
//Send the proper header information along with the request
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
}
http.onreadystatechange = function()
{
//Call a function when the state changes.
if(http.readyState == 4 && http.status == 200)
{
if(objHttpTimeout!=null)
clearTimeout(objHttpTimeout);
if(callback!=null)
callback(http.responseText);
}
}
if(method=="GET")
http.send(null);
else if(method=="POST")
http.send(params);
}
Come possiamo vedere dal corpo della funzione, la prima cosa che viene eseguita è la creazione del timeout, a cui viene passata la funzione da richiamare e il tempo di timeout (variabile "TIMEOUT_HTTPCONNECTION
" impostata a 10.000 ms); una volta impostato il timeout viene avviato l'oggetto "http
" (istanza di "XMLHttpRequest
") tramite il comando "open". Prima di eseguire questa operazione occorre però distinguere con che metodo dovranno essere inviati i parametri in quanto, se in GET questi dovranno essere accodati all'URL, se in POST invece dovranno essere passati come parametro al momento dell'invio della richiesta e dovrà essere settato opportunamente l'Header HTTP tramite la riga di codice "http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
". Avviato l'oggetto "http
" viene settata, tramite "http.onreadystatechange
", la funzione di callback che segnala il cambio dell'attributo "readyState" del
l'oggetto "XMLHttpRequest"
e quindi viene successivamente richiamato il comando "send
" per eseguire l'invio vero e proprio della richiesta HTTP. Per fare in modo che la funzione passata nel parametro "callback
" venga chiamata solo quando l'invio è terminato (il cambio dell'attributo "readyState"
può essere causato anche da altri eventi), è stato inserito ulteriore codice che verifica se i valori "http.readyState
" e "http.status
" hanno o meno i valori 4 e 200 rispettivamente. Per [...]
ATTENZIONE: quello che hai appena letto è solo un estratto, l'Articolo Tecnico completo è composto da ben 2199 parole ed è riservato agli ABBONATI. Con l'Abbonamento avrai anche accesso a tutti gli altri Articoli Tecnici che potrai leggere in formato PDF per un anno. ABBONATI ORA, è semplice e sicuro.
Bellissimo Articolo
Complimenti!
Grazie ? ci vediamo per l’ultima parte dell’articolo!
mi chiamo Emanuele, scusate se posto qui ma è la prima volta che scrivo.
Il compilatore si blocca con questo messaggio e non riesco a risolvere il problema.
Grazie in anticipo.
Arduino:1.8.3 (Windows 10), Scheda:”ESPertino, 80MHz, 921600, None”
ATTENZIONE: la libreria WiFi dichiara di funzionare sulle architetture (esp32) e potrebbe non essere compatibile con la tua scheda che utilizza l’architettura (ESPertino)
D:\carbo\Mail.Ru\Arduino\Progetti Arduino\ESPertino\switch\switch.ino: In function ‘void exOperations(WiFiClient*)’:
switch:55: error: ‘class libESPdom’ has no member named ‘sendHttp’
espdom.sendHttp(client,(char*)info);
^
switch:72: error: ‘class libESPdom’ has no member named ‘sendHttp’
espdom.sendHttp(client,(char*)webpage);
^
exit status 1
‘class libESPdom’ has no member named ‘sendHttp’
Ciao Emanuele. Nessun problema, sei nel posto giusto 🙂
Ora non riesco a dirti con precisione ma se non ricordo male è lo stesso problema che ho avuto io: fondamentalmente il problema è dovuto al fatto che sia le librerie native dell’ambiente di Arduino, sia le librerie per l’esp32 hanno entrambe la cartella “wifi” che contiene (in entrambi i casi) le librerie per la gestione della connessione wifi.
Avevo approfondito la questione anche con loro della redazione e la soluzione che ho adottato, anche se non proprio la più elegante, è stata quella di spostare la cartella “wifi” delle librerie dell’ambiente Arduino, in un altro percorso sul PC (o cancellarla ma per sicurezza te lo sconsiglio). Prova e fammi sapere se il problema è stato risolto.
Come ti dicevo ora non riesco a fornirti ulteriori dettagli ma questo sera ti darò conferma oltre che maggiori dettagli.
Ciao!
Ciao Luca, grazie della tempestività del tuo aiuto.
Ho provato a spostare altrove la dir wifi ma niente mi dava lo stesso messaggio.
Ho copiato la wifi di espertino nelle librerie native di arduino, mantenendola anche in espertino il messaggio e cambiato si capisce che ora usa la libreria giusta ma in sostanza il risultato non e cambiato ecco cosa mi esce ora
Arduino:1.8.3 (Windows 10), Scheda:”ESPertino, 80MHz, 921600, None”
ATTENZIONE: la libreria WiFi dichiara di funzionare sulle architetture (esp32) e potrebbe non essere compatibile con la tua scheda che utilizza l’architettura (ESPertino)
D:\carbo\Mail.Ru\Arduino\Progetti Arduino\ESPertino\switch\switch.ino: In function ‘void exOperations(WiFiClient*)’:
switch:55: error: ‘class libESPdom’ has no member named ‘sendHttp’
espdom.sendHttp(client,(char*)info);
^
switch:72: error: ‘class libESPdom’ has no member named ‘sendHttp’
espdom.sendHttp(client,(char*)webpage);
^
Più di una libreria trovata per “WiFi.h”
Usata: C:\Program Files (x86)\Arduino\hardware\espressif\ESPertino\libraries\WiFi
Non usata: C:\Program Files (x86)\Arduino\libraries\WiFi
exit status 1
‘class libESPdom’ has no member named ‘sendHttp’
a questo punto come ultimo tentativo ho eliminato la wifi presente nella dir di espertino mantenedo quella in arduino, ma come prevedevo, non trova piu il conflitto delle librerie ma l’errore permane.
Fammi sapere come avete risolto Voi.
Comunque a parte tutto devo dire che il modo di gestire le librerie nel IDE di arduino non mi e mai piaciuto: troppo confusionario a mio parere.
Cosa ne pensate Voi?
Dovrei migrare per il mio progetto su altri ambienti di sviluppo piu professionali solo che sicuramente piu complicati e forse credo senza quel grande assortimento di librerie che c’è con arduino. Lavoro con ESP e compagnia ma di arduino e rimasto solo l’IDE.
Tu personalmente cosa usi?
Vi ringrazio e anche se non intervengo quasi mai comunque vi seguo sempre e vi ammiro.
Spero se non questo il prossimo corso di iscrivermi all’accademy.
Grazie a presto.
Ciao Emanuele! Ti confermo che nel mio caso avevo tolto la libreria WiFi nativa di Arduino e lasciato quelle dell’ESP.
Da come dici però tu non hai provato a lasciare la WiFi di ESP ma hai fatto la prova lasciando solo quella nativa di Arduino: prova a spostare quella nativa di Arduino e lasciare quella di ESP.
Ad ogni modo che versione hai dell’IDE di Arduino? Te lo chiedo perché ho installato l’ultima versione e la compilazione va a buon fine senza togliere la cartella WiFi dalle librerie native di Arduino.
Si la gestione delle librerie di Arduino non è il massimo ma credo che la cosa sia voluta: il mondo di Arduino è destinato a chi si approccia per la prima volta nel mondo dell’embedded.
Per il progetto in questione o Arduino io personalmente uso l’IDE di Arduino ma se devi sviluppare qualcosa di più professionale, ti consiglierei di orientarti verso gli IDE delle case produttrici di microcontrollori (ad esempio per Arduino Atmel, quindi Microchip): generalmente sono gratuiti e professionali.
ver. dell’IDE 1.8.3. Comunque avevo come primo tentativo fatto quello che a te ha funzionato. Ma niente. Ho provato su un’altro pc ma niente, stesso messaggio. Mi sarebbe piaciuto seguire l’articolo perchè interessato a implementare nelle centraline, che costituiscono i nodi della mia rete, un webserver proprio allo scopo di inserirvi i dati di configurazione delle stesse eliminando tastiere e display. Attualmente uso come librerie la “WiFiManager” di tzapu o sto provando ora quella di travis che comunque vanno bene, fanno il loro lavoro, ma la grafica e le possibilità di modificarla sono limitate ed il risultato finale è poco professionale o se non altro poco personalizzabile. Un po meglio con l’integrazione di “emoncms” ( http://pdacontrolen.com/). Grazie per la pazienza ed il tempo che mi hai dedicato Luca. Magari se risolvo il problema lo posto. un saluto a tutti e buon lavoro.
Ciao,
io avevo lo stesso problema.
Oltre a cancellare le librerie native ho dovuto creare un nuovo sketch “sostituendo” di fatto il file switch.ino con un file nuovo.
Con il file scaricato dall’articolo non riuscivo a linkare in nessun modo la libreria Wifi.h
Inoltre ho dovuto cambiare il nome del metodo “espdom.sendHttp” con “espdom.sendResponseHttp”. Infatti nel file .h della classe sendHttp non esiste.
Ciao Gianmarco e grazie per il suggerimento!
E’ strano che hai dovuto sostituire il file “switch.ino” in quanto dovrebbe contenere solo il codice sorgente, senza riferimenti a librerie.
Ad ogni modo, visto che mi dici che hai dovuto sostiutire “espdom.sendHttp” con “espdom.sendResponseHttp”, credo proprio che sono state aggiornate le librerie dell’ESP32.
Molto probabilmente non ottengo l’errore durante la compilazione perché ho aggiornato l’IDE di Arduino e le librerie dell’ESP32 non aggiornate.
@Emanuele: con i suggerimenti di Gianmarco sei riuscito a compilare?
Rieccomi di nuovo.
Grazie all’aiuto di Giovanni e Stefano (della redazione), siamo riusciti a capire quali sono i problemi:
1) il file zip da me caricato crea una cartella “Switch” (con la “S” maiuscola) mentre lo sketch Arduino ha il nome “switch.ino” (con la “s” minuscola). L’IDE Arduino vuole lo sketch dentro una cartella con la stesso nome (case sensitive). E’ sufficiente quindi rinominare la cartella.
Probabilmente gianmarco.cervini creando un nuovo sketch ha indirettamente risolto il problema.
2) il repository da cui ho creato il file zip non era allineato con la cartella di lavoro e quindi, come ha fatto notare sempre gianmarco.cervini, anziché usare il metodo “sendHttp”, sullo sketch bisogna usare il metodo “sendResponseHttp” (su due righe).
Il problema delle librerie WiFi comunque potrebbe presentarsi; in questo caso è sufficiente cancellare o spostare la cartella.
A breve verrà aggiornato il file zip con il codice.
Scusate il disguido, spero non abbia creato troppi disagi.
File aggiornato.