ESP32lights

luca 08/01/2018 20

Il progetto che vi presento oggi, ESP32lights, è una centralina di controllo luci smart, basata sul chip esp32.

esp32lights-004 esp32lights-005

Tramite ESP32lights è possibile accendere/spegnere un carico (io lo utilizzo per le luci natalizie…)

  • manualmente
  • secondo una schedulazione oraria
  • in base alla luminosità

ESP32lights si collega alla rete wifi di casa, è gestito interamente via browser ed è ottimizzato per dispositivi mobile (interfaccia responsive basata su jQuery Mobile).

Componenti

Cuore della centralina ESP32lights è la scheda di sviluppo Lolin32 Lite di Wemos. Uno dei pin digitali della scheda è collegato ad un modulo relay, il quale controlla il carico. Due pin digitali, assegnati al primo controller i2c del chip esp32, sono invece connessi al sensore luminosità BH1750. L’alimentazione a tutti i dispositivi della centralina è infine fornita dal modulo HLK-PM01 di Hi-Link che converte i 220V AC della rete in 5V DC senza necessità di componenti esterni:

esp32l-001

Tutti i componenti sono inseriti in un contenitore a tenuta stagna, in modo da poter collocare la centralina anche all’esterno:

esp32lights-006 esp32lights-007

Programmazione

Il programma in esecuzione sulla devboard esp32 è disponibile nel mio repository Github.

In uno dei successivi paragrafi vi illustrerò il suo funzionamento. Se volete semplicemente realizzare la vostra centralina, potete effettuare la programmazione del firmware come segue:

1) effettuare il clone del mio repository in una cartella locale del vostro PC (dovete avere installato l’ambiente di sviluppo esp-idf):

2) configurare i parametri della vostra rete wifi e del fuso orario tramite menuconfig:

esp32lights-003

3) compilare e programmare il firmware:

make flash

4) memorizzare nella flash la partizione SPIFFS (utilizzate la vostra porta COM e il path dove avete salvato il file img):

python $IDF_PATH/components/esptool_py/esptool/esptool.py --chip esp32 --port COM15
 --baud 115200 write_flash --flash_size detect 0x180000 /home/esp32lights.img

Se tutto è stato eseguito correttamente, collegandosi in seriale (make monitor) alla scheda di sviluppo dovrebbe apparire il seguente output:

esp32lights-025

Utilizzo

ESP32light mette a disposizione una interfaccia HTTP attraverso la quale è possibile inserire la programmazione (oraria o basata su una soglia di intensità luminosa) o controllare manualmente l’accensione e lo spegnimento del carico collegato alla centralina.

E’ possibile visualizzare l’interfaccia collegandosi (da PC o smartphone) all’indirizzo http://<esp_ip> (l’indirizzo IP della scheda è visibile dall’output seriale come mostrato nel paragrafo precedente).

L’interfaccia è divisa in 3 tab, uno per ogni modalità di funzionamento:

esp32lights-001

La barra di stato visualizza la modalità di funzionamento attuale:

esp32lights-002

Nel breve video che segue, potete vedere l’utilizzo della centralina (sottotitoli in italiano disponibili):

Software

Il firmware di ESP32lights è stato realizzato sfruttando quando appreso nei miei precedenti tutorial. Se infatti seguite il mio blog, avrete sicuramente capito che prediligo il metodo divide et impera, ovvero suddividere un progetto complesso in task più semplici.

Tutti i parametri di configurazione di ESP32lights (modalità di funzionamento, programmazione oraria…) sono memorizzati nella partizione NVS come vi ho spiegato in questo tutorial; in questo modo è possibile conservarli anche in caso di riavvio del chip esp32:

nvs_handle my_handle;
int working_mode;
[...]
esp_err_t err = nvs_flash_init();
err = nvs_open("storage", NVS_READWRITE, &my_handle);
err = nvs_get_i32(my_handle, "mode", &working_mode);

I diversi elementi della interfaccia web (pagine html, fogli di stile css…) sono memorizzati all’interno di una partizione SPIFFS. In un precedente tutorial vi ho mostrato come preparare l’immagine ed accedere al suo contenuto:

esp32l-002

Anche il collegamento ad una rete wifi e l’utilizzo dei pin digitali del chip esp32 per il controllo del relay sono stati oggetto di tutorial dedicati.

La fase di setup iniziale si conclude con la configurazione del sensore di luminosità BH1750. Tale sensore offre una interfaccia i2c e può essere quindi collegato ad uno dei due controller i2c del chip come spiegato in questo tutorial. Nel mio programma ho utilizzato un driver preparato da pcbreflux.

Il programma principale è composto da tue task distinti:

xTaskCreate(&http_server, "http_server", 20000, NULL, 5, NULL);
xTaskCreate(&monitoring_task, "monitoring_task", 2048, NULL, 5, NULL);

esp32l-003

Il primo pubblica l’interfaccia web, mentre il secondo si occupa di verificare – ogni secondo – se esistono le condizioni (orario o intensità luminosa) per accendere o spegnere il carico:

if(working_mode == MODE_LIGHT && lux_valid) {
  int actual_light_value = get_light_value();
  if(actual_light_value < lux) {
    if(relay_status == false) {
      gpio_set_level(CONFIG_RELAY_PIN, 1);
      relay_status = true;
    }

Ecco nel dettaglio come funziona il server http quando viene richiesta una risorsa statica, memorizzata nella partizione SPIFFS.

Per prima cosa al path della risorsa deve essere aggiunta la root della partizione SPIFFS (/spiffs):

sprintf(full_path, "/spiffs%s", resource);

quindi il programma verifica se la risorsa esiste nella partizione:

if (stat(full_path, &st) == 0) {

in caso affermativo, apre il file in lettura:

FILE* f = fopen(full_path, "r");

e ne invia il contenuto al client, leggendo blocchi di 500 bytes:

char buffer[500];
while(fgets(buffer, 500, f)) {
  netconn_write(conn, buffer, strlen(buffer), NETCONN_NOCOPY);
}

Vediamo infine il funzionamento dell’interfaccia web. Questa è composta da una pagina html (index.html) che utilizza jQuery per effettuare chiamate AJAX al server e aggiornare l’interfaccia responsive (basata su jQuery Mobile). Non è necessario inserire il nome della pagina nel browser perché il server http effettua una redirect automatica se viene richiesta la pagina di default:

if(strstr(request_line, "GET / "))
  spiffs_serve("/index.html", conn);

Gli endpoints pubblicati dal server e invocati dalla pagina con chiamate AJAX sono 3:

  • setConfig, per inviare una nuova configurazione
  • getConfig, per leggere la configurazione attuale
  • getLight, per leggere il valore attuale di luminosità

Al primo caricamento della pagina, questa chiama la getConfig per visualizzare la configurazione attuale; inoltre schedula ogni cinque secondi la chiamata a getLight per tenere aggiornato il valore visualizzato:

refreshConfig();
setInterval("refreshLightLevel()", 5000);

Alla pressione del pulsante SET, viene invece invocata la setConfig per inviare al server la nuova configurazione:

esp32l-004

Lo scambio di informazioni avviene utilizzando il formato JSON. Il framework esp-idf include la libreria cJSON che semplifica sia il parsing che la costruzione di un nuovo messaggio json:

cJSON *root = cJSON_Parse(body);
cJSON *mode_item = cJSON_GetObjectItemCaseSensitive(root, "mode");
[...]
cJSON *root = cJSON_CreateObject();
cJSON_AddNumberToObject(root, "lux", light_value);
char *rendered = cJSON_Print(root);

Making of

Ho iniziato la costruzione della centralina tagliando un pezzo di breadboard delle dimensioni del contenitore:

esp32lights-008 esp32lights-009

La breadboard è collegata al contenitore tramite due distanziali e due fori:

esp32lights-010 esp32lights-011

Ho praticato due fori in un lato del contenitore per ospitare l’interruttore principale e un led di stato:

esp32lights-012 esp32lights-013

Ho saldato i vari componenti sulla breadboard e realizzato – tramite filo – i vari collegamenti:

esp32lights-014 esp32lights-015

Per rendere più facile l’installazione, tutti i componenti esterni (led, modulo relay…) sono collegati tramite jumpers:

esp32lights-016 esp32lights-017

Primo test di funzionamento:

esp32lights-018

Ho fissato il sensore di luminosità al coperchio del contenitore, dopo aver praticato un foro per consentirgli di “vedere” la luce esterna:

esp32lights-019 esp32lights-020

Ho infine realizzato i collegamenti elettrici, installando un interruttore generale:

esp32lights-021 esp32lights-022

e collegando l’uscita del modulo relay ad cavo che termina con una presa universale:

esp32lights-023 esp32lights-024

20 Comments »

  1. Georgian 08/01/2018 at 20:51 - Reply

    Hello, I see that you use a lot that AC/DC convertor. Are you satisfied with it. I just started using one for an ESP8266 project and so far no smoke and everything seems to work fine. Did you have any issues with them?
    Thank you.

    • luca 08/01/2018 at 21:32 - Reply

      Hi, so far the AC/DC modules I used in my projects worked great! No issues at all!

      • Georgian 09/01/2018 at 21:08 - Reply

        Thank you, I hope that mine will do just fine too. Great work.

  2. tom 09/01/2018 at 08:19 - Reply

    hi, Luca, i am in China and we want develop a device using ESP32 as the WIFI module. we have a device needs to be controlled remotelly with mobile phone. do you know any company or ppl who is good at this ESP32 based development?

    Thanks.

    • luca 09/01/2018 at 09:28 - Reply

      Hi Tom, try asking on esp32.com, it’s the “official” forum and there are freelancers who regularly write on it

  3. tom 09/01/2018 at 16:03 - Reply

    thanks, i will go for it.

  4. Daren 12/01/2018 at 08:49 - Reply

    Economics of scale kicking in. A 1A USB charger is much cheaper than the Hi-Link module, and is about the same size.
    The build quality is questionable and you have to pot them yourself then of course, but I have had good luck with them in similar applications.

    If you really wanted to get cheap since your design can be entirely isolated: Switch your relay out for a logic level triac and you can then drive this directly from mains with just two capacitors, a switching diode, and a zener. This comes with the warning that one leg of the ESP32 will be at mains level then so no human contact allowed once in circuit, and triac failure will likely fry the ESP32.

    • luca 12/01/2018 at 09:43 - Reply

      Hi Daren, thanks for your suggestions! To be honest I had some Hi-Link modules laying around and I this was a good project to test them.

  5. Lachlan 14/01/2018 at 12:15 - Reply

    Hi Luca, great project, is there anywhere that describes how the data in the webapp is accessed by the esp32 ?
    js and web development is not my strongpoint by any stretch
    thanks ! keep up the good work

  6. Lachlan 14/01/2018 at 12:17 - Reply

    ah sorry, ignore my question i hadn’t got that far down the article :-)

  7. Ted 14/01/2018 at 18:06 - Reply

    Your Hi-Link is dead!

    • luca 15/01/2018 at 08:23 - Reply

      Thanks Ted, now fixed

  8. mauro 22/01/2018 at 17:41 - Reply

    Ciao Luca, chiaro come sempre: avrei una domanda sul relay.. I 5 v per la bobina sono presi dalla esp32 board ma il pin per azionare il relay è a 3.3 v (uscita della scheda) : non hai paura che bruci la scheda (oppure hai tolto il jumper vcc che si trova sul relay e alimentazione e controllo sono su 2 linee separate?)
    Per farla breve si può connettere in maniera così semplice un relay 5 v dc alla scheda esp32?
    Grazie in anticipo della risposta
    Mauro

    • luca 23/01/2018 at 09:57 - Reply

      Ciao Mauro! In effetti il relay è dichiarato a 5v (avevo solo quello) ma “scatta” anche se lo controlli a 3.3V… non c’è rischio di bruciare la scheda, al massimo se la tensione non è sufficiente il relay non si aziona.

  9. Herman 28/01/2018 at 17:41 - Reply

    Hi Luca,

    Great project, it is almost exactly what I was looking for.
    I had a timer for years that turns the lights on when it gets dark, and turns it off at given time so it won’t be on until the morning. Since I am not a programmer, I want to ask you if your program can be modified to do that. It would be of great help to me since the timer I used is EOL and there are no replacements for a usable price.

    Thanks.

    • luca 26/02/2018 at 14:53 - Reply

      Hi Herman, you should be able to modify the program… to keep it simple you could use one of the time fields already present in the GUI to set the “off” time instead of designing a dedicated GUI (more complex)

  10. Felice 12/03/2018 at 19:36 - Reply

    Ciao Luca, grazie per la condivisione del progetto.
    Ho un dubbio sui collegamenti elettrici.
    l’uscita massa e +5 volt del convertitore su quali pin della scheda lolin32 li collego?
    A me sembra che questa scheda si alimenti solo dalla presa usb.
    Tu come li hai collegati?
    Infine confermami per cortesia gli altri pin di collegamento che sono pin 0=comando relè, il 4=SCL il 16=SDA del sensore BH1750.
    Grazie mille in anticipo.
    Felice.

    • luca 16/03/2018 at 10:42 - Reply

      Ciao Felice, ho utilizzato il connettore batteria (vedi questa immagine). Il pin del relay lo configuri da menuconfig, mentre quelli del sensore sono i pin 18 e 19 (ma li puoi cambiare editando bh1750.c

  11. Massimo 29/03/2018 at 13:12 - Reply

    Ciao Luca, ieri ho inserito una richiesta, vorrei solo sapere se è stata ricevuta, grazie.
    Massimo

    • luca 29/03/2018 at 13:58 - Reply

      ciao massimo, no non ho ricevuto nulla… mi hai scritto tramite form?

Leave A Response »

Fare clic qui per annullare la risposta.

Questo sito usa i cookie per poterti offrire una migliore esperienza di navigazione maggiori informazioni

Questo sito utilizza i cookie per fonire la migliore esperienza di navigazione possibile. Continuando a utilizzare questo sito senza modificare le impostazioni dei cookie o clicchi su "Accetta" permetti al loro utilizzo.

Chiudi