Il sensore e il display qui utilizzati erano già stati presentati nell’articolo “L'Evaluation Kit XMC 2GO di Infineon come scheda sensori per i robot ROBI".
Il sensore tipo INA219 prodotto dalla Texas Instruments, permette di misurare la tensione e la corrente fornite da una fonte di energia, nel nostro caso una batteria, comunicando i dati mediante un’interfaccia I2C.
L’integrato controlla sia la caduta shunt sia la tensione di alimentazione, con tempi di conversione e filtraggio programmabili. I dati vengono mostrati su un piccolo display di tipo OLED, anch'esso connesso tramite l’interfaccia I2C.
In quest’articolo, ne vedremo l’utilizzo per controllare il funzionamento di un piccolo motore elettrico. Per la sua gestione, si è utilizzato un modulo Arduino, rendendo il dispositivo facile da programmare usufruendo delle librerie già disponibili.
Un po’ di teoria
Per ricavare la tensione della batteria e la corrente assorbita dal carico, occorre far riferimento alla legge di Ohm (dal nome del fisico tedesco George Simon Alfred Ohm): è una legge fisica che mette in relazione la corrente con la tensione in un resistore. Si avrà quindi una relazione di semplice proporzionalità che può essere scritta nel seguente modo:
V = R • I
dove V è la tensione ai capi del resistore (misurata tramite un multimetro impostato come Voltmetro), I è la corrente che lo attraversa (misurata tramite un multimetro impostato come Amperometro), mentre R è il valore ohmico di resistenza.
Possiamo quindi calcolare il valore della tensione V ai capi del resistore.
In modo analogo, potremmo ricavare altre incognite, per esempio conoscendo la corrente e la tensione, R risulta da
R = V/I
Oppure conoscendo la tensione e la resistenza possiamo calcolare la corrente:
I = V/R
La potenza P si misura in watt (W) ed è il prodotto della tensione V espressa in volt (V) per la corrente I espressa in ampere (A):
P = V • I
Il Sensore INA219B
Come abbiamo visto, per ricavare i dati richiesti, occorrerebbero due multimetri, ma utilizzando la breakout board prodotta dalla Adafruit che misura solamente 23x20 mm, si risolveranno tutti i problemi.
Su di essa sono già presenti tutti i componenti necessari per il funzionamento dell’integrato INA219B prodotto dalla Texas Instruments.
L’integrato si presenta in package SOT23-8 e può essere alimentato con una tensione VS compresa tra 3 e 5V permettendo di misurare la tensione DC, con un valore massimo di +26V con 1 % di precisione trasmettendo i dati al processore tramite il protocollo I2C; è un’interfaccia digitale molto diffusa, utilizzata per la comunicazione a corto raggio tra differenti tipi di circuiti integrati, basata su un bus composto di due soli fili.
Nello schema a blocchi è possibile vedere un amplificatore di precisione che misura la tensione ai capi della resistenza shunt di rilevamento, che nella nostra scheda ha un valore di 0,1 ohm 1 %.
Poiché la differenza massima d’ingresso dell'amplificatore è ± 320mV significa che può misurare fino a ± 3.2 Ampere.
Con un convertitore ADC interno a 12 bit, la risoluzione è di ± 0.8mA, nella gamma ±3.2A, mentre con il guadagno interno impostato al minimo, la corrente massima misurabile sarà di ±400mA con la risoluzione di 0,1 mA.
Il modulo ha un pin head di sei pin (in modo da poter collegare facilmente questo sensore a una basetta), così come una morsettiera a vite con un passo di 3,5 mm in modo da poter collegare il carico.
Con riferimento allo schema elettrico, la parte principale del circuito è quella che ruota intorno al sensore INA219, al pin 1 e 2, VIN+ e VIN-, a cui è collegata la resistenza di misura dal valore di 0,1Ω 1%.
L'alimentazione, che può variare da un minimo di 3 a un massimo di 5V, è fornita al pin 4 (terminale positivo) e al pin 3 (terminale negativo), dove è presente il condensatore di disaccoppiamento da 100nF.
Tramite il livello logico fornito ai pin 7 e 8 (A0 e A1), viene scelto l'indirizzo della scheda che può essere: 0x40, 0x41, 0x44 , 0x45.
Per modificarlo, occorre eventualmente, depositare una goccia di stagno sui ponticelli SJ1 o SJ2; nel caso non sia selezionato, il valore di default sarà 0x40.
I pin dell'interfaccia I2C (acronimo di Inter Integrated Circuit) sono rappresentati dal pin 5 (SCL - Serial Clock Line) per il clock e 6 (SDA - Serial DAta) per i dati.
Sul connettore d'uscita JP1, sono riportati tutti i segnali per l'interfacciamento, sono inoltre visibili i due resistori di pull-up da 10kΩ della linea I2C.
Descrizione del display OLED
Per mostrare i dati letti dal sensore, si è utilizzato un piccolo display monocromo 128x32 I2C OLED (dimensioni del modulo 20 x 35mm ) prodotto anch’esso dalla Adafruit, che presenta una diagonale di 1", ma è molto leggibile dato l'alto contrasto di un display OLED.
Il display presenta 128x32 singoli pixel bianchi OLED, ciascuno è acceso o spento dal chip controller, non è richiesta alcuna retroilluminazione riducendo l'assorbimento di potenza necessaria.
L'integrato pilota è il modello SSD1306 che comunica tramite il protocollo I2C.
Sono necessari solo 3 pin per comunicare con il chip sul display OLED, due dei quali sono i pin I2C dati / clock.
Il display OLED e il driver, richiedono un'alimentazione di 3,3 V e pari valore hanno anche i livelli logici per la comunicazione.
I requisiti di alimentazione dipendono da quanto del display è acceso, ma in media il display assorbe circa 20mA dalla rete di alimentazione 3.3V.
Per l'utilizzo, è necessario un microcontrollore con più di 512 byte di RAM, in quanto la memoria del display deve essere bufferizzata.
Esaminando i vari blocchi che formano il circuito, abbiamo la sezione del display/processore, basata sull'integrato SSD1306 che è un single-chip CMOS driver per display tipo OLED / PLED ( Organic Light Emitting Diode, Polymer light-emitting diodes).
La sezione del circuito permette di traslare i livelli logici tra i valori di tensione di 3.3 e i 5V.
In questo caso, è stata utilizzata una tipologia di circuito che usa dei MOSFET e che presenta i seguenti vantaggi:
- è economico;
- sono utilizzati componenti generici, in questo caso dei MOSFET tipo BSS138;
- è possibile isolare le sezioni del bus semplicemente togliendo l’alimentazione ai MOSFETs interessati;
- viene fornita una protezione della sezione a basso livello contro eventuali spikes (con spike ci si riferisce ad una rapida variazione di tensione) nella sezione ad alto livello.
Per rendere più semplice il collegamento, sul piccolo modulo, è stato aggiunta una sezione alimentatrice formata dal regolatore tipo RT9193 di tipo LDO Ultra-Low Noise, Ultra-Fast che fornisce in uscita 3,3V con 300mA di corrente.
Per ultimo abbiamo il connettore d'ingresso, dove sono presenti pin di alimentazione e d'interfaccia I2C rappresentati dal pin SCL, SDA più il pin RES.
Per quanto riguarda l’indirizzo I2C della scheda, questo è del tipo a 7-bit ed è fissato al valore di 0x3C.
Librerie di gestione
Gestire il modulo sensore e il modulo display sarebbe piuttosto complesso, fortunatamente la stessa Adafruit ha messo a disposizione delle apposite librerie che semplificano la scrittura del programma, possono essere scaricate dal sito del produttore, in particolare sono necessarie:
- La libreria di gestione del modulo INA 219;
- La libreria di gestione del modulo OLED;
- La librerie grafiche per il modulo OLED.
Per il giusto funzionamento del display, occorrerà modificare all’interno del file Adafruit_SSD1306.h della libreria, la linea che definisce la dimensione del display per cui si dovranno cercare le linee:
#define SSD1306_128_64 //#define SSD1306_128_32
E di dovrà modificarle in:
//#define SSD1306_128_64 #define SSD1306_128_32
Uso della libreria
Per utilizzare il sensore, occorre installare l’apposita libreria, espandendo il file zip nella cartella Libraries nella cartella Arduino, la si dovrà rinominare in Adafruit_INA219.
Si dovranno chiudere tutte le istanze dell’IDE, per poi riaprire una, in modo che l'IDE riconosca la nuova libreria.
Funzioni di assegnazione e inizializzazione
Adafruit_INA219 (uint8_t addr = INA219_ADDRESS);
Questa funzione crea l’oggetto Adafruit_INA219 con relativo indirizzo, se questo non è specificato, è utilizzato quello di default (0x40). Se invece si utilizza più di un modulo INA219, occorrerà definire per ognuno, un proprio indirizzo tra quelli disponibili.
void begin (void);
Questa istruzione inizializza la comunicazione I2C con il dispositivo Adafruit_INA219 utilizzando i valori di configurazione predefiniti.
Funzioni di lettura del sensore
float getBusVoltage_V (void);
Legge la tensione tra GND e V. Questa è la tensione totale vista dal circuito in esame. (Tensione di alimentazione - tensione shunt). Il valore di ritorno è in Volt.
float getShuntVoltage_mV (void);
Legge la tensione tra V e V +. Questa è la caduta di tensione misurata ai capi del resistore shunt. Il valore di ritorno è in millivolt.
float getCurrent_mA (void);
Legge l'attuale corrente ricavata tramite la legge Ohm dalla tensione shunt misurata. Il valore di ritorno è in milliampere.
Il collegamento
Per testare il dispositivo, si è realizzato un semplice circuito, in cui il sensore è utilizzato per la lettura della tensione di alimentazione, la corrente e la potenza assorbita da un piccolo motore elettrico.
Nell’esempio riportato nella foto, si è utilizzato un Micro Pro prodotto dalla SparkFun, che è una piccola scheda che monta un processore ATmega32U4, questo fornisce la connettività on-board, per cui non è necessario utilizzare un'interfaccia USB esterna.
In alternativa, sarà possibile utilizzare una qualunque scheda Arduino, tipo la Arduino UNO.
Come abbiamo visto, i due moduli hanno un diverso indirizzo, che vale 0x40 per il sensore e 0x3C per il display.
Se si utilizza la scheda Arduino UNO, i pin dell’interfaccia I2C sono rappresentati dal pin A4 (SDA) e A5 (SCL).
Abbiamo ancora bisogno di connettere il pin RES del display ad un pin IN/OUT digitale, nel nostro caso al PIN 4, anche se potrà essere diverso, variando il valore indicato nel programma.
Nel caso si utilizzasse una scheda Arduino UNO R3, i pin I2C sono stati replicati a lato dei pin digitali come riportato in figura.
Come abbiamo visto le caratteristiche di alimentazione, sia del modulo sensore sia del display, sono simili e possono variare tra i 3 e i 5 V, permettendo di utilizzarli con una grande varietà di schede di controllo.
Per questo, oltre che a schede tipo Arduino UNO, Arduino MEGA2560 e Arduino Leonardo, potranno essere collegati alla scheda Arduino DUE che lavora con logica a 3,3 V.
Utilizzando entrambi i dispositivi, su bus I2C (che usa solo due pin), sono lasciate libere molte porte digitali utilizzabili per altri scopi.
Sarà altresì, possibile inserire altri dispositivi dotati di bus I2C, curando solo che abbiano tutti un indirizzo diverso.
Va verificato inoltre, che i vari dispositivi lavorino tutti con la medesima tensione; in caso contrario, occorrerà inserire un traslatore di livello.
Uno di questi potrebbe essere il convertitore di livello logico a 4 canali bidirezionale della Adafruit.
In questo modo, sarà possibile avere moduli I2C con livelli logici (3,3-5V) diversi, presenti sulla stessa linea del bus.
Il programma di gestione
Il programma di gestione è presente nell'allegato ed è molto semplice, il listato è sufficientemente commentato per comprenderne il funzionamento.
Dopo il caricamento delle varie librerie, l’inizializzazione del sensore e del display, il programma legge ciclicamente i dati rilevati dal sensore, mostrandoli sul display OLED.
//Caricamento delle librerie di comunicazione #include <SPI.h> #include <Wire.h> //Caricamento delle librerie gestione display #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define OLED_RESET 4 //Definizione pin reset display Adafruit_SSD1306 display(OLED_RESET); //Caricamento delle librerie gestione sensore #include <Adafruit_INA219.h> //Costruisce un'istanza della Adafruit_INA219 //Se non viene specificato alcun indirizzo, viene utilizzato //quello di default (0x40). Se si collegano più modulo INA219 //occorre indicare il suo indirizzo per esempio // Adafruit_INA219 ina219_B(0x41) Adafruit_INA219 ina219; void setup() { //Impostazione modulo INA219 uint32_t currentFrequency; //Inizializza la comunicazione I2C con il dispositivo Adafruit_INA219 // utilizzando i valori di configurazione predefiniti. ina219.begin(); // Impostazione modulo display con indirizzo I2C addr 0x3C display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Cancellazione schermo e buffer display.clearDisplay(); // Messaggio iniziale display.setTextSize(1); //Definizione della grandezza del carattere display.setTextColor(WHITE); //Impostazione del colore del testo display.setCursor(0,0); //Posizionamento del cursore display.println("www.adrirobot.it"); display.setTextColor(BLACK, WHITE); // Inverte il colore del testo display.println("Voltmetro digitale"); display.display(); // Stampa sul display delay(2000); //Pausa per lettura dei valori } void loop() { //Definizione variabili float shuntvoltage = 0; float busvoltage = 0; float current_mA = 0; float loadvoltage = 0; //Acquisizione dei valori dal sensore shuntvoltage = ina219.getShuntVoltage_mV(); //Legge la tensione tra V e V +. Questa è la caduta di tensione //misurata ai capi del resistore shunt. Il valore è espresso in mV busvoltage = ina219.getBusVoltage_V(); //Legge la tensione tra GND e V. Questa è la tensione totale vista //dal circuito in esame. (Tensione di alimentazione - tensione shunt). //Il valore è in Volt. current_mA = ina219.getCurrent_mA(); //Legge la corrente, ricavata tramite la legge di Ohm //dalla tensione shunt misurata. Il valore è in mA. loadvoltage = busvoltage + (shuntvoltage / 1000); //Calcola la tensione sul carico //Stampa dei valori misurati sul display display.clearDisplay(); // cancellazione dello schermo display.setTextSize(2); //Definizione della grandezza del testo display.setTextColor(WHITE); //Impostazione del colore del testo display.setCursor(0,0); //Posizionamento del cursore // Definizione dei valori con relative unità di misura display.print("V:"); display.print(loadvoltage, 2); display.println(" V"); display.print("A:"); display.print(current_mA,1); display.println(" mA"); display.display(); // Stampa dei valori sul display delay(2000); //Pausa per lettura dei valori display.clearDisplay(); // cancellazione dello schermo display.setCursor(0,0); //Posizionamento del cursore // Mostra sul display il valore della potenza assorbita // ottenuta moltiplicando la corrente per la tensione sul carico display.println("Potenza"); display.print((current_mA*loadvoltage)/1000); display.print(" W"); display.display(); // Stampa dei valori sul display delay(2000); //Pausa per lettura dei valori }
Immagini del display
Immagine iniziale
Lettura tensione e corrente
Lettura potenza assorbita
Filmato illustrativo
Nel filmato, potrete vedere il sensore e il display in funzione; il test è stato realizzato con un Micro Pro, ma può essere utilizzato un qualunque modello di Arduino.
Conclusioni
Quanto presentato in quest’articolo è un tipico utilizzo del sensore INA 219, che potrà essere inserito in un sistema di controllo più complesso e completo.
I valori letti, potranno essere utilizzati per monitorare eventualmente i consumi di corrente e produrre allarmi o avvisi in caso questi superino valori preimpostati, oppure far sì che, in via automatica, sia disconnesso il carico, per evitare guasti.
Si potrà implementare la funzione che avverta, nel caso di alimentazione a batteria, che il valore fornito sia troppo basso.
Abbiamo anche visto l’utilizzo del display OLED, che potrà essere utilizzato in altri progetti in sostituzione dei normali display LCD 16x2.
Starà solo all’inventiva del progettista utilizzare al meglio il dispositivo.
Sfortunatamente nell'articolo non è visibile il link nel filmato, per chi volesse vederlo eccolo: Filmato illustrativo uso sensore
Ho notato che adrirobot sottolinea che è necessario riavviare l’IDE per fargli digerire le modifiche. Posso dire che è una cosa che secca un po’? A voi non da fastidio? Perchè succede?
La risposta è molto semplice: succede perchè l’IDE non è un ambiente di lavoro realtime ma carica quei file come delle vere e proprie librerie. Come se lavorassi da remoto.
Tutto sommato succede anche con altri programmi. Non è così terribile infondo 🙂
E poi quel momento di pausa può servire a far ordine, magari 🙂
Stando al disordine medio dei banchi di lavoro di hobbysti e professionisti che ho potuto vedere ultimamente, “quel momento di pausa” dovrebbe essere almeno di 48 ore 🙂
Condivido!
Oppure come mi succede che non un banco dedicato, per cui a volte, prendo tutto e metto in vari contenitori e il giorno dopo devo passare un’ora a ritrovare le varie parti del progetto.
Sempre parlando del laboratorio di Elettronica, vi ripropongo l’articolo
http://it.emcelettronica.com/laboratorio-di-elettronica
Concordo con quanto scrive Piero!
Posso suggerire ad adrirobot che il prossimo esperiemento sia in effetti un indicatore a led dal verde al rosso o con led rgb che cambia colore?
Puoi spiegare meglio la tua richiesta, cosa dovrebbe indicare/rappresentare il sistema a led?
Certo, scusa. Alla fine dell’articolo, nelle conclusioni, scrivi “Si potrà implementare la funzione che avverta, nel caso di alimentazione a batteria, che il valore fornito sia troppo basso.” ecco pensavo a dotare il sistema di un indicatore visivo.
Grazie per la precisazione, credo non sia difficile implementare la funzione. Appena posso modifico il circuito inserendo un led RGB e modifico il programma.
Sono molto interessato alle funzionalità di questo progetto sopratutto per la trasmissione in I2C delle misure utilizzando un unico integrato…
Nel mio caso però vorrei monitorare correnti ben più elevate, diciamo intorno ai 40A, come dovrei fare? cosa cambierebbe?
Ho fatto qualche ricerca, potresti utilizzare un modulo basato sull’integrato prodotto dalla ALLEGRO. Il suo nome è AC709 e può misurare correnti sino a 75 A.
Sfortunatamente l’uscita non è I2C ma è una tensione analogica, per quanto motivo, occorre utilizzare una porta A/D, e con la risoluzione a 10bit della porta di Arduino i valori potrebbero non essere molto accurati.
http://www.pololu.com/product/2199
Ottimo progetto … domanda per sitemi AC ,tensioni, corrente e fase esiste qualche modulo.
Saluti
Il problema di misurare tensioni e correnti alternate è dato dal fatto che Arduino accetta in ingresso solamente tensioni continue.
Perciò occorre “convertire” queste grandezze in modo che possano essere lette dalle porte analogiche di Arduino.
Cercando in rete ho trovato questo progetto che dovrebbe fare al caso tuo.
http://openenergymonitor.org/emon/node/58
Considera che visto i circuiti di trasformazioni e la bassa precisione del convertitore analogico/digitale dell’Arduino UNO i risultati potrebbero non essere troppo accurati.
ok .. quindi l’accuratezz dipende molto dal fatto che io debba convertire in dc … domanda forse stupida.
Ma a me non serve sapere istantaneamene il valore della tensione o della corrente, non ho bisogno di sapere ora che tensioni abbiamo , ma potrei farlo tramite elaborazione numerica in un secondo momento , per cui avevo pensato questo .
1) traslare dla sinusoude e trasformarla in un range AC da 1 a 4 v con la possibiltà di avere tensioni anche superiori a 220V , campionarla ad una frequenza maggiore , non so 200-300 Hz e memorizzare i dati su una memoria … sarà possibile ?
Se si quale potrebbe essere l’errore ce potrei avere e fino che frequanza di campionatura mi potrei spingere considerando anche il salvatazzio su memoria .. Grazie ancora
Per risolvere il problema della risoluzione del convertitore A/D si possono percorrere anche altre due strade.
1 – Utilizzare una scheda Arduino due che ha dei convertitori A/D a 12 bits anche se la massima tensione accettata è in questo caso di 3.3V
http://it.emcelettronica.com/arduino-due-tutorial-atmel-sam3x8e-arm-cortex-m3-cpu
2- Utilizzare con la scheda Arduino UNO una piccola schedina come quella realizzata dalla Adafruit che fornisce 4 canali con una risoluzione di 16 bits, la sua interfaccia con Arduino è di tipo I2C
http://www.adafruit.com/product/1085
quidni la strada si potrebbe percorrere da quanto sono risucito a capire..
Giusto ? quali potrebbere essere secondo lei i limiti di tutto questo ? Grazie ancora
Si credo che sia possibile, per i limiti (diamoci pure del tu) credo dipenda molto da cosa devi farci dei dati e che precisione ti serve..
Cercando in rete, ho trovato questo progetto
http://openenergymonitor.org/emon/
che come vedrai è Arduino compatibile ed è molto sofisticato.
E’ possibile impostare il PGA in modo da misurare correnti sempre più basse ed avere un’accuratezza maggiore. Cioè
se il PGA è impostato al minimo posso misurare fino a 400mA con un’accuratezza di 0.1 mA
se il PGA è impostato al massimo posso misurare fino a 3200 mA con un’accuratezza di 0.8 mA.
Di default qual è il valore di PGA impostato ?
come si fa ad impostare il valore del PGA ?
Quali sono i valori di riferimento intermedi PGA =1,2,4 e 8 ?
grazie.
La gestione dell’integrato INA219 attraverso la libreria di Arduino è limitata, per sfruttare appieno le sue potenzialità occorre accedere direttamente tramite l’interfaccia I2c.
Per le impostazioni e le caratteristiche che chiedi ti consiglio di vedere direttamente il data sheet dell’integrato
http://www.ti.com/lit/ds/symlink/ina219.pdf
Ho richiesto il materiale, e penso di replicare il progetto per poi adattarlo ad una mia idea.
Grazie Adriano
PS:
Ti contatterò presto per chiederti su il progetto ricevitore ad ultrasuoni del tuo sito.
Sergio
Bene, quando hai realizzato il progetto puoi pubblicare qui il link, cosi che anche altri possano realizzarlo! Tra l’altro è possibile avere qualche anticipazione sull’idea?
complimenti bel progettino e un articolo veramente completo. Certo che l’esigenza di conoscere gli assorbimenti di un carico è sempre presente in diverse applicazioni, come ad esempio dove è necessario caricare delle batterie, oppure controllare eventuali corti di sezioni delicate e un oggetto del genere, viste le dimensioni, trova largo utilizzo. L’alternativa potrebbe essere quella di realizzare un circuito di sensing con gli amplificatori operazionali, in aggiunta ai canali ADC di un micro, ma non sempre è la strada percorribile, soprattutto quando si ha la necessità di una accuratezza. Unica pecca dell’oggeto è l’assenza di isolamento dal canale di misura, cosa che invece la si ottiene con sensori ad effetto Hall.
Ti ringrazio per i complimenti, per quanto riguarda un sensore di corrente con effetto hall, ho fatto un’esperienza con il modello ACS714 della Allegro con cui ho realizzato un voltmetro/amperometro con Arduino.
L’unica pecca, se così si può dire è che l’uscita del sensore è analogica e deve essere letta tramite la porta A/D del processore.
Puoi vedere l’applicazione a questa pagina http://www.adrirobot.it/arduino/voltmetro_amperometro/Arduino_voltmetro-amperometro.htm
Beh spesso gestire l’analogico ti consente di realizzare applicazioni più precise in termini di acquisizioni in base ampiezza e temporali. Come sensori ad effetto hall ci sono anche alcuni prodotti dalla Infineon (molto recenti risalgono al 2014 con uscita in commercio) che prevedono un canale di comunicazione I2C e nascono sopratutto per applicazioni automotive.
Cercando un pò in rete ho trovato il sensore della Infineon, modello TLI4970-D050T4, che tra l’altro è montato su una piccola scheda prodotta dalla MikroElektronika
http://www.mikroe.com/click/hall-current/
Questultima è dotata dello stesso bus della scheda PIC Clicker
di cui si parla nell’articolo
http://it.emcelettronica.com/pic-clicker-semplice-scheda-di-mikroelektronika-con-grandi-potenzialita