Un power monitor per l'impianto fotovoltaico con Arduino

by maurizio
23 minuti
Un power monitor per l'impianto fotovoltaico con Arduino

Qualche settimana fa ho pubblicato un post riguardante il monitoraggio della produzione del mio impianto fotovoltaico e del consumo della mia casa, realizzato con uno Shelly EM.

Recentemente ho deciso di aggiungere un piccolo dispositivo per rendere visibile a colpo d'occhio i parametri "vitali" relativi a produzione e consumo di energia elettrica. L'idea è quella di avere su un display una visualizzazione costante della situazione che ci permetta di ottimizzare i consumi.

Non avendo trovato un dispositivo di questo tipo, ho deciso di progettarlo e costruirlo utilizzando una scheda NodeMCU ESP8266.

Il progetto

Come visto nel post precedentemente citato, Shelly EM è un dispositivo IOT che si connette alla WiFi di casa e consente, tra le altre cose, di misurare la potenza istantanea rilevata da ben due pinze amperometriche. I dati rilevati vengono comunicati al cloud di Shelly dal quale possono essere visualizzati grazie ad una apposita App, ma questi dispositivi mettono anche a disposizione una interfaccia API locale che possiamo interrogare direttamente. Pertanto ho pensato di implementare il progetto usando una scheda Arduino compatibile con processore ESP8266, quindi già dotata di interfaccia WiFi, che interroga periodicamente va rete lo Shelly EM per rilevare le potenze misurate sul fotovoltaico e al contatore, rappresentandole su un piccolo schermo LCD.

In questo modo non mi devo preoccupare di implementare la lettura delle pinze amperometriche su Arduino, e inoltre non avrò bisogno di posizionare il monitor vicino all'inverter e al contatore, anzi grazie al WiFi potrò spostarlo in qualsiasi stanza della casa.

Le API di Shelly EM

Prima di andare avanti ritengo sia opportuno esaminare, pur senza entrare nei dettagli, le API di Shelly EM. 

Va detto innanzitutto che tutti i dispositivi Shelly sono dotati di API Rest consumabili liberamente (anche se è possibile proteggerle con password se lo si ritiene necessario). Queste API sono implementate direttamente sui dispositivi e funzionano indipendentemente dal fatto che il dispositivo sia connesso al cloud Shelly oppure no. La documentazione completa delle API Shelly è disponibile sul sito di Shelly. 

Ogni dispositivo Shelly è dotato di un web server a bordo che offre un'interfaccia utilizzabile da browser per poterlo consultare o cambiarne lo stato (se ha un interruttore). Per poterlo fare basta utilizzare il browser indicando l'indirizzo IP del dispositivo. Ad esempio nel caso de mio Shelly EM: http://192.168.10.50.

L'indirizzo IP di ogni dispositivo si trova facilmente grazie all'App shelly, ma se si è configurato in DHCP è possibile che questo indirizzo cambi ogni volta che si resetta o si fa ripartire lo Shelly EM, pertanto vi consiglio vivamente di impostarlo su un indirizzo statico, in modo che ogni volta che riparte riprenda il medesimo indirizzo. Per impostarlo su un indirizzo statico dovrete osservare le regole che valgono sempre in questi casi:

  • Scegliere un indirizzo nella stessa subnet del resto della nostra rete (ad esempio se la rete è 192.168.1.0/255.255.255.0 potremo scegliere un indirizzo tra 192.168.1.1 e 192.168.1.254, 
  • verifichiamo prima che l'indirizzo NON sia già occupato, ricordiamo che su una LAN non possono e non devono esserci due device con lo stesso indirizzo IP,
  • verifichiamo che l'indirizzo NON sia compreso nel range del DHCP . Ad esempio se il dhcp fornisce gli indirizzi da 32 a 96, occorre scegliere un indirizzo fuori da quel range, ad esempio 192.168.1.25 oppure 192.168.1.98, e ovviamente occorre prima verificare che tale indirizzo non sia già occupato.

E' buona pratica mantenere un documento nel quale annotarsi tutti gli indirizzi della propria rete in modo da orientarsi rapidamente in caso di bisogno.

Supponiamo che il nostro Shelly EM abbia indirizzo IP 192.168.10.50, potremo facilmente richiamare l'API che ci fornisce il suo stato andando con il browser all'indirizzo: http://192.168.10.50/status . Ad esempio:

A questa chiamata, Shelly EM risponde con una lunga riga di testo, a prima vista poco chiara, ma in realtà molto ben interpretabile, soprattutto da un software, perché è nel formato JSON. Il formato JSON permette di strutturare degli oggetti (raccolti tra parentesi graffe) definendo delle coppie chiave/valore. 

Se vogliamo vedere con una formattazione più facilmente leggibile il contenuto della risposta, possiamo aprire la vista sugli strumenti per sviluppatori del browser (su Google Chrome lo si fa premendo il tasto F12), e posizionandoci sulla vista "Network" (o "Rete" in Italiano), e poi evidenziando il file "status" che abbiamo appena richiesto. Ad esempio:

Ad esempio se andiamo a leggere nell'immagine sopra troviamo alcuni dati facilmente interpretabili, come ad esempio: "power":3341.44 e "power":-503.96. Questi due valori corrispondono alla misura istantanea della potenza delle due sonde amperometriche del mio Shelly EM, la prima collegata all'uscita dell'impianto fotovoltaico, che quindi in questo momento sta erogando 3341.44 Watt di potenza, e la seconda al contatore che sta cedendo alla rete (segno meno) 503.96 watt. Se vi state chiedendo dove stia andando il resto dell'energia per un totale di 3341.44-503.96=2837.48 Watt, sappiate che oltre al mio PC, in casa mia sono accesi lavatrice, lavastoviglie, frigorifero e 2 televisori.

Quindi Shelly ci mette a disposizione uno strumento potentissimo per poter realizzare delle integrazioni prelevando i dati direttamente dal dispositivo di misura. In realtà con le API di shelly si può fare molto di più, ma andremmo fuori dallo scopo di questo articolo quindi per adesso mi limito a invitarvi a visitare la documentazione ufficiale delle API Shelly.

Arduino si, ma quale?

Arduino non dovrebbe aver bisogno di presentazioni: si tratta di una piattaforma hardware open source sulla quale sono stati sviluppati tantissimi prodotti, in larga parte compatibili tra loro, dedicati alla prototipazione rapida o all'implementazione "fai da te" di sistemi di automazione industriale, domotica e IoT.

Quindi quando si diciamo "Arduino" solitamente non si fa riferimento alla specifica scheda elettronica, quanto più estesamente a tutta la piattaforma che include tante schede diverse, progettate e fabbricate da produttori diversi, ma che seguono tutte la stessa filosofia di apertura e condivisione degli standard nati con il progetto Arduino. Ed è propria questa filosofia aperta, in pratica l'equivalente dell'open source del software applicato all'hardware, che ha determinato il grande successo e lo sviluppo esponenziale di questa piattaforma.

Purtroppo, come si dice in questi casi, nessuna rosa è senza spine, quindi se da una parte la piattaforma Arduino ci ha portato una serie di strumenti molto semplici da usare e a costi bassissimi per realizzare le nostre applicazioni, dall'altra troviamo sul mercato tantissime schede, tutte simili tra loro ma non completamente uguali, e quando si va a programmarle occorre capire bene quali pezzi andiamo ad unire insieme per essere sicuri di utilizzare le librerie corrette per farli funzionare. Vedremo più avanti qualche esempio pratico di questa situazione.

In ogni caso la realizzazione del mio progetto del PowerMeter, prevede l'utilizzo di una scheda Arduino compatibile che possa accedere alla rete WiFi, in modo da poter richiamare le API dello Shelly da cui prendere le informazioni. 

Inizialmente avevo pensato di utilizzare una scheda D1 ESP8266 collegata ad un display LCD 16x2 (due righe da 16 caratteri) ed ho anche realizzato un prototipo di cui potete vedere una fotografia qui sotto.

Il progetto funzionava bene ma il display LCD non è molto visibile con la retroilluminazione spenta e non sono sicuro che tenerla accesa sempre sia una buona idea. Inoltre la scheda D1 è piuttosto grande e sarebbe stato difficile trovare un contenitore adatto per il progetto da poter tenere appoggiato sul mobiletto dove ho pensato di collocare il power monitor.

Quindi, dopo aver fatto qualche valutazione relativa ai prezzi e alla rapida reperibilità dei componenti, ho optato per una NodeMCU ESP8266 di AZ-Delivery, accompagnata da uno schermo OLED. Di schermi OLED se ne trovano di diverse dimensioni, per non sbagliare ne ho presi sia uno da 0,96 pollici che uno da 1,3 pollici, entrambi collegabili alla scheda Esp8266 tramite interfaccia I2C.

L'interfaccia I2C è in pratica un BUS seriale che utilizza solo 2 conduttori per la comunicazione (più i due fili dell'alimentazione), e quindi è piuttosto semplice da collegare, e può essere utilizzato per pilotare anche più apparecchiature periferiche con una scheda Arduino. In questo caso l'unico dispositivo collegato sarà il display.

Per quanto riguarda invece l'alimentazione, questa sarà fornita da un da un vecchio alimentatore switching recuperato da  un apparecchio dismesso: per abitudine quando getto via (nel RAE) qualche apparecchio elettronico, cerco di tenere l'alimentatore perché so che prima o poi può tornare utile. L'alimentatore che ho usato eroga 9v in corrente continua. Per fortuna la ESP8266 ha l'ingresso Vin dove può accettare da 5 fino a 20 volts CC.

Lo schema finale è semplicissimo ed è rappresentato nella seguente immagine:

Programmare la NodeMCU ESP8266

Il punto di forza delle schede Arduino, e quindi anche della Esp8266, è la loro programmabilità, e in questo caso le cose che dobbiamo far fare alla scheda sono molte e caratterizzate da una certa complessità.

Le schede Arduino si programmano attraverso il loro linguaggio, che si ispira fortemente al C++ anche se presenta alcune peculiarità proprie. Notoriamente programmare in C++ non è semplice ma Arduino offre una IDE, ossia un ambiente di sviluppo integrato, che oltre a dare un interfaccia grafica consistente e multi piattaforma (c'è per Windows, Mac e Linux ed è sostanzialmente identica) semplifica moltissimo anche l'integrazione dei vari componenti aggiuntivi di Arduino (come il Display del nostro esempio) grazie al gestore di librerie integrato.

Non è certo questo lo spazio giusto per introdurre alla programmazione di Arduino, voglio però dare alcuni consigli generali utili a chi si avvicina alla programmazione di queste schede. 

In primo luogo, come ho già scritto in precedenza, le varie schede basate sulla piattaforma Arduino e Arduino-compatibili, sono tra loro simili ma non identiche. Ciò significa che per ogni scheda di marca/modello diverso che andiamo ad acquistare dobbiamo verificare le istruzioni specifiche del produttore per impostare correttamente la IDE, altrimenti questa non riuscirà a "parlare" con la scheda.

Ad esempio io ho preso la scheda NodeMCU ESP8266 di AZ-delivery, insieme alla quale viene distribuito un PDF (da scaricare dal sito di AZ-Delivery) che contiene le istruzioni su come impostare la IDE per scaricare i driver che consentono di dialogare con la scheda. Se non si seguono correttamente le istruzioni del produttore non si sarà in grado di caricare il programma compilato.

Come ogni scheda ha i suoi driver, anche ogni componente aggiuntivo necessita delle proprie librerie per poter essere pilotato. Ad esempio io ho acquistato due display OLED, uno da 0.96 pollici e uno da 1.3 pollici, entrambi con interfaccia I2C identici tra loro in tutto tranne che nelle dimensioni. In realtà questi sono solo apparentemente identici,  in quanto l'elettronica che pilota i due schermi è diversa e quindi la libreria che pilota lo schermo da 0.96" non vede quello da 1.3" e viceversa.

A titolo di esempio qui sotto riporto due snippet di codice, che rappresentano la stessa funzione di scrittura di una stringa di testo sul display oled, a sinistra nella versione per lo schermo da 0.96" e a destra quella per lo schermo da 1.3".

Come si può vedere i due metodi sono molto diversi tra loro perché le librerie che si utilizzano per pilotarli non sono le stesse.

Ne segue che se vogliamo ridurre i tempi di sviluppo occorre effettuare un'accurata selezione iniziale dell'hardware e poi evitare di cambiarlo in corso - in pratica tutto il contrario di quello che ho fatto io cambiando sia la scheda di base (da D1 a NodeMCU ESP8266) sia display inizialmente LCD, poi Oled da 0.96" e infine oled da 1.3". Ognuno di questi cambiamenti ha portato infatti la necessità di riscrivere buona parte del software che pilota il progetto.

Detto tra noi io mi considero un vero neofita di Arduino e quindi ho imparato molto e mi sono divertito nel farlo, ma se si ha la necessità di giungere rapidamente ad un risultato, questa non è certo la strada corretta!

Il programma del Power Monitor

Il programma del power monitor non è particolarmente complesso ma deve effettuare una serie di compiti e in particolare:

  • Attivare la scheda WiFi onboard e collegarla alla WiFi locale
  • Interrogare via rete lo Shelly EM attraverso l'interfaccia API di cui abbiamo parlato prima
  • Estrarre i dati dal JSON che arriva dalle API di Shelly EM
  • Visualizzare sul display  dati ricevuti, se possibile anche in formato grafico
  • Gestire un allarme di carico eccessivo
  • Gestire eventuali errori di comunicazione

I sorgenti degli sketch che ho realizzato, sia per la versione con schermo LCD che quelle per gli schermi da 0.96 e 1.3 pollici, sono disponibili su GitHub.

Con l'hardware giusto e includendo le librerie utilizzate (che si possono desumere dai vari include) basta modificare la configurazione iniziale per poter compilare il software, caricarlo sulla scheda e ottenere un power monitor funzionante.

Ovviamente occorre scegliere lo sketch corretto per la propria configurazione. Ad esempio lo sketch PowerMonitorOLED-13 è pronto per la scheda AZ-Delivery NodeMCU ESP8266 più display OLED 1.3 pollici. Come ho già detto, per poter caricare lo sketch occorre prima configurare la IDE di Arduino in modo che carichi i drivers specifici della scheda. Per farlo occorre seguire le istruzioni specifiche del produttore della scheda, che di solito consistono nel copiare una URL nella scheda delle impostazioni dela IDE Arduino, come ad esempio:

Dopo aver impostato questa URL di solito è necessario impostare il tipo di scheda utilizzata dal menu Strumenti -> Scheda. Questa operazione è il modo standard di operare della IDE di Arduino: ogni volta che si vuole caricare un programma su una scheda diversa è necessario aggiungere i drivers specifici di quella scheda nelle impostazioni e poi selezionare la scheda, altrimenti quando si va a compilare e caricare il programma compilato sulla scheda l'operazione non va a buon fine.

Una volta assicuratisi che la IDE può caricare programmi sulla scheda (ad esempio caricando il programma vuoto di base), è consigliabile installare le librerie necessarie a pilotare lo schermo e interpretare i JSON. Quindi occorre andare sul menu Strumenti -> Gestione librerie e installare le seguenti:

  • Arduino_JSON
  • U8g2
  • U8g2_for_Adafruit_GFX

Una volta installate le librerie è possibile caricare lo sketch (anche semplicemente copiandolo da GitHub e incollandolo nell'IDE a sostituzione del programma di default), e configurare tre parametri contenuti nelle prime righe del programma:

ifndef STASSID
#define STASSID "---SSIDNAME---"
#define STAPSK  "---SSIDPWD---"
#endif

// Shelly EM API URL
const char* shellyapiurl = "http://192.168.10.50/status";


Al posto di ---SSIDNAME--- e ---SSIDPWD--- vanno messi l'SSID e la password della rete WiFi alla quale dovrà collegarsi il power monitor e l'indirizzo "192.168.10.50" andrà invece sostituito con l'IP del proprio Shelly EM.

Se tutto va bene si può compilare e caricare il programma sulla scheda e attivare il power monitor.

Come funziona il Power Monitor

Come già detto il power monitor ogni 10 secondi chiama le API dello Shelly EM, rileva i valori dei due sensori e li mostra sul display OLED. Nella mia configurazione dello Shelly EM, la prima pinza amperometrica è collegata al fotovoltaico e la seconda al contatore elettrico della casa. Ho pensato quindi di dividere il display in due parti, quella superiore dove viene mostrata la produzione dell'impianto fotovoltaico, e quella inferiore dove viene mostrato la potenza elettrica utilizzata oppure ceduta rete elettrica, in caso di sovrapproduzione del fotovoltaico rispetto al consumo della casa. Questi due valori sono rappresentati oltre che numericamente su sue barre simili ad istogrammi.

In particolare la barra che rappresenta il contatore si "riempie" da sinistra verso destra quando l'impianto sta utilizzando energia dalla rete e da destra verso sinistra quando invece cediamo energia generata dal fotovoltaico alla rete.

Ad esempio nell'immagine qui sotto l'impianto fotovoltaico sta producendo 694.97 Watt di cui una parte vengono assorbiti dagli elettrodomestici e i carichi attivi della casa ma non tutti, infatti 234,7 Watt vengono ceduti alla rete elettrica.

Per poter disegnare le barre abbiamo bisogno di un dato importante: quali sono i valori massimi che queste possono assumere. Nel mio caso la barra che rappresenta la produzione del fotovoltaico dovrà rappresentare valori da 0 a 5100 Watt in quanto l'impianto è da 5,1 kW di picco. Invece il contatore ha un massimo di 4500 Watt perché il mio contratto col fornitore di energia prevede un impegno massimo di 4,5 kW.

Anche in questo caso questi valori sono configurati all'inizio dello sketch e sono facilmente modificabili nel caso ce ne sia bisogno:

#define MAXPWP  4500 // Max power contatore 4.5kW
#define MAXFVP  5100 // Max power fotovoltaico 5.1kW

Vestiamo il power monitor

A questo punto il mio power monitor è praticamente completo, almeno a livello funzionale, ma è un po' scomodo da usare perché in pratica si tratta solo di due schedine elettroniche tenute insieme da quattro fili e assomiglia più ad un qualche esperimento da scienziato pazzo che ad un apparecchio elettronico dotato di una certa utilità.

Occorre quindi trovare un contenitore dove poterlo montare in modo da poterlo collocare in una stanza senza provocare l'ira funesta della consorte.

Per fortuna ho un amico molto disponibile dotato di una stampante 3d (grazie Gae!), quindi mi sono messo a cercare il file STL di un case che potesse fare al caso mio. Dopo un bel po' di ricerche, ho finalmente trovato un contenitore modulare adatto ad ospitare una ESP8266 e un display OLED dall'aspetto molto simpatico, che abbiamo subito ribattezzato, chissà perché, il suppostone

Purtroppo finito il processo di stampa e ricevuti i vari pezzi, mi sono accorto che le misure non si adattavano perfettamente ai componenti da alloggiare nel case. Anche in questo caso ho pagato il mio noviziato in questi argomenti. Quello di cui non ho tenuto conto è che, se pure il file STL fosse disegnato per produrre un case a misura per le due schede, NodeMCU ESP8266 e Display OLED da 1.3 pollici, purtroppo quelle prese in considerazione dal produttore del file sono probabilmente di una marca diversa dalle mie e quindi le misure non tornano alla perfezione.

Ho imparato quindi che quando si stampa un case in 3d è sempre bene verificare le misure delle schede che poi si andranno ad alloggiare in modo da operare in necessari cambiamenti al file STL prima di stamparlo, altrimenti poi è necessario lavorare di lima e fantasia.

Nel caso specifico ho infatti dovuto riadattare il case per fare in modo che lo schermo entrasse nell'alloggiamento che evidentemente era stato progettato per una scheda di qualche millimetro più piccola, e poi ho dovuto usare dell'adesivo per fare in modo che lo schermo rimanesse al suo posto.

Il risultato finale comunque è di livello accettabile e il power monitor adesso fa bella mostra di se su un mobiletto della nostra cucina, dove ha già dato prova più e più volte della sua utilità.

Infatti accade spesso che prima di avviare una lavatrice o mettere in carica l'auto elettrica si "butti un'occhio al suppostone" per vedere quanta energia stiamo producendo e consumando: avere una semplice indicazione grafica della produzione e del carico istantanei è utilissimo per educare al miglior uso dell'energia tutti i componenti della famiglia, anche i più "low-tech" ! :-)

CrazyHorse80
Problemino con JSON...
Written by CrazyHorse80 on Novembre 14, 2022

Ciao, potresti indicarmi esattamente quale versione della libreria ArduinoJSON scaricare? Io ho installato l'ultima 6.19.4 ma ho un problema su questa riga di codice del software PowerMonitorOLED-13: 90 JSONVar data = JSON.parse(js);

Errore: error: 'JSONVar' was not declared in this scope JSONVar data = JSON.parse(js); ^~~

E poi a seguire, ovviamente, su tutti i richiami a JSON... Puoi aiutarmi? Grazie in anticipo!

maurizio Admin
Written by maurizio on Novembre 30, 2022

Io ho installata la Arduino_JSON v 0.1.0 BETA.

Banalità: ti sei ricordato di includerla nello sketch?

GB
D1 Mini
Written by GB on Febbraio 23, 2023

Ciao, mi ritrovo una scheda D1 mini utilizzata per un altro progetto, potrebbe fare al caso? La descrizione completa sul sito dove l'ho acquistata: ESP8266 ESP-12 ESP-12F CH340G CH340 V2 USB D1 Mini PRO V3.0.0 S2 MINI scheda WIFI NodeMCU Lua IOT Board 3.3V con pin

Andrebbe bene con questo display?: AZDelivery 1.3 pollici Display OLED I2C SSH1106 Chip 128 x 64 Pixel

Grazie :-)

maurizio Admin
Written by maurizio on Febbraio 23, 2023

Si, penso di si. E' una esp8266 quindi ha il wifi. DIrei che potrebbe andare bene.

GB
Visualizzazione produzione totale giornaliera
Written by GB on Febbraio 27, 2023

Grazie, funziona perfettamente 👍 Vorrei visualizzare anche la produzione totale inserendo questa stringa: String p0=JSON.stringify(data["emeters"][0]["total"]); // FV quale altra riga devo inserire per visualizzarla correttamente? Ancora grazie per la tua disponibilità :-)

maurizio Admin
Written by maurizio on Febbraio 28, 2023

Credo che il primo problema sia trovare il posto dove visualizzarla, visto che lo schermo è molto piccolo. Al limite puoi pensare di visualizzarla alternandola con la produzione o il consumo istantanei, tipo per 10 secondi visualizzi il consume e poi per altri 10 secondi visulizzi la produzione totale. Per farlo puoi ad esempio creare una versione alternativa della drawScreen() da richiamare alternativamente alla drawScreen() attuale. Non si tratta di inserire una riga o due di codice, ma occorre apportare qualche modifica alla logica di funzionamento. Se mi viene voglia in futuro lo faccio e pubblico l'aggiornamento (ma non prometto niente che in questo periodo il lavoro mi sta assorbendo tutto il tempo!)

GB
Visualizzazione produzione totale giornaliera
Written by GB on Febbraio 28, 2023

Maurizio l'idea sarebbe di sostituire la prima riga "--I POWER MONITOR I--" con una riga con la produzione totale giornaliera "fv tot: xxx" senza l'indicazione a barre ;-) Se e quando avrai del tempo sarà gradita la modifica, nel frattempo incomincio a studiare, magari ci riesco da solo e nel caso condividerò 🤗