Come fare misurazioni più precise con Arduino

In questo articolo scopriremo come misurare le tensioni (e dunque anche i segnali provenienti dagli eventuali sensori analogici utilizzati) con maggiore precisione quando utilizziamo, come sistema per l’acquisizione analogico-digitale (ADC), il microcontrollore Arduino. Infatti, se alimentiamo Arduino con la porta USB del computer, otterremo delle letture di tensione relativamente errate sia a causa delle fluttuazioni di tensione tipiche di queste porte sia della mancanza di calibrazione della tensione di riferimento usata dall’ADC. Vedremo come risolvere entrambi i problemi.

Come abbiamo illustrato nell’articolo Come misurare una tensione DC, AC o PWM con Arduino, che puoi trovare qui, normalmente quando si misura con Arduino la tensione di una corrente elettrica fornita dai sensori a uno dei pin di ingresso analogico, si usa la funzione analogRead (). Poiché Arduino ha di solito un convertitore analogico-digitale (ADC) a 10 bit, il valore restituito da analogRead () è compreso tra 0 e 1023, essendo quest’ultimo valore dato dalla formula 2^(nbit-1) = 2^(10-1).

Ciò è dovuto alla cosiddetta “risoluzione” dell’ADC. La risoluzione è il grado in cui qualcosa può essere rappresentato numericamente. Maggiore è la risoluzione, maggiore è l’accuratezza con cui qualcosa può essere rappresentato. Misuriamo la risoluzione in termini di numero di bit di risoluzione. Ad esempio, una risoluzione di 1 bit consentirebbe solo due (due alla potenza di uno) valori: 0 e 1. Una risoluzione a 2 bit consentirebbe quattro (due alla potenza di due) valori: 0, 1, 2 e 3.

Lettura di tensione fornita da un ipotetico ADC con una risoluzione di soli 2 bit. 

Se provassimo a misurare un intervallo di 5 V con una risoluzione di due bit e la tensione misurata fosse di 4 V, l’ADC restituirebbe un valore numerico di 3, poiché 4 V cadono tra 3,75 e 5 V. Quindi, con il nostro esempio, l’ADC con risoluzione a 2 bit può rappresentare solo la tensione con quattro possibili valori risultanti. E così via. Con la gamma ADC del nostro Arduino di 0 – 1023 abbiamo invece 1024 possibili valori, e poiché 5 V : 1024 = 0,0049 V, la precisione corrispondente è pari a 4,9 x 2 = 10 mV circa.

In effetti, le specifiche ci dicono che Arduino è in grado di misurare con le tensioni con una precisione di  ± 2 LSB (Least Significant Bit), quindi l’errore massimo è di 2 bit (4 decimali) su 10 bit (1024 decimali). Di conseguenza, Quindi la precisione, nel caso peggiore, del’ADC di Arduino è di 4/1024 o 1 parte su 256, ovvero dello 0,25%. Tuttavia, il limite della precisione della misurazione con Arduino è più grande e dipende da altre ragioni, che fra poco vedremo insieme alle rispettive soluzioni.

In pratica, un ADC misura una tensione grazie a una serie di comparatori di tensione e ad una tensione di riferimento (che deve essere calibrata e non fluttuante). Arduino Uno, Mega, Nano, etc. hanno tutte una risoluzione di 10 bit (Arduino Due e Arduino Zero di 12 bit), ma non serve avere una buona risoluzione se poi i valori forniti non sono precisi, come in Arduino. Perciò è cosi importante adottare gli accorgimenti suggeriti in questo articolo quando si lavora con una scheda Arduino.

Come un ADC effettua la conversione da analogico a digitale grazie a una serie di comparatori.

Perché Arduino fornisce valori di tensione non precisi

Infatti, che cosa rappresentano i valori 0 e 1023? Ebbene, 0 rappresenta 0 V mentre 1023 si potrebbe ingenuamente pensare che rappresenti 5 V, dato che Arduino può accettare tensioni di ingresso da 0 V a 5 V e che, se vi sono 1024 valori per mapparli (compreso lo zero), allora 1023 ci si aspetta che corrisponda a 5 V. Tuttavia non è così, nel senso che in realtà 1023 rappresenta la cosiddetta “tensione operativa” della scheda Arduino in uso, che di solito non è esattamente di 5 V, come ora vedremo.

Quando parliamo di tensione operativa, ovvero di tensione di funzionamento, questa è la tensione disponibile per Arduino dopo il circuito di alimentazione. Ad esempio, se si dispone di una tipica scheda Arduino Uno e la si alimenta dalla presa USB, sulla scheda dovrebbero essere disponibili “in teoria” i 5 V forniti dalla presa USB sul computer o sull’hub, ma nella realtà la tensione è leggermente più bassa per varie ragioni, ed è anche fluttuante perché la sorgente USB non è fatta per quest’uso.

Ciò può essere facilmente dimostrato collegando una scheda Arduino Uno a una porta USB e inserendo un multimetro per misurare la tensione tra i pin 5V e GND. Alcune schede restituiscono un minimo di 4,8 V, alcune valori più alti ma ancora inferiori a 5 V. Quindi, se stai la cercando precisione, alimenta la tua scheda da un alimentatore esterno tramite la presa DC oppure tramite il pin Vin (ora vedremo come), così  potrai risolvere sia (in parte) il problema della tensione errata sia quello delle sue fluttuazioni.

Misurazione della tensione ai capi dei pin 5V e ground per un Arduino Mega alimentata da una porta USB. Si noti come il valore differisca di molto da quello atteso, che è di 5,00 V. 

Ciò è importante poiché la precisione di qualsiasi valore analogRead () sarà influenzata dal fatto che non si hanno realmente 5 V. Se non hai un’alimentazione non-USB, potresti usare un coefficiente moltiplicatore (intorno a 1,1 nel caso di Arduino Uno) nello sketch per compensare la caduta di tensione, altrimenti se ad es. la tensione è di 4,8 V, l’intervallo analogRead () di 0 – 1023 sarà correlato a 0 – 4,8 V e non a 0 – 5 V. Tuttavia, rimarrebbero fluttuazioni nella tensione, poiché l’USB non è una sorgente stabile.

Il problema delle fluttuazioni nell’alimentazione

Vi sono vari modi per alimentare Arduino (dalla porta USB di un computer, da un alimentatore, con una batteria, etc.) e per collegare la nostra fonte di energia alla nostra scheda (connettore, pin Vin, pin 5V). Il “cuore” di Arduino (il chip Atmega328) funziona ad una tensione compresa tra 4.5 e 5.5 V, tuttavia l’Atmega non è da solo sulla scheda: Arduino è dotato di altri componenti che permettono di alimentarlo anche con una tensione più alta. Ma vediamo quali sono i vari modi di alimentarlo.

Il modo più ovvio è l’alimentazione da PC tramite un cavo USB, utilizzato anche per la programmazione di Arduino (per cui i dilettanti, ignorando l’inaffidabilità dell’alimentazione via USB, purtroppo di solito usano questo sistema). Se oltre al cavo USB usato per la programmazione alimentiamo Arduino anche tramite un connettore tramite l’apposito ingresso DC o dal pin Vin (di cui parleremo fra poco), verrà bypassata automaticamente l’alimentazione da USB e verrà utilizzata invece quella esterna.

Un comune alimentatore universale switching (lo puoi trovare ad es. qui), che converte la 230 V AC in bassa tensione, ad es. a 7,5 V DC, è il modo più semplice ed economico per fornire ad Arduino un’alimentazione “esterna”, cioè non USB.

Un altro modo per alimentare Arduino è attraverso una batteria. Purtroppo, però, sia la tensione fornita dalle porte USB sia quella fornita dalle batterie fluttuano, sia pure in modo diverso. Per esempio, una porta USB alle volte fornisce una tensione di 5,12 V, alle volte di 5,14 V, insomma la tensione proveniente dalle porte USB oscilla. L’uscita di tensione fornita da un adattatore AC-DC – cioè da un comune alimentatore stabilizzato – è più stabile, purché a questo non siano attaccati altri carichi.

Il problema delle fluttuazioni nella tensione di alimentazione fa sì che Arduino fornisca valori errati, cioè più o meno grandi rispetto ai valori reali. Perciò, se se stai usando un sensore che restituisce un valore come tensione (ad es. un sensore di temperatura), il valore fornito da Arduino sarà errato: qualche volta più alto e qualche volta più basso di ciò che il sensore avrebbe misurato se la tensione di alimentazione di Arduino fosse stata stabile, cioè non fornita da una sorgente di scarsa qualità come l’USB.

Fluttuazione della tensione ai capi dei pin 5V e ground per un Arduino Uno alimentato da una porta USB. Si noti come la tensione oscilli sopra e sotto un valore “medio”.

Quando Arduino è alimentato da delle semplici batterie o da una power bank (che ha una batteria al litio e un circuito che ne eleva la tensione a 5 V), le cose vanno ancora peggio. È probabile che la tensione delle batterie diminuisca nel tempo. La diminuzione (o la fluttuazione) della tensione nell’alimentazione elettrica influenzano i risultati della conversione dall’ADC a un valore di tensione. Quindi, nell’interesse della precisione, occorre usare un alimentatore esterno stabilizzato. Ma come farlo?

Se usiamo l’ingresso DC (vedi figura) – e quindi un connettore plug-in a sezione rotonda tipico di molti alimentatorini economici – la tensione che forniamo da qui deve essere compresa tra 7 e 12 Volt: l’ideale è 7,5 V, poiché il resto della tensione non porta nessun beneficio, ma anzi fa aumentare la temperatura del regolatore. Questa tensione passa attraverso un diodo di protezione (nel caso invertiste accidentalmente le polarità) e poi viene portata a 5 V dal regolatore di tensione interno di Arduino.

L’alimentazione di Arduino tramite l’ingresso esterno DC per connettore plug-in a sezione rotonda con diametro di 5,5 mm, tipico dei comuni alimentatori switching.

Un secondo modo per alimentare Arduino “dall’esterno” (cioè non tramite il cavo USB) usa il piedino Vin. Questo metodo è molto simile a quello con connettore rotondo appena illustrato. Infatti, da qui la tensione passa dal regolatore di tensione incorporato di Arduino prima di arrivare al “cuore” del microprocessore. Tuttavia questo pin non è protetto con il diodo, quindi fate attenzione ad non invertire le polarità! Poiché non c’è il diodo, la tensione minima può essere un po’ inferiore, compresa tra 6.5 e 12 V.

Un terzo modo (più rischioso) per alimentare Arduino dall’esterno è il collegamento diretto al pin 5 V. Si tratta, infatti, di collegare direttamente una tensione stabilizzata di 5 V ad Arduino. La tensione deve assolutamente stare tra 4,5 e 5,5 V (pena il danneggiamento irreversibile di Arduino). La cosa positiva è che così il regolatore di tensione di Arduino (che non è calibrato, come ora vedremo) viene bypassato, e inoltre alimenterete in modo diretto i dispositivi a 5 V (ad es. dei servomotori).

I pin Vin e quello di 5 V di una scheda Arduino Uno.

Dunque, per eliminare il problema delle fluttuazioni nella tensione di alimentazione, che si ripercuote sulle misurazioni di una tensione, occorre alimentare Arduino con un alimentatore stabilizzato (usando uno dei tre modi / ingressi appena descritti). Se usate un alimentatorino switching economico, esso inoltre non deve avere attaccati altri carichi oltre alla scheda Arduino, poiché quando gli attaccate altri carichi la tensione che Arduino “vede” fluttua al variare della corrente assorbita da questi ultimi.

Il problema della mancanza di calibrazione

In alcuni microcontroller Arduino, esiste un riferimento di tensione incorporato (built-in) a 1,1 V. Arduino Uno e Arduino Nano, ad esempio, ne hanno entrambi uno, e molti altri Arduino ne hanno uno. Di solito, si configura l’ADC di Arduino in modo che usi l’alimentatore del microcontrollore come riferimento di tensione poiché è più facile, e ciò è la modalità predefinita del software Arduino. Il problema è che, così facendo, il chip dell’alimentatore definirà la precisione della misurazione.

Il riferimento di tensione interno fornito dal chip ATMega328P di Arduino non fornisce letture di tensione ultra precise, ma è stabile contro i cambiamenti di temperatura e tensione di alimentazione; dunque, è utile quando non si desidera affrontare il problema dell’aggiunta di un chip esterno per determinare le tensioni ed è necessario un riferimento più stabile di Vcc (quando questa è fornita da es. da una pessima sorgente come l’USB, in cui per di più la tensione di alimentazione fluttua).

Anche se alimentato con un alimentatore esterno di migliore qualità, Arduino può ancora fornire letture di tensione leggermente (ma molto meno di prima) errate perché la sua tensione di riferimento non è calibrata. In figura, si vede la tensione (che dovrebbe essere di 5,00 V) misurata sul pin 5 V di un Arduino Mega alimentata tramite ingresso DC a connettore tondo.

In alternativa, puoi usare un riferimento di tensione esterno, ma lo sconsiglio perché così è molto facile danneggiare Arduino. Se si utilizza un riferimento di tensione esterno, la misurazione ADC effettuata da Arduino sarà più accurata poiché si controllano le specifiche del chip. Tuttavia, ricorda che l’ADC interno in Arduino non è comunque troppo preciso (vedi la scheda tecnica dell’ATMega328: precisione assoluta 2LSB, inclusi errori INL, DNL, quantizzazione, guadagno e offset).

In generale, non si avrà la minima idea di quanto il chip dell’alimentatore di Arduino sia accurato finché non si fanno delle misurazioni appropriate: sebbene il riferimento di tensione interno di Arduino sia stabile con la temperatura e con la tensione, il suo valore iniziale varia leggermente tra i vari chip (ma non da originale a clone, pertanto se non potete optare per l’Arduino originale non cambierà granché). Dunque, per avere misure di tensione precise hai bisogno di fare una calibrazione.

Le informazioni nel datasheet sul riferimento di tensione di Arduino indicano che ha valori minimi e massimi di 1,0 V – 1,2 V e nominalmente 1,1 V. Non ci sono informazioni sulla ripetibilità o sulla stabilità. Suggerisce che la tensione potrebbe variare di ± 9% intorno a 1,1 V. Quindi la domanda è: il riferimento di tensione di Arduino è buono? Le specifiche sembrano implicare che possa variare di ± 9% in qualsiasi momento. In realtà, il riferimento di tensione può essere molto migliore.

Per calibrare Arduino, può essere utile un alimentatore stabilizzato regolabile da banco (ne puoi trovare diversi modelli qui), che è dotato di un voltmetro preciso e affidabile. Tuttavia, se non ce lo abbiamo, possiamo usare un alimentatore più economico, ma in tal caso dovremo avere un multimetro di precisione.

In altre parole, la precisione iniziale è di ± 9% ma la calibrazione del riferimento di tensione di Arduino consente di eliminare questo errore (di tipo sistematico). La gamma di microcontrollori Arduino fornisce ingressi analogici che possono essere utilizzati per misurare la tensione. Possiamo ad es. usare Arduino per costruire un voltmetro. Se quindi vogliamo avere delle misurazioni di tensione assolute (e non solo relative) corrette, la calibrazione del riferimento di tensione di Arduino è essenziale.

Vediamo come effettuare, in pratica, questa calibrazione. La calibrazione può essere effettuata in due diversi modi: via software oppure (metodo più rischioso) via hardware. Nel primo caso, si tratta di determinare e aggiungere nello sketch di Arduino un fattore moltiplicativo appropriato (diverso a seconda dell’Arduino e dell’alimentatore usati). Nel secondo caso, invece, si tratta di regolare sperimentalmente al valore opportuno la tensione fornita da un alimentatore stabilizzato regolabile da banco.

Prima di calibrare la tensione via software, è opportuno calibrare l’offset, cioè la differenza costante fra letture fornite e letture reali, che in genere è piccolissima, se non nulla. Per calibrare l’offset, colleghiamo il piedino ground con ad es. il piedino A0 e guardiamo sul monitor seriale la tensione fornita da Arduino a tale piedino. Supponiamo che la tensione indicata sia 0,01 V. Allora nello sketch di Arduino dovremo sottrarre questo valore. A questo punto possiamo procedere alla calibrazione della tensione.

La necessità della calibrazione dell’offset in Arduino.

Per calibrare la tensione via software, forniamo ad Arduino, ad esempio al piedino A0, la tensione di 5,00 V fornita da un alimentatore stabilizzato. Guardiamo sul monitor seriale la lettura fornita da Arduino. Ad esempio, supponiamo di leggere 4,97 V. Allora il fattore moltiplicativo da usare nello sketch è 5 : 4,97 = 1,0060362 (usa 7 cifre decimali). Con questa correzione, quando Arduino ci fornirà la misurazione di una tensione, il valore indicato sarà corretto. Nel nostro caso, 4,97  x 1,0060362 = 5,00 V.

La necessità della calibrazione del guadagno in tensione in Arduino.

Per calibrare la tensione via hardware, dobbiamo semplicemente alimentare Arduino dall’esterno tramite il collegamento diretto al pin 5 V, così che il regolatore di tensione di Arduino (che non è calibrato) venga bypassato. In pratica, dovremo collegare direttamente ad Arduino la tensione stabilizzata di 5 V fornita da un alimentatore stabilizzato da banco fornito (necessariamente) di regolazione fine. Ricordo che la tensione deve stare tra 4,5 e 5,5 V (pena il danneggiamento irreversibile di Arduino).

Questo sistema è un po’ rischioso per la scheda, evidentemente. Tuttavia, se non abbiamo bisogno di una calibrazione ultra precisa, alimentando Arduino dall’esterno all’ingresso DC con il connettore tondo fornendo 7,5 V con un alimentatorino universale, farà sì che Arduino fornisca al piedino di 5 V una tensione di almeno 4,98 V, con un errore quindi dell’ordine dello 0,4 %, che per la maggior parte degli utilizzi di un dilettante – anche per i propri esperimenti – si può considerare accettabile.