Apr 022015
 

Oggi vedremo come usare Arduino per misurare il consumo di corrente in modo non invasivo. Ok, lo ammetto, non è un argomento particolarmente innovativo, c’è infatti in rete un progetto ben più completo, il famoso OpenEnergyMonitor, dove potete attingere ad un sacco di informazioni, ma è da molto tempo che ho comprato un sensore di corrente non invasivo e non ho ancora avuto l’opportunità di provarlo per cui approfitto di questa prova per scrivere un articolo anche perchè leggere tutta la documentazione dell’O.E.M, peraltro tutta in inglese, non è certo ciò che l’utente medio cerca di fare.

Il sensore

Il sensore in mio possesso è il SCT 013-030 che potete vedere nella figura qui vicino. E’ formato da una sorta di pinza apribile. Nel foro deve essere inserito il cavo dove transita la corrente che vogliamo misurare, dopodiché la pinza viene chiusa senza danneggiare il cavo stesso. Bisogna però fare alcune premesse importanti. Questo sensore è in grado di misurare unicamente correnti AC (alternate), infatti la variazione nel tempo della corrente in transito crea un campo elettromagnetico direttamente proporzionale alla corrente stessa, ed è questo che viene misurato dal sensore. Bisogna però chiarire cosa intendiamosct01330 per “cavo ove passa la corrente da misurare”. Se ad esempio voleste misurare la corrente assorbita dai dispositivi connessi ad una ciabatta, non potete semplicemente mettere la pinza attorno al cavo di alimentazione della ciabatta. Dentro quel cavo, infatti, ci saranno tre conduttori, uno di massa, una fase ed un neutro. Nella fase e neutro il passaggio della corrente avviene nelle due direzioni opposte per cui, dato che i campi magnetici che si generano dipendono anche dalla direzione in cui transita la corrente, si formeranno due campi elettromagnetici opposti che si annullano uno con l’altro. E’ per questo che la misura deve essere fatta solamente su uno dei due conduttori per cui, se proprio volete misurare l’assorbimento della ciabatta, siete costretti ad esporre uno dei due conduttori o creare una piccola prolunga a cui possiamo facilmente accedervi.

Questo sensore misura correnti da 0 a 30A generando un segnale da 0 a +1V. Si noti che si tratta di un’intera famiglia di sensori che vanno da 5 a 100A, questo è quello da 30. Già questi due dati ci permettono due considerazioni preliminari. In primo luogo 30A sono assolutamente esagerati per una normale abitazione con un normale contratto da 3kW dove con un carico puramente resistivo non riusciamo a superare i 15A. Io in realtà ho un contratto da 4.5KW/h per cui potrei arrivare sui 20A, ciò però non toglie che per l’utilizzo medio è un sensore sin troppo grande ed il risultato finale è una perdita di precisione sul range realmente misurato. Se non fosse chiaro facciamo un esempio chiarificatore. A 30A questo sensore genera una tensione di 1V per cui se ipoteticamente il nostro consumo massimo reale fosse di 15A il sensore a quel valore produrrà una tensione di circa 0.5V. Questo significa che tutta la fascia da 0.5 a 1V non sarà mai utilizzata per cui andiamo a sfruttare solamente il 50% della scala a disposizione con dimezzamento della precisione su quella realmente sfruttata.

La seconda considerazione riguarda l’output del sensore che è una tensione alternata da -1 a 1 V che istintivamente potremmo pensare di leggere con gli ingressi analogici di Arduino. Questi però possono leggere solamente tensioni fra 0 e 5V per cui occorre qualche aggiustamento. Faccio notare che prima avevo detto che il sensore risponde con una tensione da 0 a 1V corrispondenti alla scala da 0 a 30A, ora invece ho detto che il segnale del sensore oscilla da -1 a +1V, questo perchè la corrente cambia segno 50 volte al secondo, quindi il campo elettromagnetico generato inverte la sua direzione con la stessa frequenza e con conseguente inversione anche del segnale in uscita dal sensore. Nella realtà perciò abbiamo un segnale -1 / +1V corrispondenti alla scala -30 / +30A.

Trasformiamo la tensione.

Come dicevamo la tensione prodotta dal sensore non può essere letta direttamente da Arduino in quanto riporta anche valori negativi . Come facciamo a modificare questa tensione? Semplice aggiungiamo una tensione in serie per aumentarne il valore base e far rientrare le letture nel range che Arduino è in grado di leggere. Più precisamente usiamo un partitore di tensione fatto da due resistori uguali per cui a partire dalla tensione 5V di Arduino ne otteniamo una di 2.5V. In questo modo passiamo da -1 / +1 a 1.5 / 3.5V, valori che sono facilmente leggibili dagli ingressi analogici di Arduino.

schemapinzaamperometricaSulla sinistra troviamo il sensore di corrente che è rappresentato dal generatore V1 e dal resistore di carico (burden resistor) R1 che è di 62Ω ed è integrato nella pinza. Vediamo che un capo del sensore andrà collegato ad un ingresso analogico di Arduino mentre l’altro capo sarà collegato al partitore di tensione. V2 non è altro è che i 5V di Arduino. Potete inoltre vedere nella figura i due resistori identici (potete mettere valori anche sino a 10K senza problemi) che portano la tensione a 2.5V ed un piccolo condensatore da 10μF utile per attenuare piccole fluttuazioni residue della tensione in uscita. Tutto qui? Si tutto qui, con un sensore, due resistori ed un piccolo condensatore siete già in grado di creare il vostro piccolo lettore di corrente.

Accennavamo che il sensore da 30A per un normale contratto da 3kW è un po’ esagerato, vediamo ora che precisione possiamo raggiungere con questo sensore. Purtroppo il sensore in uscita fornisce solamente 1V di escursione per cui dei 1024 valori campionabili da Arduino possiamo sfruttarne solamente 204.8 (5:1=1024:x). Quindi se 30A sono divisibili in 204.8 parti, ognuna di essa rappresenta 0.146A che a 220V diventano quasi 32.2W, ossia questo sensore, su Arduino UNO, utilizzato come spiegato sopra è in grado di misurare assorbimenti a passi di circa 32W.

Teoria e calcoli….

In questa fase dell’articolo ero molto indeciso se parlare o meno di teoria, calcoli, soluzioni, etc, etc. La risposta questa volta è stata no, almeno non in modo approfondito. No perchè sul sito di OpenEnergyMonitor c’è spiegato già tutto e in modo molto approfondito, non ha nessun senso fare una semplice traduzione del lavoro altrui. Ci sono però alcuni semplici concetti da conoscere, giusto per poter poi capire che il risultato voluto non è magari ciò che ci aspettavamo. Ci tengo a sottolineare che questo è un articolo base che vuole affrontare in maniera semplice l’argomento per cui per forza di cose sarò un po’ superficiale.

La cosa principale che dovremmo sapere è che per una misura accurata della potenza occorre la misura non solo della corrente assorbita, che facciamo con il sensore descritto, ma anche del voltaggio che c’è nel medesimo istante in cui campioniamo l’assorbimento di corrente. Per essere ancora più pignoli, dovremmo effettuare numerosi campionamenti lungo almeno un’intero periodo (lunghezza dell’onda formata dalla semionda positiva e negativa) ed effettuare una media quadratica dei valori ottenuti. Vi faccio notare che a 50Hz il periodo dura 0,02 secondi, per cui dovrebbe già iniziare a chiarirsi il fatto che in quel brevissimo tempo dobbiamo fare tutta una serie di campionamenti e calcoli che il nostro buon Arduino potrebbe fare un po’ di fatica a seguire. In realtà Arduino, da un punto di vista strettamente teorico, ha un convertitore analogico-digitale (ADC) in grado di campionare a 9,6kHz, ossia in un solo secondo riesce ad eseguire 9600 misurazioni, ognuna delle quali dura 104μs. Nella realtà oltre all’acquisizione vera e propria del segnale dobbiamo anche occuparci di fare dei calcoli con i dati ottenuti per cui la velocità reale si abbassa. OpenEnergyMonitor dichiara ad esempio di effettuare circa 100 campionamenti se viene misurata solo la corrente o 50 se viene misurata sia la corrente che la tensione.

Ma torniamo al nostro progetto. Abbiamo detto che in questa prima esperienza vogliamo fare le cose nel modo più semplice e chiaro possibile per cui la tensione la diamo per fissa a 220V. E’ giusto però precisare ancora una cosa. Abbiamo prima detto che la potenza per un carico resistivo è data dal prodotto di corrente x tensione.  Purtroppo però i carichi di un’abitazione non sono tutti al 100% resistivi, ci sono anche componenti capacitive ed induttive che portano ad uno sfasamento temporale fra il picco di tensione e di corrente che porta ad una modifica della potenza.  In questo caso la misura della tensione ci permetterebbe di capire quando c’è il picco di tensione e quello di corrente e calcolare lo sfasamento delle due con una migliorata precisione della misura, motivo per cui il mancato calcolo della tensione porta ad un doppio errore di misurazione, sia sul valore vero e proprio, sia sullo sfasamento rispetto la corrente.

Cominciamo.

Come potete immaginare ho deciso di crearmi un sistema rudimentale ma funzionante e semplice da calibrare per chiunque, scritto da noi e sul quale abbiamo il totale controllo, credo che questa sia l’unica vera strada per capire davvero quello che stiamo facendo. Per prima cosa mi sono costruito una piccola prolunga con i 3 fili separati in modo da poter applicare la mia pinza amperometrica su uno dei cavi come potete vedere nella figura. Poi mi sono procurato un portalampada per poterci mettere delle lampadine ad incandescenza che come tali sono carichi resistivi ed hanno un consumo noto.prolungasgusciata Credo sia ovvio ma io ve lo dico ugualmente: warnig32 ATTENZIONE warnig32 perché la 220V è pericolosa! Se non sapete quel che fate non cimentatevi con questi esperimenti, potreste farvi mooolto male, piuttosto chiedete a qualche conoscente che vi può aiutare, ma non fate da soli; rischiare l’arresto cardiaco per giocare con Arduino e non vale proprio la pena.

La via più semplice.

Vi ho promesso un prototipo semplice semplice per cui in questa prima fase ci accontenteremo di un software funzionante da subito, anche se migliorabile.  Per prima cosa dobbiamo trovare il “punto zero”. Mi spiego meglio. Abbiamo detto che il sensore misura da -1 a +1, ma con il circuito su cui abbiamo collegato il sensore passiamo da 1.5 a 3.5V. Il problema è che si tratta di un’onda che sale e scende continuamente per 50 volte al secondo, ma a noi interessa di fatto il punto zero ed il picco. Ho cominciato facendo delle misurazioni con la sonda senza alcun carico, senza cavo dentro la pinza. In questo modo il sensore per forza di cose deve misurare zero (nessun carico) e la tensione che circola è solo quella del nostro partitore di tensione che quindi possiamo misurare con Arduino. Noi sappiamo che dovrebbe essere 2.5V, ma nella realtà non è detto che i due resistori usati siano del tutto identici per via della tolleranza, la temperatura, etc, per cui potremmo trovarci con valori leggermente sballati, anche perché non è detto che la tensione in uscita da Arduino sia esattamente di 5V. La teoria ci dice che Arduino ha 1024 valori possibili (da 0 a 1023, 10 bit) corrispondenti a voltaggi fra 0 e 5V, perciò i 2.5V teorici del partitore cadono esattamente a metà per cui dovrei ottenere una misurazione pari a 1024/2=512.  Con il seguente sketch possiamo misurare i valori massimo e minimo di una serie consecutiva di 500 misurazioni:

 

#define misure 500
double sensorValue;
int sensorPin=A1;
void setup()

{
  Serial.begin(9600);
  while (!Serial) {} // wait for serial port to connect. Needed for Leonardo only
}
void loop()

{
  double maxval=0;
  double minval=1023;
  for(int i=0;i<misure;i++)
  {
   sensorValue = analogRead(sensorPin);
   if(sensorValue>maxval) maxval=sensorValue;
   if(sensorValue<minval) minval=sensorValue;
  }
  Serial.print(minval);
  Serial.print(" - ");
  Serial.println(maxval);
  delay(500);

}

In realtà non è nulla di speciale, misura l’ingresso analogico A1  (sul quale ho collegato il sensore) e tiene traccia dei valori massimo e minimo misurati che poi li stampa sulla porta seriale. Senza carico ho ottenuto un valore minimo di 511 e massimo di 513. Potremmo pensarla come ad un valore medio di 512 sul quale abbiamo un’oscillazione di ±1 dovuta ad un’oscillazione residua della tensione sul partitore o al rumore di fondo. Vorrei però farvi notare che all’inizio avevamo calcolato che ogni unità misurata corrispondeva a circa 32W motivo per cui quella singola unità di rumore rappresenta un errore di base di circa 32W sulla misurazione finale. Chiaramente la componente di rumore che misuriamo senza carico sarà presente anche nella misurazione finale per cui ne terremo conto per sottrarla.

Riassumendo: stiamo creando un sistema che non misura la tensione, non tiene conto dello sfasamento fra tensione  e corrente ed ha un errore di base di circa 32W. Con questa premessa il modo migliore per proseguire è fare dei campionamenti seriati sufficientemente lunghi da coprire almeno 3 periodi completi e da questi tenere traccia dei valori minimo e massimo. Una volta ottenuto questo valore abbiamo il valore di “picco” di corrente, che però non deve essere confuso con i valori medi che normalmente vengono utilizzati. Ad esempio anche la nota tensione 220V è intesa quale valore medio mentre il picco supera i 311V. Allo stesso modo il valore di picco di corrente ottenuto dovrà essere diviso per 1.414 (radice quadrata di 2) per ottenere il valore medio a noi familiare. Ho fatto i primi test con una lampada da 100W ed ho ripetuto la misurazione ottenendo valori minimi di 507 e massimi di 517 che potremmo perciò riferire ad un’oscillazione di 4 unità sul rispettivo valore basale massimo che abbiamo calcolato prima. Considerando che dai calcoli fatti all’inizio ogni unità rappresenta 0.146A, otteniamo 0.584A che a 220V corrispondono a quasi 129W. Ora, indipendentemente dalla correttezza del valore di 220V (a casa mia il multimetro segna 218V), questo è un valore di picco e dobbiamo dividerlo per 1.414 ottenendo 90.8W (talora ottengo un’unità in più raggiungendo 113.5W).

Vediamo lo sketch:

#define misure 576
#define taratura 513
double sensorValue;
int sensorPin=A1;

void setup()
{
  Serial.begin(9600);
  while (!Serial) {} // wait for serial port to connect. Needed for Leonardo only
}
void loop()
{
  double maxval=0;
  double Vmax=0;
  for(int z=0;z<misure;z++)
  {
   sensorValue = analogRead(sensorPin);
   if(sensorValue>maxval) maxval=sensorValue;
  }  
  Serial.print(“Max unit: “);
  Serial.print(maxval);
  Serial.print(” / Consumo: “);
  Serial.print((maxval-taratura)*0.146*220/1.414);
  Serial.println(” W”);
  delay(500);
}

Il listato qui sopra non è molto differente da quello precedente. Non fà nulla di particolare se non eseguire delle misure seriate e tenere traccia dei picchi massimi. Una volta stabilito qual’è il picco sottrae il valore di taratura prima calcolato ed effettua le conversioni che abbiamo descritto prima ottenendo il valore in Watt. Per semplicità ho utilizzato solamente il picco positivo che però non è detto essere simmetrico con quello negativo.

Con questo abbiamo terminato il nostro primo semplice prototipo. Abbiamo chiarito agli inizi che non sarebbe stato un campione di precisione ma in modo estremamente semplice abbiamo creato qualcosa di funzionante e abbastanza preciso vista la tipologia di sensore impiegato e la rudimentalità del software. Con carichi di 100W abbiamo un errore di circa il 10-11%, passando a 300W l’errore oscilla fra il 2 e 9% circa (misurazioni di 272.59 e 295.30).

Come potete immaginare ci sono delle possibilità di migliorare la precisione del sistema. Attualmente sto finendo di sviluppare un sistema più preciso, basato quasi esclusivamente su modifiche software che mi hanno portato ad un errore su carichi da 100W inferiori all’1%, cosa che si ripete su carichi da 300W migliorando perciò la precisione anche di 10 volte.

Ci sono numerose cose che si possono fare per migliorare la precisione della misurazione, dall’utilizzo della media quadratica anzichè il puro livello di picco, alla calibrazione automatica del “livello zero”, al sovracampionamento del segnale e alla modifica del fattore di “prescaling” del convertitore analogico-digitale. Il discorso però è molto complesso e merita un intero articolo, forse anche più di uno, per cui ho preferito separare questa prima parte introduttiva dal resto in modo da scrivere articoli a crescente difficoltà. Questo era il più semplice, ma già ci permette di avere qualcosa di funzionante per cui se pensate che vi possa bastare potete fermarvi anche qui, altrimenti spero che possiate apprezzare il prossimo articolo.

  7 Responses to “Arduino per il monitoraggio del consumo elettrico – parte 1: introduzione – it”

  1.  

    Salve, prima di tutto vorrei complimentarmi con lei per l’ottimo post scritto, e dato che anche io ho realizzato lo stesso progetto, vorrei sapere come ha collegato la pinza al piccolo circuito per trasformare la tensione considerato che la pinza ha un’uscita jack. Grazie per l’attenzione e cordiali saluti.

    •  

      Grazie per i complimenti e qui diamoci tutti del tu. Nei primi esperimenti ho tagliato il cavo e collegato i due fili al resto del circuito, invece in una seconda realizzazione che ho fatto per un amico ho usato dei semplici connettori audio da pannello per inserire direttamente il jack delle sonde. Ti conviene fare delle prove prima di saldare per controllare che il “verso” sia corretto, se sbagli la “polarità” dovrai semplicemente girare la sonda dal verso opposto sul cavo quindi nulla di grave.

  2.  

    esiste un modo per determinare il verso della corrente con questo sensore?

    Grazie

    •  

      si certo, le la corrente scorre dal versante “sbagliato” rispetto quello indicato sulla sonda ottieni un valore negativo per cui sai che la sensore scorre all’inverso. Scusa il ritardo nella risposta ma non mi è arrivata la notifica.

  3.  

    Senza un log completo non posso saperlo, non ho nulla in mano per poter rispondere. Vai su file -> impostazioni e su “Mostra output dettagliato” attiva almeno l’opzione “compilazione”, copi l’intero log e lo metti qui fra i commenti così posso leggerlo.