La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... ·...

128

Transcript of La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... ·...

Page 1: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino
Page 2: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

La Conversione Analogico/Digitale conArduino

Prima edizione: Febbraio 2016Copyright © 2016 Giulio Tamberi

Ad eccezione degli esempi di codice, nessuna parte del presente libro può essere riprodotta,memorizzata in un sistema che ne permetta l’elaborazione, né trasmessa in qualsivoglia formae con qualsivoglia mezzo elettronico o meccanico, né può essere fotocopiata, riprodotta oregistrata altrimenti, senza previo consenso scritto dell’autore, tranne nel caso di brevicitazioni contenute in articoli di critica o recensioni. La presente pubblicazione contienele opinioni dell’autore e ha lo scopo di fornire informazioni precise e accurate.L’elaborazione dei testi, anche se curata con scrupolosa attenzione, non può comportarespecifiche responsabilità in capo all’autore e/o all’editore per eventuali errori oinesattezze.Nomi e marchi citati nel testo sono generalmente depositati o registrati dalle rispettiveaziende. L’autore detiene i diritti per tutte le fotografie, i testi e le illustrazioni checompongono questo libro, salvo quando diversamente indicato.

Page 3: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

INDICEINTRODUZIONE

Note

L’ADC DELL’ATmega328

I microprocessori delle schede Arduino

Microprocessori a 8-bit

Microprocessori a 32-bit

Il convertitore Successive Approximation Register (SAR)

GLI INGRESSI

Il multiplexer interno e la funzione analogRead()

L’intervallo delle tensioni in ingresso

Ridurre le tensioni in ingresso

Partitore di tensione

Ottimizzare l’intervallo delle tensioni di ingresso

Amplificazione del segnale di ingresso

Riduzione della tensione di riferimento

Buffer di ingresso digitale

Resistori di pull-up interni

L’impedenza di uscita del segnale in ingresso

LA RISOLUZIONE E LE CIFRE SIGNIFICATIVE

La risoluzione

Come migliorare la risoluzione?

Stimare la tensione

1023 oppure 1024?

Ottimizzazione dell’errore di quantizzazione (Half LSB Adder)

Le cifre significative

IL RIFERIMENTO DI TENSIONE DEL CONVERTITORE

Le possibili impostazioni della funzione analogReference()

Modalità DEFAULT

Modalità EXTERNAL

Modalità INTERNAL

Le tensioni disponibili sulla scheda Arduino

USB POWER SUPPLY

LDO 5V

On-board 3.3V

Esempio con AREF

L’ACCURATEZZA DELLA CONVERSIONE

La stabilità del riferimento di tensione

Page 4: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

L’accuratezza sulla stima della tensione in ingresso

L’accuratezza sulla stima della misura da un sensore

Esempio della misura della temperatura

Esempio della misura dell’umidità relativa

La calibrazione del riferimento di tensione dell’ADC

Misura esterna con un voltmetro

Misura interna riferita alla tensione interna di bandgap

Misura interna riferita a una tensione esterna

La calibrazione dell’ADC

IL CAMPIONAMENTO

Il teorema del campionamento

La frequenza di campionamento con l’ATmega328

Il tempo di conversione

La scelta della frequenza di campionamento

Il campionamento uniforme

LA TECNICA DELL’OVERSAMPLING

Massimo oversampling

Oversampling vs. rumore

Oversampling vs. velocità di variazione

Le cifre significative in caso di oversampling

La frequenza di campionamento con oversampling

Filtraggi avanzati per l’oversampling

Filtri a media ponderata

Svantaggi nell’utilizzo della finestra mobile

Filtri a mediana

BIBLIOGRAFIA

CONTATTI

Page 5: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

INTRODUZIONEIl principale merito di Arduino è aver reso accessibile a una largabase di persone uno strumento versatile, di semplice utilizzo e abasso costo per realizzare progetti anche senza possedere unaspecifica preparazione tecnica in elettronica o nella programmazionedi microcontrollori. Questo lo ha consacrato all’attuale successointernazionale presso quella variopinta comunità di designer,inventori e appassionati che siamo ormai abituati a indicare con iltermine di Makers.Accanto alla documentazione ufficiale, il progetto Arduino hagenerato nel corso degli anni moltissimi contenuti sul web, tra cuiil Forum, il Playground e il Project Hub sul sito Arduino stesso, maanche le numerose pagine sui social network come Facebook (ArduinoProjects, Arduino Arts, ecc.) e Google+ (Arduino Basics, XtremeArduino, ecc.), i vari canali di Instructables (Arduino, ArduinoProjects, ecc.) e le aree dedicate su Dangerous Prototypes, SparkFunElectronics, Adafruit, Reddit e Flickr.La popolarità di Arduino risiede proprio in questa fertile webcommunity i cui confini digitali sono in costante espansione graziealla creazione di nuovi contenuti declinati su applicazionitecnologiche sempre più diversificate (domotica, stampa 3D,droni/modellismo, fotografia, ecc.).Tuttavia, accanto alla possibilità di consultare liberamente questadocumentazione condivisa, resta aperta la questionedell’attendibilità delle informazioni, poiché in questi spazivirtuali è possibile pubblicare liberamente dei contenuti percontribuire alla discussione collettiva, ma per quanto le intenzionipossano essere nobili non ne sono sempre garantite l’esattezza el’affidabilità. In particolare, quello del convertitoreanalogico/digitale (ADC) è appunto uno degli argomenti su cui siregistrano maggiori imprecisioni e grossolani errori che tendonopurtroppo a diffondersi rapidamente in rete, rimanendo consultabilinel tempo e riverberandosi negativamente nel codice (sketch) e neglischemi elettrici utilizzati da altri utenti. In molti casi questoargomento potrebbe essere considerato un problema minore, ma stadiventando centrale da quando la famiglia delle schede Arduino hainiziato a diffondersi in applicazioni prototipali avanzate,specialmente nelle aree emergenti delle reti di sensori intelligenti(Internet of Things) e delle tecnologie indossabili (Wearables).

Page 6: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Questa guida nasce da esperienze raccolte progettando con le schedeArduino e illustra le possibilità per utilizzarne al meglio l’ADC,con una particolare attenzione per quelle più diffuse basate sulmicroprocessore Atmel ATmega328, come la Arduino UNO. Conriferimenti teorici ed esempi applicativi, offre una base persviluppare progetti più accurati e migliorare quelli già realizzati,specialmente nell’ambito delle acquisizioni di segnali da sensorianalogici.Consultando questa guida troverete la risposta a domande comequeste: Quanti segnali analogici può acquisire contemporaneamente unascheda Arduino? È vero che alcune schede Arduino basate sul microprocessoreATmega328 consentono due ulteriori ingressi single-ended? Qual è la massima tensione consentita in ingresso all’ADC di unascheda Arduino UNO? E nel caso di Arduino ZERO? È possibile in qualche modo acquisire segnali la cui tensione siamaggiore di quella massima consentita in ingresso all’ADC di unascheda Arduino? Qual è la risoluzione di tensione dell’ADC di una scheda ArduinoUNO? E qual è la sua dipendenza dalla tensione di riferimento? Nelle formule di conversione della tensione nel codice è piùcorretto utilizzare il valore 1023 o 1024? È ragionevole eseguire misure di tensione con una risoluzionedell’ordine dei microVolt con una scheda Arduino UNO? Quante sono le cifre decimali significative su cui ha sensovisualizzare le acquisizioni dell’ADC? In seguito a un cambiamento del riferimento di tensione con lafunzione analogReference(), quante conversioni dell'ADC occorrescartare prima di poterle considerare attendibili? È possibile aumentare la risoluzione dell’ADC di una schedaArduino? Si ottengono acquisizioni più accurate con una scheda Arduino UNOoppure con Leonardo, Yún o Mega? Utilizzando schede Arduino con sensori di temperatura analogici, èpossibile misurare temperature con un’accuratezza di ±0.1°C? Quanto incide l’accuratezza della tensione di alimentazione sullemisure dell’ADC di una scheda Arduino? È sufficiente acquisire un campione ogni secondo per monitorare latemperatura ambiente? Qual è il tempo di conversione effettivo di una scheda Arduino? È possibile utilizzare Arduino per acquisire segnali audio? In cosa consiste la tecnica dell’oversampling?

Page 7: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Ha senso implementare un oversampling a 13-bit con una schedaArduino UNO?

Page 8: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

NoteSe vi siete avvicinati a questa guida molto probabilmente avrete giàfamiliarità con Arduino e per questo motivo non sono state riportatele indicazioni su come muovere i primi passi con questa scheda einstallarne l’ambiente di sviluppo integrato IDE (IntegratedDevelopment Environment), per le quali è comunque possibile fareriferimento alle letture consigliate nella bibliografia oall’indirizzo Getting Started with Arduino.Le illustrazioni dei circuiti sulle breadboard sono state realizzategrazie a Fritzing.Le analisi con il metodo Monte Carlo sono state eseguite con OracleCrystal Ball.Per una maggiore praticità per il lettore, tutti gli sketch presentiin questo testo sono disponibili online tramite degli appositi linkad Arduino Web Editor. È possibile distribuirli, modificarli,ottimizzarli e utilizzarli, anche commercialmente. La citazionedell’autore è gradita, ma non indispensabile.Per indicare il convertitore analogico/digitale in letteratura siutilizzano diversi termini (Analog-to-Digital Converter,Analog/Digital Converter, ecc.) e acronimi (ADC, A/D, A-D, A2D). Inquesto testo si fa riferimento all’acronimo ADC (Analog-to-DigitalConverter). Inoltre, per ragioni di semplicità, si impiega iltermine microprocessore anche laddove sarebbe più pertinentericorrere al termine microcontrollore.

Page 9: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

L’ADC DELL’ATmega328I microprocessori delle schede ArduinoIl seguente elenco riassume i principali microprocessori utilizzatinelle schede Arduino e Arduino-compatibili: Microprocessori a 8-bitAtmel AVR: ATmega328: è presente sulla celebre scheda Arduino/Genuino UNO esulle schede Duemilanove, Pro e Pro Mini, Nano 3.0, Fio, LilyPad (ele varianti Simple e SimpleSnap), Bluetooth, Ethernet, SquareWear2.0, Sparkfun RedBoard, Seeeduino 4.0, Iteaduino UNO, AVR.duino U+,Olimexino-328, Eleven, Fishino UNO, Arduino UNO WiFi e AdafruitMETRO 328 ATmega1280: è presente sulla versione Arduino/Genuino Mega ATmega2560: si trova sulle schede Arduino/Genuino Mega 2560 e ADK ATmega32u4: è presente sulle versioni Arduino/Genuino Micro,Leonardo, Leonardo ETH, Yún, Yún Mini, LilyPad USB, Industrial 101,Qduino Mini, Bare Conductive Touch Board, Olimexino-32U4 e AdafruitFeather 32u4 Adalogger Microprocessori a 32-bitAtmel ARM Cortex: ATSAMD21: è il microprocessore Cortex M0+ delle schedeArduino/Genuino ZERO, M0, M0 PRO, Tian, Adafruit Feather M0 ed ècontenuto anche nel modulo System on Chip (SoC) Atmel ATSAMW25 dellascheda Arduino/Genuino MKR1000 ATSAM3X8E: è il microprocessore Cortex M3 della scheda Arduino DUETexas Instruments ARM Cortex: Sitara AM335x: è il microprocessore Cortex A8 della scheda ArduinoTREIntel Quark System on Chip (SoC): Quark X1000: è il microprocessore x86 delle schede Intel Galileo eIntel Galileo Gen 2 Quark SE Curie: è presente sulla scheda Arduino/Genuino 101 Tuttavia, la maggior parte delle schede Arduino e Arduino-compatibili presenti oggi sul mercato utilizza i microprocessoriAtmel AVR e, principalmente, l’ATmega328. Ed è appunto sul suo

Page 10: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

convertitore analogico/digitale che si concentra l’analisi di questaguida, con un particolare riferimento alla sua implementazione sullascheda Arduino UNO, che è di fatto la più popolare e diffusa ditutta la famiglia Arduino.

Page 11: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Il convertitore Successive ApproximationRegister (SAR)L’ADC del microprocessore ATmega328 è basato su un’architettura ditipo Successive Approximation Register (SAR) a 10-bit, che sebbenesia più lenta rispetto ad altri convertitori (come, ad esempio,quelli di tipo Flash) è piuttosto comune nei microcontrolloricommerciali per l’interfaccia semplice, la linearità e l’efficienzadei consumi. L’architettura SAR utilizza, infatti, un comparatoreche riceve in ingresso il segnale da convertire e un segnalegenerato internamente da un convertitore digitale-analogico (DAC,Digital-to-Analog Converter) e, seguendo una sorta di algoritmo diricerca binaria, consente di approssimare la tensione in ingresso,dal bit più significativo a quello meno significativo, da cui ilnome “ad approssimazioni successive”. Ad ogni ciclo del clockinterno all’ADC, l’uscita del DAC converge verso il valore delsegnale in ingresso e il risultato è memorizzato nel registro diuscita. Questa operazione di conversione richiede un certo numero dicicli, che aumenta al crescere del numero di bit del convertitore.La durata di ciascun ciclo è comunque limita dai tempi dicommutazione della logica interna e del DAC.Le principali caratteristiche dell’ADC dell’ATmega328 sono comunianche agli ADC degli altri microprocessori Atmel AVR, tutti infattibasati sulla stessa architettura SAR a 10-bit. In sintesi, leprincipali differenze dei microprocessori ATmega1280, ATmega2560 eATmega32u4 rispetto all’ATmega328 sono: un maggior numero di ingressi single-ended (16 su ATmega1280/2560;12 su ATmega32u4) la presenza anche di ingressi differenziali (14 suATmega1280/2560, di cui 4 con guadagno opzionale di 10× 200×; 1 suATmega32u4 con guadagno opzionale di 1× 10× 40× 200×) la possibilità di impostare il riferimento di tensione internodell’ADC a 2.56V I microprocessori utilizzati invece nelle schede Arduino ZERO, DUE eTRE hanno un ADC a 12-bit e un maggior numero di ingressi (adesempio, su DUE sono presenti 12 single-ended), mentre le schedeIntel Galileo utilizzano un ADC esterno collegato al microprocessoreQuark X1000 con una porta SPI: nel caso della prima generazione sitratta di un AD7298 a 12-bit di Analog Devices con 8 ingressisingle-ended, mentre nella seconda generazione è un ADC108S102 a 10-bit di Texas Instruments con 8 ingressi single-ended.

Page 12: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino
Page 13: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fig. 1 – Il diagramma a blocchi dell’ATmega328 (in giallo sono evidenziati i modulidell’ADC).

Page 14: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

GLI INGRESSINella maggior parte dei casi pratici i sistemi realizzati conArduino utilizzano in ingresso uno, due o al più tre segnalianalogici (temperature, umidità relativa di ambienti, tensioni dibatterie, segnali da sensori di pressione (piezoelettrici),forza/flessione (estensimetri), ecc.).Il microprocessore ATmega328 è comunque dotato di un convertitoreADC, che nella versione con package PDIP a 28 pin consente fino a 6ingressi, mentre nelle versioni SMD a 32 pin (nei package TQFP andQFN/MLF) offre ulteriori 2 ingressi. In tutti i casi, si tratta diingressi per segnali di tipo single-ended (ovvero in cui la tensioneè riferita al pin GND). Il convertitore ADC dell’ATmega328, infatti,non ha ingressi per segnali differenziali, ma è comunque possibilericorrere a un amplificatore operazionale differenziale esterno comeil diffuso LM358, che è disponibile anche nel pratico package DIP a8-pin e alimentabile direttamente con la stessa tensione di 5Vnormalmente utilizzata per la scheda Arduino.Nel caso invece occorra acquisire un numero di ingressi maggiore diquelli presenti su Arduino, è possibile ricorrere a un multiplexeresterno come il CD74HC4067 che con 4 pin di controllo, collegabiliai pin digitali di Arduino, consente di gestire fino a 16 ingressi.

Page 15: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fig. 2 – Le versioni di package dell’ATmega328 (in giallo sono evidenziati i pin dell’ADC).

Page 16: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

PIN (ATmega328) PIN (Arduino) PackageADC0 A0

Tutti

ADC1 A1ADC2 A2ADC3 A3ADC4 A4ADC5 A5ADC6 A6 Solo 32-pin TQFP e QFN/MLFADC7 A7

In realtà, confrontando le schede Arduino e Arduino-compatibilibasate sull’ATmega328 con package TQFP o QFN/MLF, i due ingressiaggiuntivi sono presenti soltanto sulle schede Arduino Pro, ArduinoNano 3.x, Arduino Bluetooth, Seeeduino 3.0 e Olimexino-328.

Fig. 3 – La scheda Arduino UNO con evidenziati i pin che riguardano l’ADC.

Page 17: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fig. 4 – La scheda Seeeduino 3.0 con evidenziati i pin 6 e 7 di ulteriore ingresso all’ADC.

Fig. 5 – La scheda Olimexino-328 con evidenziati i pin 6 e 7 di ulteriore ingresso all’ADC.

Page 18: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Il multiplexer interno e la funzioneanalogRead()Per acquisire una tensione in ingresso all’ADC, Arduino utilizza lafunzione analogRead() che seleziona il pin di ingresso e comanda laconversione. Tutti gli ingressi analogici sono gestiti da unmultiplexer che, in conformità a quanto previsto dall’utente nellosketch, li connette all’unico convertitore ADC interno che puòconvertire soltanto un ingresso per volta.Ad esempio, una scheda Arduino UNO programmata con il seguentesketch acquisisce ogni secondo il segnale sul pin A0 e ne stampa sulmonitor seriale il valore convertito su 10-bit: byte analogPin = 0; // set the analog input pinunsigned int ADC_value = 0; // variable storing the ADC reading void setup() Serial.begin(9600); // baud rate for the serial communication void loop() ADC_value = analogRead(analogPin); // read the analog input Serial.println(ADC_value); // print the ADC reading delay(1000); // wait for a second Per la variabile analogpin che definisce l’ingresso per l’ADC èstato utilizzato il tipo byte che consente di memorizzare numeriinteri postivi da 0 a 255, quindi ampiamente sufficiente per tuttele schede Arduino.Nel caso si desideri campionare più ingressi in parallelo (sensoridi diverso tipo, uscite multiple di uno stesso sensore, segnaliaudio relativi a più canali, ecc.) questi saranno in realtàcampionati in modo sequenziale, producendo così uno sfasamentotemporale (generalmente indicato in letteratura come channel-to-channel skew) che dipende sia dal tempo di conversione intrinsecodell’ADC e sia dal tipo di operazioni che sono programmate nellosketch dall’utente. In altre parole, per via della particolarearchitettura, non si ha la contemporaneità delle conversioni suivari ingressi analogici. Nella maggior parte dei casi questo noncostituisce un problema, ma in alcune applicazioni (ad esempio, consensori high-speed o nel caso di analisi in frequenza su campioniprovenienti da diversi canali) occorre tenerne conto per evitare

Page 19: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

grossolani errori nella fase dell’elaborazione dei dati, per cuipotrebbe essere necessario compensare i ritardi nel codice.Ad esempio, una scheda Arduino UNO programmata con il seguentesketch acquisisce ogni secondo i segnali presenti sui pin A0, A1,A2, A3 e ne stampa su una riga del monitor seriale il relativovalore convertito su 10-bit: unsigned int ADC_value_0 = 0; // variable storing the ADC reading for pin A0unsigned int ADC_value_1 = 0; // variable storing the ADC reading for pin A1unsigned int ADC_value_2 = 0; // variable storing the ADC reading for pin A2unsigned int ADC_value_3 = 0; // variable storing the ADC reading for pin A3 void setup() Serial.begin(9600); // baud rate for the serial communication void loop() ADC_value_0 = analogRead(0); // read the input on analogPin A0 ADC_value_1 = analogRead(1); // read the input on analogPin A1 ADC_value_2 = analogRead(2); // read the input on analogPin A2 ADC_value_3 = analogRead(3); // read the input on analogPin A3 Serial.print(ADC_value_0); // print the ADC reading for pin A0 Serial.print("\t"); // prints a tab Serial.print(ADC_value_1); // print the ADC reading for pin A1 Serial.print("\t"); // prints a tab Serial.print(ADC_value_2); // print the ADC reading for pin A0 Serial.print("\t"); // prints a tab Serial.println(ADC_value_3); // print the ADC reading for pin A0 and a carriage return delay(1000); // wait for a second Quando si acquisiscono più ingressi, specialmente se provenienti dasensori con impedenza di uscita elevata, è sempre meglio scartare laprima lettura dopo una chiamata della funzione analogRead() su unpin diverso; infatti, la prima lettura potrebbe essere errata acausa del transitorio necessario affinché l’uscita del multiplexersia andata completamente a regime. Una possibile soluzione,facilmente implementabile nel codice, consiste nel definire unanuova funzione personalizzata sulla base della analogRead() in cuiuna variabile statica interna tenga traccia dell’ultimo pinutilizzato. ESERCIZIO: Si invita il lettore a definire questa nuova funzionepersonalizzata e a utilizzarla nel codice per convertire

Page 20: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

sequenzialmente quattro segnali analogici collegati in ingresso suipin A0, A1, A2 e A3 di una scheda Arduino UNO.

Page 21: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino
Page 22: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fig. 6 – Il diagramma a blocchi del convertitore analogico/digitale dell’ATmega328.

Page 23: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

L’intervallo delle tensioni in ingressoL’ADC dell’ATmega328 è di tipo unipolare, cioè accetta tensioni iningresso positive comprese tra 0V e la tensione di fondoscala, che èpari alla tensione di riferimento (VREF) dell’ADC stesso. Adesempio, su Arduino UNO nelle condizioni di default VREF = 5Vl’intervallo di tensione consentito è tra 0V e 5V. Applicare unatensione al di fuori da questo intervallo potrebbe danneggiareirreversibilmente il microprocessore. ATTENZIONE: Nelle schede Arduino alimentate a 3.3V (come la ZERO, laDUE e la TRE), la massima tensione consentita in ingresso all’ADC èappunto 3.3V. Occorre quindi tenerne conto quanto si riutilizzanocircuiti progettati per Arduino UNO per gestire segnali di ingressocon tensioni inferiori a 5V ma maggiori di 3.3V.

Page 24: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Ridurre le tensioni in ingressoPartitore di tensioneNel caso in cui i segnali di ingresso siano tensioni positive, macon un valore massimo maggiore della tensione VREF dell’ADC, èpossibile utilizzare un partitore di tensione come mostrato nellafigura seguente:

Fig. 7 – Un esempio di partitore di tensione.

In cui: VOUT = VIN × R2 / (R1 + R2) I valori delle resistenze R1 e R2 devono essere scelti in modo taleche la massima tensione del segnale d’ingresso corrisponda al piùalla tensione VREF dell’ADC, ovvero: VREF = VIN_MAX × R2 / (R1 + R2) Da cui si ricava il rapporto: R1 / R2 = VIN_MAX / VREF − 1 Ad esempio, volendo scalare un intervallo di tensioni da 0÷12V a

Page 25: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

0÷5V: R1 / R2 = 12V / 5V – 1 = 1.4 Per la scelta dei valori delle resistenze tali da soddisfare questorapporto sono possibili molte possibilità. Tuttavia, bisognaconsiderare alcuni vincoli.Innanzitutto, occorre non sovraccaricare la sorgente del segnale VIN(ad esempio, nel caso di una tensione da una batteria questapotrebbe scaricarsi oppure un sensore potrebbe avere comportamentianomali nella sua caratteristica di uscita), ovvero: R1 + R2 >> RIN Dove RIN indica la resistenza di uscita della sorgente del segnaleVIN che, nella maggior parte delle applicazioni, è compresa traqualche decimo di Ohm e alcune decine di Ohm, per cui sonocertamente adeguati valori tali che: R1 + R2 > 1kΩ D’altra parte però, scegliendo dei valori molto elevati, potrebbeverificarsi che la resistenza equivalente di uscita su VOUT siamaggiore di quella consentita dall’ingresso dell’ADC.Secondo il datasheet, l’ADC dell’ATmega328 è ottimizzato perricevere in ingresso segnali provenienti da una sorgente la cuiimpedenza di uscita sia al massimo 10kΩ, ovvero: R1 // R2 = R1R2 / (R1 + R2) < 10kΩR1R2 < (R1 + R2) × 10kΩ < 1kΩ × 10kΩ = 10MΩ2

Quindi riassumendo i vincoli che occorre rispettare sono: R1 + R2 > 1kΩR1R2 < 10MΩ2

È inoltre opportuno scegliere le resistenze con una piccolatolleranza poiché il rapporto tra i loro valori inciderà nellacatena dell’accuratezza complessiva della conversioneanalogico/digitale.

Page 26: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Considerando la serie standard E96 (con una tolleranza pari a ±1%),una scelta compatibile per questo esempio è: R2 = 1kΩR1 = 1.4kΩ Ovviamente utilizzando la serie standard E192 (con tolleranze di±0.5%, ±0.25% e ±0.1%) si otterrebbe un risultato più accurato macon maggiori costi e difficoltà nella reperibilità. ESERCIZIO: Calcolare i valori delle resistenze R1 e R2 della serieE192 nel caso occorra scalare la massima tensione da VIN_MAX = 12V aVREF = 1.1V.

Page 27: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Ottimizzare l’intervallo delle tensionidi ingressoPer minimizzare l’effetto dell’errore di quantizzazione occorresfruttare quanto più possibile tutto l’intervallo delle tensioniconsentite in ingresso all’ADC. A questo scopo è possibilecondizionare i segnali di ingresso in modo da renderli compatibilicon l’ADC.Ad esempio, supponiamo che l’ADC riceva in ingresso il segnale da unsensore analogico la cui tensione sia compresa tra 0V e VIN_MAX <VREF. Si possono seguire sostanzialmente due strategie,implementabili singolarmente o anche in modo combinato: Amplificazione del segnale di ingressoIn questo caso si amplifica il segnale da convertire di un fattorequanto più possibile uguale a VREF / VIN_MAX. Ad esempio, utilizzandoun amplificatore non invertente il cui guadagno sia impostato come: 1 + R2 / R1 = VREF / VIN_MAX

Fig. 8 – Un esempio di un amplificatore operazionale in configurazione non invertente.

Nel caso in cui la tensione minima del sensore VIN_MIN sia diversa dazero, occorrerà anche eseguire una traslazione di livello per

Page 28: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

adattare il fondoscala alla tensione minima dell’ADC: VOUT = V2 × (1 + R2 / R1) × R4 / (R3 + R4) – V1 × R2 / R1 Per cui: R4 / R1 × (R1 + R2) / (R3 + R4) = VREF / VIN_MAXV1 × R2 / R1 = VIN_MIN E nel caso particolare in cui si scelga opportunamente R1 // R2 = R3// R4 allora: R2 / R1 = VREF / VIN_MAX(R2 / R1) × V1 = VIN_MIN → V1 = (VIN_MAX × VIN_MIN) / VREF

Fig. 9 – Un esempio di un amplificatore operazionale in configurazione differenziale.

Riduzione della tensione di riferimentoIn questo caso si sceglie la minima VREF in modo che il massimovalore del segnale in ingresso all’ADC sia inferiore ad essa. Adesempio, nell’ipotesi di utilizzare un sensore di temperatura LM35per misurare una temperatura ambiente compresa tra 0°C e 50°C, è

Page 29: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

possibile ridurre la tensione di riferimento dell’ADC da 5V alriferimento interno di 1.1V. Infatti, con 50°C l’uscita del sensoreè: 50°C × 10mV/°C = 500mV < 1.1V Se l’uscita del sensore fosse 1.1V corrisponderebbe a unatemperatura di 110°C.

Page 30: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Buffer di ingresso digitaleI pin di ingresso analogici di Arduino A0-A5 possono in realtàessere programmati anche come pin I/O digitali, e per questo motivohanno un buffer interno per le funzioni digitali. Quando si desideraimpiegarli soltanto come ingressi analogici è opportunodisabilitarne i relativi buffer digitali sia per ridurre ilcrosstalk del rumore prodotto dai circuiti digitali ma anche perlimitare i consumi di corrente e per non sovraccaricare eventualisegnali in ingresso nel caso di elevati carichi resistivi (a causadella capacità di ingresso dei buffer digitali).Per disabilitare i buffer digitali occorre configurare i relativibit del registro Digital Input Disable Register (DIDR0), inserendole seguenti righe di codice all’interno della sezione void setup(): void setup() //… bitSet(DIDR0, ADC0D); // disable digital input on ADC0 bitSet(DIDR0, ADC1D); // disable digital input on ADC1 bitSet(DIDR0, ADC2D); // disable digital input on ADC2 bitSet(DIDR0, ADC3D); // disable digital input on ADC3 bitSet(DIDR0, ADC4D); // disable digital input on ADC4 bitSet(DIDR0, ADC5D); // disable digital input on ADC5 //…

Fig. 10 – Il registro Digital Input Disable Register (DIDR0).

Gli ingressi di Arduino A6 e A7 (che corrispondono ai pin ADC6 eADC7 dell’ATmega328) non hanno i buffer di ingresso digitale equindi non richiedono di disabilitare i relativi bit nel registroDIDR0.Nel caso in cui alcuni dei pin A0-A5 di Arduino siano utilizzaticome uscite digitali è importante che questi siano gestitiopportunamente nello sketch in modo che non si verifichinocommutazioni di uscita mentre è in corso una conversioneanalogico/digitale su uno degli altri pin eventualmente configurato

Page 31: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

come ingresso analogico. Infatti, il rumore dovuto alle commutazionidelle uscite digitali interferirebbe con l’accuratezza dellaconversione del segnale analogico di ingresso.Una soluzione suggerita al lettore è quella di introdurre un piccoloritardo nel codice tra la commutazione di un segnale di uscita el’acquisizione di un segnale analogico di ingresso.

Page 32: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Resistori di pull-up interniCiascuno dei pin A0-A5 di Arduino (ADC0-ADC5 dell’ATmega328) ha unpull-up interno abilitabile di valore compreso tra 20kΩ e 50kΩ. Ipin A6-A7 (ADC6 e ADC7 dell’ATmega328) non hanno invece alcun pull-up interno.

Fig. 11 – Lo schema equivalente di un pin di ingresso dell’ADC.

La corrente di perdita dovuta alle protezioni d’ingresso sul pin ètrascurabile per le applicazioni tipiche a temperatura ambiente.La capacità interna di 14pF è dovuta in parte al multiplexer masoprattutto al condensatore interno di Sample and Hold (S/H).È importante che il pin di ingresso dell’ADC sia configurato comeingresso in alta impedenza. Infatti, nel caso in cui il suo pull-upinterno fosse abilitato, formerebbe un partitore di tensione conl’impedenza di uscita del segnale da acquisire riducendo cosìl’accuratezza della conversione. Inoltre, l’assorbimento di correntedall’alimentazione sul pull-up inciderebbe, anche se in piccolaquota, sui consumi.

Page 33: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fino alla versione Arduino IDE 1.0 per gestire i pull-up interni eranecessario ricorrere a due distinti comandi nel codice. Ad esempio,per abilitare la resistenza di pull-up occorreva prima configurareun pin come INPUT con la funzione pinMode() e poi impostare larelativa uscita come HIGH con il comando digitalWrite(). Dallaversione Arduino IDE 1.0.1 il software può gestire la configurazionedei pull-up interni con il solo comando pinMode(). Ad esempio, perconfigurare il pin A0 come ingresso e disabilitarne il relativopull-up interno è sufficiente eseguire il seguente comando: pinMode(A0, INPUT); // set pin A0 to input and the internal pull-up is not enabled Fortunatamente di default tutti i pin A0-A5 di Arduino (ADC0-ADC5dell’ATmega328) sono configurati come ingressi con il pull-upinterno disabilitato e quindi non è necessaria alcuna impostazioneinziale nella sezione void setup().

Page 34: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

L’impedenza di uscita del segnale iningressoIl convertitore dell’ATmega328 è ottimizzato per ricevere iningresso segnali provenienti da una sorgente la cui impedenza diuscita sia sufficientemente bassa. Secondo il datasheet Atmel,questa deve essere al massimo di 10kΩ. Infatti, in presenza disorgenti a impedenza maggiore, per via del carico RC interno all’ADC(ovvero, con riferimento allo schema precedente, RADC che è compresatra 1kΩ e 100kΩ e CADC che ha un valore di ≈ 14pF) il tempo ditrasferimento della carica al circuito di Sample and Hold potrebberisultare eccessivo per garantire una corretta conversione delsegnale.Per acquisire segnali da sensori a impedenza di uscita maggiore di10kΩ si suggerisce l’impiego di amplificatori operazionali low noisein configurazione voltage follower in modo da diminuire l’impedenzadi uscita e mantenere il livello del segnale.

Page 35: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

LA RISOLUZIONE E LE CIFRESIGNIFICATIVELa risoluzioneLa conversione analogico/digitale è costituita da due fasisequenziali: il campionamento e la quantizzazione.Campionare un segnale significa registrarne il valore a certiistanti, normalmente a intervalli di tempo di durata costante. Laquantizzazione è il processo successivo per cui i campioni sonoapprossimati con numeri interi, la cui codifica binaria è infinememorizzata in appositi registri accessibili dall’utente. Il numerodi livelli su cui si opera l’approssimazione dei valori campionati è2N, dove N indica il numero di bit dell’ADC. Su questi livelli èmappato l’intervallo delle tensioni accettabili in ingresso all’ADC.Nel caso dell’ATmega328, l’ADC è di tipo unipolare, cioè consente iningresso tensioni positive comprese tra 0V e la tensione difondoscala, che è pari alla tensione VREF dell’ADC stesso. In questocaso la quantizzazione è detta lineare poiché tutti gli intervallihanno la stessa ampiezza che determina la cosiddetta risoluzione ditensione dell’ADC, ovvero la più piccola variazione di tensione iningresso che causa la variazione di 1 bit del valore convertito inuscita: ΔV = VREF / 2N

Nel caso dell’ADC a 10-bit di Arduino, considerando la tensione VREFdi default pari a 5V, la risoluzione di tensione è: ΔV = VREF / 2N = 5V / 1024 = 4.883mV ≈ 4.9mV Questo significa che a fronte di una variazione di 4.9mV nellatensione di ingresso, l’uscita digitale del convertitore cambia di 1bit. Questa risoluzione è più che sufficiente nella maggior partedelle applicazioni, ma è opportuno tenerne conto in relazione allagrandezza che si desidera misurare.Ad esempio, nel caso in cui Arduino sia collegato a un sensore ditemperatura analogico con guadagno (spesso indicato anche comesensibilità) G = 10mV/°C, si avrebbe una risoluzione di temperatura

Page 36: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

di: ΔT = ΔV / G = 4.883mV / 10mV/°C ≈ 0.49°C Ovvero, a fronte di una variazione di temperatura di 0.49°C,l’uscita del convertitore cambia di 1 bit. Questa risoluzione nonsarebbe tuttavia adeguata nel caso in cui occorresse distinguere letemperature con una risoluzione di 0.1°C. Come migliorare la risoluzione?Per come è definita, la risoluzione migliora (ovvero diminuisce,permettendo così una conversione più fine) all’aumentare del numerodi bit (N) e/o al diminuire della tensione di riferimento (VREF).L’aumento del numero di bit comporta un miglioramento dellarisoluzione poiché aumenta il numero di livelli su cui l’intervallodi tensione di ingresso è suddiviso. Tuttavia, da un punto di vistahardware, non è un’opzione particolarmente flessibile poiché laquasi totalità delle schede Arduino è basata su microprocessori ilcui ADC interno è fissato a 10-bit (a meno di utilizzare alcuneversioni più recenti, come Arduino DUE, con microprocessori dotatidi un ADC interno a 12-bit). Da un punto di vista software invecel’aumento del numero di bit è più facilmente perseguibile in quanto,come si vedrà più avanti, è possibile implementare nel codice lacosiddetta tecnica di oversampling che consente di aumentare“virtualmente” il numero di bit effettivi del convertitore ADC.Per quanto riguarda la diminuzione della tensione di riferimento, èpossibile utilizzare le tensioni già presenti sulle schede Arduino(ad esempio, per Arduino UNO: 3.3V e 1.1V) oppure fornirne unaesterna sul pin AREF. Tuttavia, questa non è sempre un’opzionepercorribile poiché diminuirebbe anche l’intervallo di tensioneconsentito in ingresso all’ADC e, di conseguenza, anche l’intervallodelle eventuali grandezze potenzialmente misurabili dai sensorianalogici collegati alla scheda Arduino.

Page 37: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fig. 12 – L’andamento della risoluzione di tensione al variare della tensione di riferimentoe del numero di bit.

Nel caso del convertitore dell’ATmega328 di Arduino, la funzioneanalogRead() restituisce un numero intero a 10-bit compreso appuntotra 0 e 210 − 1 = 1023, che è memorizzato su due registri ciascunodi 8-bit: ADCL che contiene gli 8 bit meno significativi e ADCH checontiene i 2 bit più significativi (gli altri 6 bit sono riempiticon zeri). Il compilatore dell’ambiente di Arduino consente digestire questi due registri come se fossero virtualmente un unicoregistro 16-bit.Su questi 1024 intervalli è mappato l’intervallo di tensionecompreso tra 0V e la tensione VREF dell’ADC, con cui l’ingressoanalogico è confrontato per produrre l’uscita digitale dellaconversione.Il valore acquisito con la funzione analogRead() è dato dallaseguente relazione: ADC = trunc[VIN / ΔV] = trunc[2N × VIN / VREF]

Page 38: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Ad esempio, con una tensione di VIN = 3.3V in ingresso all’ADC diArduino UNO si acquisisce un valore di: ADC = trunc[1024 × 3.3V / 5V] = trunc[675.84] = 675 Per effetto di questo troncamento, tutti i valori del segnale diingresso compresi all’interno di 1 LSB (Least Significant Bit) sonorappresentati dalla stessa codifica digitale. Ad esempio, nel casodi una scheda Arduino UNO con una tensione VREF di 5V, le tensioniin ingresso all’ADC comprese tra 5 × 1023 / 1024 ≈ 4.996V e 5V sonotutte acquisite con lo stesso valore ADC di 1023.Il troncamento comporta l’introduzione di un errore detto errore diquantizzazione, dovuto appunto al fatto che si considera il valorequantizzato del segnale al posto del suo valore continuo.

Page 39: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fig. 13 – La caratteristica della conversione dell'ADC a 10-bit con una tensione diriferimento di 5V.

Page 40: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Stimare la tensioneLa tensione in ingresso al convertitore può essere stimata a partiredal valore acquisito moltiplicandolo per la risoluzione di tensione: Ṽ = ADC × ΔV = ADC × VREF / 2N

Nel caso dell’ADC a 10-bit di Arduino, considerando la tensione VREFdi default pari a 5V, si ottiene: Ṽ = ADC × 5 / 210 = ADC × 5 / 1024 Ecco un esempio di sketch nel caso di una scheda Arduino UNOconfigurata per misurare una tensione in ingresso sul pin A0: byte analogPin = 0; // set the analog input pinunsigned int ADC_value = 0; // variable storing the ADC readingfloat vref = 5.0; // set the ADC voltage referencefloat voltage = 0.0; // variable storing the calculated voltage void setup() Serial.begin(9600); // baud rate for the serial communication void loop() ADC_value = analogRead(analogPin); // read the input voltage = (float)ADC_value * vref / 1024.0; // calculate the voltage Serial.println(voltage, 3); // print the voltage with 3 decimal places delay(1000); // wait for a second 1023 oppure 1024?Talvolta su Internet (e purtroppo anche in letteratura) si trovanosketch per Arduino dove la formula per la stima della tensionecontiene il numero 1023 anziché 1024. Ad esempio: voltage = (float)ADC_value * 5.0 / 1023.0; Ovviamente utilizzare 1023 non è corretto perché i livelli su cui èmappata la conversione sono in realtà 1024, ovvero da 0 a 1023.Il motivo per cui alcuni utilizzano 1023 è perché in questo modo ilrisultato della divisione è leggermente maggiore rispetto al caso di1024 e così facendo ritengono erroneamente di “recuperare” una parte

Page 41: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

del troncamento dovuta all’ADC.Utilizzare 1023 nella formula introduce un errore sistematico nellastima. Quanto incide? Molto poco, sul singolo LSB: VREF / 1023 – VREF / 1024 = VREF / (1023 × 1024) = 0.955 × 10−6 × VREF Ovvero circa 1μV per ogni Volt della tensione VREF dell’ADC (adesempio, con VREF = 5V si tratta di circa 5μV). Tuttavia, occorreconsiderare che questo errore incide maggiormente al crescere dellatensione in ingresso al convertitore e al crescere della tensione diriferimento:

Fig. 14 – L’andamento dell’errore dovuto al fattore 1023 al variare della tensione iningresso e della tensione di riferimento dell’ADC.

Ad esempio, nel caso di Arduino con VREF = 5V con una tensione diingresso pari a metà VREF, l’errore è di circa 2.5mV (ovvero, nelcaso di un sensore di temperatura con sensibilità di 10mV/°C, siavrebbe un errore di temperatura di 0.25°C), mentre a fondoscalaraddoppia e vale circa 5mV (che comporterebbe, ad esempio, un erroredi temperatura di 0.5°C).

Page 42: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Ottimizzazione dell’errore diquantizzazione (Half LSB Adder)Il valore stimato della tensione in ingresso all’ADC si calcolacome: ṼIN = ADC × ΔV = ADC × VREF / 2N = trunc[2N × VIN / VREF] × VREF / 2N

Nel caso di Arduino UNO con N = 10 e VREF = 5V si ha: ṼIN = trunc[210 × VIN / 5] × 5 / 210 = trunc[1024 × VIN / 5] × 5 /1024 Come si è detto, questa relazione introduce un errore diquantizzazione, per cui la differenza tra la tensione stimata equella effettivamente presente all’ingresso del convertitore ha ilseguente andamento:

Page 43: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fig. 15 – L’andamento dell’errore di quantizzazione dell'ADC a 10-bit con una tensione diriferimento di 5V.

La tensione stimata è sempre minore o uguale alla tensioneeffettivamente presente all’ingresso dell’ADC e il modulodell’errore di quantizzazione è compreso tra 0V e la risoluzione diingresso (o, come spesso si usa dire, è inferiore a 1 LSB): ṼIN – VIN ≤ 0 |ṼIN – VIN| ≤ ΔV = VREF / 2N = 5 / 1024 = 4.883mV ≈ 4.9mV In pratica è possibile ottenere una riduzione degli effettiassociati al disturbo di quantizzazione, facendo in modo chel’intervallo di indifferenza risulti centrato rispetto al livellonominale di quantizzazione.La tecnica è quella della cosiddetta compensazione Half LSB Adderper la quale al valore letto dall’ADC si somma un valore uguale allametà della risoluzione di ingresso (0.5 LSB). Il grafico (ovvero la

Page 44: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

funzione di trasferimento) si sposta dunque verso l’alto di 0.5 LSBe l’errore di quantizzazione risulta a valor medio nullo e dimezzatoin valore assoluto, cosicché il rumore di quantizzazione è contenutoentro una fascia simmetrica di ±0.5 LSB: |ṼIN – VIN| ≤ ΔV / 2 = 0.5 × VREF / 2N = 0.5 × 5 / 1024 = 2.441mV

Fig. 16 – La caratteristica della conversione dell'ADC a 10-bit con una tensione diriferimento di 5V e compensazione Half LSB Adder.

Page 45: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fig. 17 – Andamento dell’errore di quantizzazione dell'ADC a 10-bit con una tensione diriferimento di 5V e compensazione Half LSB Adder.

Questo metodo è facilmente implementabile nel codice sommando 0.5 alvalore acquisito dall’ADC, come nel seguente sketch: byte analogPin = 0; // set the analog input pinunsigned int ADC_value = 0; // variable storing the ADC readingfloat vref = 5.0; // set the ADC voltage referencefloat voltage = 0.0; // variable storing the calculated voltage void setup() bitSet(DIDR0, ADC0D); // disable digital input on ADC0 Serial.begin(9600); // baud rate for the serial communication void loop() ADC_value = analogRead(analogPin); // read the input voltage = ((float)ADC_value + 0.5) * vref / 1024.0; // optimize the quantization error andcalculate the voltage Serial.println(voltage, 3); // print the voltage with 3 decimal places delay(1000); // wait for a second

Page 46: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino
Page 47: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Le cifre significativeNel linguaggio C di Arduino, la più alta precisione che si puòottenere per un numero di tipo float è di 7 cifre. Pertantoeventuali altre cifre non sono significative poiché ilmicroprocessore non è comunque in grado di rappresentarle nelleoperazioni matematiche con una precisione migliore.Ad esempio, volendo definire in uno sketch la costante PI Greco, nonavrebbe senso elencarne decine di cifre come: #define PI 3.141592653589793238462643383279502884197169399 Sarebbe sufficiente limitarsi semplicemente alla definizioneseguente: #define PI 3.141592 Per lo stesso motivo, volendo definire in uno sketch una costanteper una tensione di riferimento espressa in Volt, non avrebbe sensospingersi oltre la sesta cifra decimale (ovvero limitarsi aimicroVolt): #define VREF 5.123456 Analogamente, con variabili di tipo float per tensioni espresse inVolt ha senso mostrare a schermo fino a un massimo di 6 cifredecimali (ovvero i microVolt): float my_voltage = 0.0;……Serial.println(my_voltage, 6); ATTENZIONE: È opportuno precisare che a causa di una limitazione delcompilatore avr-gcc con i microprocessori Atmel AVR a 8-bit (comeappunto l'ATmega328), l'implementazione del tipo double vienerealizzata allo stesso modo del tipo float, ovvero su 32 bits (4bytes). Quindi, sebbene negli sketch di Arduino UNO sia consentitol’utilizzo del tipo double per le variabili, queste saranno inrealtà trattate come se fossero di tipo float, senza alcun guadagnoin termini di precisione nella rappresentazione numerica. Inpresenza di schede Arduino con microprocessori a 32-bit, come nelcaso della Arduino DUE, il tipo double viene invece correttamentegestito su 64 bits (8 bytes) con il relativo miglioramento della

Page 48: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

precisione (15 cifre) rispetto al caso del tipo float. Tuttavia, è opportuno chiedersi se abbia veramente sensovisualizzare sempre tutte queste cifre decimali. Per rispondere aquesta domanda occorre fare riferimento alla risoluzione dell’ADC,che determina appunto il numero di cifre decimali visualizzabili perla grandezza che si desidera misurare. Come si è visto, nel caso diuna scheda Arduino UNO con tensione VREF = 5V, la risoluzione ditensione di ingresso è: ΔV = 4.883mV ≈ 0.005V Pertanto in uno sketch di Arduino UNO per una tensione in ingressoall’ADC rappresentata da una variabile di tipo float non ha sensoimpostarne la stampa a schermo oltre la terza cifra decimale (ovveronel caso di una tensione espressa in Volt è sufficiente limitarsi aimilliVolt), poiché le cifre decimali successive alla terza nonsarebbero significative: float my_voltage = 0.0;……Serial.println(my_voltage, 3); Al diminuire della risoluzione, il numero di cifre decimalisignificative può aumentare. Tuttavia, è importante sottolineare checon le schede Arduino UNO a 10-bit, anche supponendo di migliorarela risoluzione utilizzando il più piccolo riferimento di tensionedisponibile (ovvero 1.1V), non è possibile spingersi oltre le 3cifre decimali significative (ovvero oltre i milliVolt).Consideriamo adesso il caso in cui la tensione in ingresso all’ADCdi Arduino provenga da un sensore di temperatura analogico con unasensibilità di 10mV/°C (come nel caso dei sensori LM35 e TMP36): suquante cifre avrebbe senso visualizzare la temperatura (espressa in°C)?La tabella seguente riassume la risoluzione di temperatura e ilnumero di cifre significative al variare della tensione diriferimento nel caso dell’ADC a 10-bit di Arduino:

VREF [V]RISOLUZIONE DITENSIONE [mV]

DECIMALISIGNIFICATIVIDELLA TENSIONE

(in Volt)

RISOLUZIONE DITEMPERATURA [°C]

DECIMALISIGNIFCATIVI

DELLA TEMPERATURA(in °C)

5.0 4.883 3 0.488 1

Page 49: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

3.3 3.223 3 0.322 12.56 2.500 3 0.250 11.1 1.074 3 0.107 1

A meno di impiegare tecniche di oversampling, diversamente da quantotalvolta si trova erroneamente indicato in rete, con Arduino UNO eun sensore di temperatura con una sensibilità di 10mV/°C non hasenso visualizzare temperature in °C oltre la prima cifra decimale,qualunque sia l’alimentazione tra quelle disponibili sulla scheda(1.1V, 3.3V, 5V). Infatti, anche supponendo di utilizzare il piùpiccolo riferimento di tensione disponibile (ovvero 1.1V), larisoluzione di temperatura in ingresso sarebbe appunto: ΔT = ΔV / G = VREF / (G × 2N) = 1.1V / (10mV/°C × 1024) ≈ 0.1°C

Fig. 18 – L’andamento della risoluzione di temperatura con un sensore analogico (con unasensibilità di 10mV/°C) al variare della tensione di riferimento e del numero di bit.

Page 50: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

IL RIFERIMENTO DI TENSIONE DELCONVERTITORELe possibili impostazioni della funzioneanalogReference()La tensione di riferimento dell’ADC di una scheda Arduino basata suATmega328 può essere impostata con la funzione analogReference() intre possibili modalità di seguito illustrate. Modalità DEFAULTQuesta è la modalità predefinita per le schede Arduino e, se nondiversamente specificato nello sketch, configura automaticamenteVREF = AVCC, dove AVCC indica l’alimentazione analogica della schedaArduino che varia a seconda del microprocessore presente sullascheda stessa. Nel caso specifico dell’ATmega328 è 5V per le schedecome la UNO, Duemilanove, Pro/Pro Mini (ver. 5V), Nano 3.0 mentre è3.3V per le schede come la Fio, Pro/Pro Mini (ver. 3.3V). Nelleschede Arduino con microprocessori a 32-bit (come la ZERO, DUE o101), l’alimentazione analogica è tipicamente 3.3V. Si invitacomunque il lettore a fare sempre riferimento alle specificheelettriche della particolare scheda utilizzata.Nelle applicazioni in cui l’accuratezza della conversione rivesta unruolo critico, è possibile ridurre il rumore sull’alimentazioneanalogica AVCC filtrandola da quella digitale VCC con un filtro LCrealizzato con un induttore da 10μH e un condensatore da 100nF, comeperaltro indicato nel datasheet dell’ATmega328:

Page 51: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fig. 19 – Un esempio di filtraggio LC sull’alimentazione secondo il datasheet dell’ATmega328.

Tuttavia sulla scheda Arduino UNO, sebbene sia presente ilcondensatore da 100nF sul pin AVCC, l’alimentazione analogica AVCC ècortocircuitata con quella digitale VCC e non è quindi possibileintrodurre l’induttore di filtraggio:

Page 52: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fig. 20 – Il condensatore da 100nF sulle alimentazioni AVCC e VCC nello schema elettrico diArduino UNO.

Di tutte le schede Arduino-compatibili che ho potuto analizzare, ilfiltraggio LC sull’alimentazione AVCC è presente solo sullaOlimexino-328. In questa scheda o, in generale, nel caso siacomunque implementato un qualche tipo di filtraggiosull’alimentazione analogica, si suggerisce di preferire gliingressi A0, A1, A2, A3 (e, dove presenti, A6 e A7) poichéalimentati direttamente dal power supply analogico AVCC rispettoagli ingressi A4 e A5 che, essendo configurabili anche come pinSDA/SCL di comunicazione digitale, sono alimentati dal power supplydigitale VCC che è soggetto ai disturbi indotti dalle commutazionidei segnali digitali. Infatti, come sarà chiarito più avanti,l’accuratezza della conversione analogico/digitale dipende anchedalla stabilità dell’alimentazione dei circuiti elettronicicoinvolti.

PIN (ATmega328) PIN (Arduino) Alimentazione del PINADC0 A0 Analog (AVCC)ADC1 A1 Analog (AVCC)ADC2 A2 Analog (AVCC)ADC3 A3 Digital (VCC)ADC4 A4 Digital (VCC)ADC5 A5 Analog (AVCC)ADC6 A6 Analog (AVCC)ADC7 A7 Analog (AVCC)

Modalità EXTERNALQuesta modalità configura VREF = AREF, dove AREF indica il

Page 53: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

riferimento di tensione esterno (Analog REFerence) della schedaArduino. Per abilitarlo occorre utilizzare il seguente comandoall’interno della sezione di setup(): analogReference(EXTERNAL); ATTENZIONE: Quando si utilizza un riferimento di tensione esternooccorre sempre utilizzare il comando sopra indicato prima dichiamare la funzione analogRead() per evitare di cortocircuitareinternamente la tensione AREF con il riferimento di tensionepredefinito AVCC. Inoltre, la tensione di riferimento esterna deveessere necessariamente compresa tra 0V e AVCC per non danneggiare ilmicrocontrollore. Quando si utilizza un riferimento di tensione esterno occorreconsiderare la presenza del resistore interno di 32kΩ sul pin AREF,che insieme alla resistenza di uscita dell’alimentazione esterna,crea un partitore di tensione per cui la tensione effettivamenteutilizzata come riferimento dell’ADC è in realtà: VREF = VEXT × 32kΩ / (32kΩ + REXT)

Fig. 21 – Lo schema equivalente del pin AREF.

Ad esempio, nel caso di una tensione di riferimento esterna di 2.5Vcon una resistenza serie equivalente di 5kΩ, si otterrebbe:

Page 54: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

VREF = 2.5V × 32kΩ / (32kΩ + 2kΩ) ≈ 2.2V Per ritornare alla condizione di default con riferimento AVCC,occorre utilizzare il seguente comando: analogReference(DEFAULT); ATTENZIONE: Non bisogna mai cambiare la tensione in DEFAULT oINTERNAL quando un’altra tensione di alimentazione è collegata alpin AREF, poiché questo cortocircuito rischierebbe di danneggiareirreparabilmente il microprocessore. Il riferimento di tensione AREF può essere reso più immune al rumorecollegando esternamente un condensatore ceramico da 100nF tra i pinAREF e GND.

Fig. 22 – Un esempio di una scheda Arduino UNO con un condensatore ceramico da 100nF tra ipin AREF e GND.

Tuttavia, poiché questo condensatore non è presente sulla schedaArduino UNO, molti utenti lo aggiungono saldandolo direttamente sul

Page 55: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

retro della scheda.

Fig. 23 – Un esempio tratto da Internet di un condensatore ceramico saldato tra i pin AREF eGND sul retro di una scheda Arduino UNO.

A questo scopo, un condensatore ceramico da 100nF è già presentesulla scheda stessa nel caso di Arduino Fio, Arduino Nano 3.x,Arduino Bluetooth e Arduino Ethernet e anche in alcune schedeArduino-compatibili (come Olimexino-328, Sparkfun RedBoard,Freaduino UNO). ESERCIZIO: Valutare come esercizio l’acquisizione di una tensionecon una scheda Arduino DUE che utilizzi una tensione di riferimentoesterna di 2.048V (con accuratezza di 0.1%) prodotta da uno Zenerdella serie Texas Instruments LM4040-N. Arduino DUE è progettata peruna tensione massima di 3.3V, (non 5V come per Arduino UNO):applicare tensioni superiori a 3.3V può comportare danniirreparabili alla scheda.Si tenga presente che Arduino DUE integra un ADC a 12-bit, ma permantenere la compatibilità con le altre schede Arduino larisoluzione è configurata di default a 10-bit. È tuttavia possibilemodificarla con la funzione analogReadResolution(). Ad esempio,impostando nel codice analogReadResolution(12) la funzioneanalogRead() fornirà valori su 12-bit, compresi cioè tra 0 e 212 − 1= 4095. Modalità INTERNALQuesta modalità configura VREF al riferimento di tensione di tipobandgap interno al microprocessore, che genera una tensione nominaledi 1.1V.Per abilitare il riferimento interno occorre utilizzare il seguentecomando:

Page 56: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

analogReference(INTERNAL); Il riferimento di tensione interno è di 1.1V anche con ATmega168,mentre con ATmega8 è di 2.56V. Con Arduino Mega anziché il parametroINTERNAL occorre utilizzare INTERNAL1V1 (che configura unriferimento interno di 1.1V) o INTERNAL2V56 (che configura unriferimento interno di 2.56V).Secondo il datasheet dell’ATmega328 la tensione di riferimentobandgap ha un valore nominale di 1.1V con un’accuratezza massima di±100mV. È presente inoltre una dipendenza dalla temperatura comevisibile nei seguenti grafici:

Fig. 24 – La tensione di riferimento bandgap dell’ATmega328 al variare della temperatura.

Page 57: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fig. 25 – La tensione di riferimento bandgap dell’ATmega328P (P = calibrated bandgap) alvariare della temperatura.

La tabella seguente riassume i risultati di alcune misure eseguite atemperatura ambiente:

ALIMENTAZIONE CONDENSATORE SUAREF

VREF [V]ERRORE MEDIO

[mV] TOLLERANZA [mV]

9V (alimentatoreesterno)

100nF 1.082 −17.6 ±3.3Non presente 1.082 −17.5 ±3.4

5V (PC USB) 100nF 1.086 −13.7 ±6.0Non presente 1.087 −13.1 ±6.3

Page 58: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fig. 26 – Una misura della tensione bandgap sul pin AREF di una scheda Arduino UNO alimentatacon un alimentatore esterno da 9V, con un condensatore ceramico da 100nF sul pin AREF stesso.

Page 59: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fig. 27 – Una misura della tensione bandgap sul pin AREF di una scheda Arduino UNO alimentatacon un alimentatore esterno da 9V, senza condensatore sul pin AREF.

Page 60: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fig. 28 – Una misura della tensione bandgap sul pin AREF di una scheda Arduino UNO alimentatacon un cavo USB collegato a un PC, con un condensatore ceramico da 100nF sul pin AREF stesso.

Page 61: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fig. 29 – Una misura della tensione bandgap sul pin AREF di una scheda Arduino UNO alimentatacon un cavo USB collegato a un PC, senza condensatore sul pin AREF.

Utilizzando un alimentatore esterno sia l’errore sul valor medio cheil rumore picco-picco sono maggiori rispetto al caso diun’alimentazione da USB 5V.Il condensatore ceramico da 100nF non comporta miglioramentisensibili sul rumore picco-picco. ATTENZIONE: È importante tenere presente che, come peraltro indicatoanche nel datasheet dell’ATmega328, dopo un cambiamento delriferimento di tensione con la funzione analogReference() le primeconversioni dell’ADC che si ottengono potrebbero non essere accurateper effetto dei transitori interni al circuito di acquisizione ed èquindi buona norma scartarle.A questo proposito, l’immagine seguente mostra il comportamentodella tensione di riferimento nel passaggio da 5V (DEFAULT) a 1.1V(INTERNAL) nel caso in cui non ci sia alcun condensatore sul pin

Page 62: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

AREF della scheda Arduino:

Fig. 30 – Una misura del transitorio della tensione di riferimento da 5V (DEFAULT) a 1.1V(INTERNAL) senza alcun condensatore sul pin AREF.

Si misura un tempo di discesa 90−10% di circa 4ms che (considerandoun tempo di conversione pari a 112µs) corrisponde a circa 35conversioni dell’ADC da scartare prima di considerare il sistema diacquisizione effettivamente a regime.È comunque importante considerare che la durata di questi transitoriaumenta in presenza di condensatori esterni sul pin AREF che insiemeal resistore interno da 32kΩ determinano la costante di tempo RC chedomina il transitorio. Com’è noto, esiste una relazione per stimareil tempo di transizione a partire dalla costante di tempo: Δt ≈ 2.2 × RC

Page 63: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Ad esempio, nel caso di un condensatore da 100nF sul pin AREF siotterrebbe: Δt ≈ 2.2 × RC = 2.2 × 32kΩ × 100nF = 7ms Considerando un tempo di conversione pari a 112µs, il numero diletture da scartare prima di considerare il sistema di acquisizioneeffettivamente a regime è: 7ms / 112µs ≈ 63 È possibile scartare queste acquisizioni iniziali come èimplementato ad esempio nello sketch seguente (nel caso di unascheda Arduino UNO configurata per misurare una tensione in ingressosul pin A0): byte analogPin = 0; // set the analog input pinunsigned int ADC_value = 0; // variable storing the ADC readingunsigned int dummyreadings = 63; // set the number of initial ADC readings to discardfloat vref = 1.1; // set the ADC voltage referencefloat voltage = 0.0; // variable storing the calculated voltage void setup() bitSet(DIDR0, ADC0D); // disable digital input on ADC0 analogReference(INTERNAL); for (int i = 0; i < dummyreadings; i++) unsigned int a = analogRead(analogPin); // ADC readings to discard Serial.begin(9600); // baud rate for the serial communication void loop() ADC_value = analogRead(analogPin); // read the input voltage = ((float)ADC_value + 0.5) * vref / 1024.0; // optimize the quantization error andcalculate the voltage Serial.println(voltage, 3); // print the voltage with 3 decimal places delay(1000); // wait for a second

Page 64: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Le tensioni disponibili sulla schedaArduinoUSB POWER SUPPLYLa stabilità della tensione USB lascia molto a desiderare a causadelle armoniche della frequenza di rete (50Hz o 60Hz), di quelledovute a eventuali regolatori switching e agli spikes e dips causatidalle variazioni di assorbimento dei carichi. Le specifiche dellostandard USB contemplano un’alimentazione di 5V con una tolleranzadi ±5%, ovvero ±250mV per cui teoricamente la tensione può esserecompresa tra 4.75V e 5.25V. Nella pratica, le tensioni fornite daalimentatori USB commerciali e porte USB di PC mostrano in genere unrumore dell’ordine di ±10/20mV e comunque quasi mai superiore a±100mV.La tabella seguente riassume i risultati di alcune misure eseguite atemperatura ambiente:

ALIMENTAZIONE CONDENSATORE SUAREF

VREF [V]ERRORE MEDIO

[mV] TOLLERANZA [mV]

5V (PC USB) 100nF 5.045 45.2 ±14.1Non presente 5.046 45.7 ±14.2

Page 65: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fig. 31 – Una misura della tensione 5V sul pin AREF di una scheda Arduino UNO alimentata conun cavo USB collegato a un PC, con un condensatore ceramico da 100nF sul pin AREF stesso.

Page 66: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fig. 32 – Una misura della tensione 5V sul pin AREF di una scheda Arduino UNO alimentata conun cavo USB collegato a un PC, senza condensatore sul pin AREF.

LDO 5VSu Arduino UNO Rev. 3 è montato un regolatore low-dropout diOnSemiconductor modello NCP1117ST50T3G in package SOT-223 e contensione di uscita nominale di 5.0V e una tolleranza di ±50mV a+25°C. Il datasheet riporta che questo regolatore ha un operatingtemperature range tra 0 e +125°C, ovvero non è adatto per letemperature negative, per le quali esiste il modello NCV1117 che èprogettato per funzionare tra −40°C e +125°C, ma la cui tolleranzasulla tensione di uscita peggiora a ±100mV.Per quanto riguarda le principali schede Arduino-compatibili, tranneil caso della Seeeduino 4.0 che utilizza il regolatore LM78M05 diFairchild Semiconductor con una tolleranza di ±200mV, la situazioneè sostanzialmente equiparabile a quella di Arduino UNO. Ad esempio,le schede Freaduino UNO e Sparkfun RedBoard utilizzano regolatori

Page 67: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

del tipo LM1117 di Texas Instruments in package SOT-223 con unatolleranza di ±50mV. AVR.duino U+ utilizza il regolatoreLD1117DT50CTR di STM in package DPAK con una tolleranza di ±50mV.La tabella seguente riassume i risultati di alcune misure eseguite atemperatura ambiente:

ALIMENTAZIONE CONDENSATORE SUAREF

VREF [V]ERRORE MEDIO

[mV] TOLLERANZA [mV]

9V (alimentatoreesterno)

100nF 4.999 −1.2 ±2.9Non presente 4.998 −2.0 ±3.3

Fig. 33 – Una misura della tensione 5V sul pin AREF di una scheda Arduino UNO alimentata conun alimentatore esterno da 9V, con un condensatore ceramico da 100nF sul pin AREF stesso.

Page 68: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fig. 34 – Una misura della tensione 5V sul pin AREF di una scheda Arduino UNO alimentata conun alimentatore esterno da 9V, senza condensatore sul pin AREF.

Si conclude che è decisamente preferibile utilizzare come tensionedi riferimento da 5V per l’ADC quella fornita da un alimentatoreesterno e non quella derivata dall’alimentazione USB, sia in terminidi errore rispetto al valore atteso (circa 2mV contro 45mV) e sia intermini di rumore picco-picco (una tolleranza di circa ±3mV contro±14mV). On-board 3.3VSulla scheda Arduino UNO Rev. 3 è presente anche un regolatore LDOdi Texas Instruments LP2985 in package SOT-23 con tensione di uscitanominale di 3.3V e tolleranza a 25°C di ±1.5% (ovvero ±49.5mV), ingrado di erogare una corrente di 150mA. La tensione di uscita diquesto regolatore ha una dipendenza dalla temperatura, comeriportato nel grafico seguente:

Page 69: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fig. 35 – L’andamento della tensione di uscita del regolatore LP2985 al variare dellatemperatura.

La tabella seguente riassume i risultati di alcune misure eseguite atemperatura ambiente:

ALIMENTAZIONE CONDENSATORE SUAREF

VREF [V]ERRORE MEDIO

[mV] TOLLERANZA [mV]

9V (alimentatoreesterno)

100nF 3.292 −7.8 ±7.6Non presente 3.292 −7.5 ±7.6

5V (PC USB) 100nF 3.296 −4.0 ±9.8Non presente 3.296 −3.9 ±9.7

Page 70: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fig. 36 – Una misura della tensione 3.3V sul pin AREF di una scheda Arduino UNO alimentatacon un alimentatore esterno da 9V, con un condensatore ceramico da 100nF sul pin AREF stesso.

Page 71: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fig. 37 – Una misura della tensione 3.3V sul pin AREF di una scheda Arduino UNO alimentatacon un alimentatore esterno da 9V, senza condensatore sul pin AREF.

Page 72: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fig. 38 – Una misura della tensione 3.3V sul pin AREF di una scheda Arduino UNO alimentatacon un cavo USB collegato a un PC, con un condensatore ceramico da 100nF sul pin AREF stesso.

Page 73: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fig. 39 – Una misura della tensione 3.3V sul pin AREF di una scheda Arduino UNO alimentatacon un cavo USB collegato a un PC, senza condensatore sul pin AREF.

Si conclude che è preferibile utilizzare come tensione diriferimento da 3.3V per l’ADC quella fornita da un alimentatoreesterno e non quella derivata dall’alimentazione USB, sia in terminidi errore rispetto al valore atteso (circa 4mV contro 8mV) e sia intermini di rumore picco-picco (una tolleranza di circa ±8mV contro±10mV).Per quanto riguarda altre versioni di Arduino e le principali schedeArduino-compatibili, la situazione è piuttosto variegata. Adesempio: Olimexino-328: ha il regolatore MCP1700T-3302E/MB di Microchip conuna tolleranza tipica a 25°C di ±0.4% (ovvero ±13.2mV) e di ±3%(ovvero ±99mV) su tutto l’intervallo tra −40°C e +125°C; la correnteerogabile è di 250mA. AVR.duino U+: ha la stessa soluzione adottata sulla scheda ArduinoUNO.

Page 74: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Sparkfun RedBoard: utilizza un regolatore LDO MIC5205 di Micrelcon una tolleranza massima del 2% (ovvero ±66mV); la correnteerogabile è di 150mA. Seeeduino 3.0: è montato il regolatore LD1117-3.3V di STM con unatolleranza di ±33mV a 25°C, mentre la tolleranza sale a ±65mV sututto l’intervallo di corrente erogabile, che è al massimo 800mA. Iteaduino UNO: utilizza il regolatore LDO CE6209-3.3 di Chipowercon una tolleranza tipica di ±2% (ovvero ±66mV) e una correnteerogabile fino a 250mA. Esempio con AREFAd esempio, è possibile utilizzare la tensione di 3.3V generatasulla scheda Arduino collegando un ponticello tra il pin 3.3V e ilpin AREF:

Fig. 40 – Un esempio in cui la tensione di riferimento dell’ADC utilizza la tensione di 3.3Vgenerata sulla scheda Arduino UNO stessa.

In questo caso, si può considerare la tensione di riferimentodell’ADC uguale alla tensione di 3.3V stessa poiché l’impedenza diuscita del regolatore LP2985 che genera la tensione di 3.3V è dicirca 0.5Ω, ovvero due ordini di grandezza inferiore a quella

Page 75: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

interna al pin AREF (32kΩ) e quindi trascurabile nel partitore.

Fig. 41 – L’impedenza di uscita del regolatore LP2985.

ESERCIZIO: Nel caso si desideri ottenere acquisizioni più accuratecon Arduino, è opportuno ricorrere a riferimenti di tensione esternibasati su Zener, come quelli della serie Texas Instruments LM4040-Ndisponibili con varie tensioni di uscita (tra cui 2.048V, 2.500V,3.000V, 4.096V, 5.000V). Grazie a una processo di calibrazione delfornitore, offrono un’elevata accuratezza sulla tensione di uscita:per versioni in package TO-92 fino a ±0.2% e per i componenti “A-grade” in package SOT-23 addirittura ±0.1%. Come esercizio si invitail lettore a valutare l’utilizzo della scheda Precision LM4040Voltage Reference Breakout di Adafruit che fornisce due tensioni diriferimento: 2.048V e 4.096V con accuratezza di 0.1%. In

Page 76: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

particolare, si valuti la tensione effettivamente utilizzata comeriferimento dall’ADC per effetto del partitore dovuto allaresistenza di uscita della scheda e di quella interna (32kΩ) al pinAREF.

Page 77: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

L’ACCURATEZZA DELLA CONVERSIONESpesso quando si parla di accuratezza a proposito dell’ADC diArduino si fa erroneamente riferimento alla sua risoluzione ditensione di ingresso.In un sistema ADC la risoluzione e l’accuratezza non devono essereconfusi: la risoluzione rappresenta il peso dell’ultima cifra,l’accuratezza rappresenta la qualità della misura. La risoluzioneindica cioè quanto l’ADC è in grado di discriminare in ingresso;infatti, come si è detto, rappresenta la più piccola variazionedella grandezza di ingresso che produce una variazione apprezzabiledella grandezza di uscita.

Page 78: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

La stabilità del riferimento di tensioneRiprendiamo la relazione con cui l’ADC acquisisce una tensione iningresso con la funzione analogRead(): ADC = trunc[2N × VIN / VREF] Una piccola variazione della tensione VREF potrebbe essereininfluente ai fini del valore acquisito dall’ADC poiché potrebbenon essere sufficiente da far sforare di un’unità l’argomento dellafunzione troncamento. Tuttavia, specialmente con tensioni VINprossime a VREF, variazioni della tensione di riferimento potrebberocomportare una variazione di una o più unità sul valore acquisito.In particolare, essendo la tensione VREF a denominatore, una suadiminuzione potrebbe causare un aumento del valore acquisito dalconvertitore e, viceversa, un suo aumento comporterebbe unadiminuzione del valore acquisito.In pratica, l’accuratezza della tensione di riferimento può incideresull’accuratezza dell’acquisizione dell’ADC e riverberarsi infinesui calcoli matematici dello sketch.Per farsi un’idea di quanto questo aspetto possa influire,immaginiamo di voler acquisire una tensione VIN = 3.3V utilizzandouna scheda Arduino UNO con ADC a 10-bit e tensione VREF = 5V. In uncaso ideale con una tensione di riferimento costante si otterrebbeun’acquisizione di: ADC = trunc[1024 × 3.3V / 5V] = trunc[675.84] = 675 Considerando invece la tensione VREF con un valor medio di 5V ma conuna tolleranza di ±3mV (come nel caso della tensione di riferimentofornita dal regolatore LDO da 5V), con una simulazione con il metodoMonte Carlo eseguita su 1 milione di trial si ottiene la seguentedistribuzione per i valori acquisiti dall’ADC:

Page 79: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fig. 42 – La distribuzione dei valori acquisiti dall’ADC con una tensione di riferimento di5V ±3mV.

Considerando ancora la tensione VREF con un valor medio di 5V ma conuna tolleranza maggiore, ovvero di ±14mV (come nel caso dellatensione di riferimento fornita dall’alimentazione USB POWER SUPPLY5V), allora si ottiene invece la seguente distribuzione dei valoriacquisiti dall’ADC:

Page 80: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fig. 43 – La distribuzione dei valori acquisiti dall’ADC con una tensione di riferimento di5V ±14mV.

Da queste analisi si conclude che l’effetto dell’accuratezza dellatensione di riferimento sull’accuratezza dell’acquisizione dell’ADCè di circa ±1 LSB se il riferimento è particolarmente stabile,altrimenti può essere anche di circa ±2 LSB se la tensione diriferimento è soggetta a una maggiore variabilità.In realtà, per valutare l’accuratezza complessiva occorreconsiderare anche il contributo della cosiddetta absolute accuracydell’ADC (che tiene conto di tutti i comportamenti che lo discostanodal modello ideale: errori di offset, di guadagno, di quantizzazione(±0.5 LSB), non linearità integrali e differenziali). Nel casodell’ATmega328, il datasheet riporta un’absolute accuracy di ±2 LSB.Quindi in definitiva, si può stimare l’accuratezza complessivadell’acquisizione dell’ADC di Arduino con un valore di circa ±3 LSBse la tensione di riferimento è particolarmente stabile (≈ ±5mV)oppure di circa ±4 LSB se la tensione di riferimento è soggetta auna maggiore variabilità (≈ ±20mV). ESERCIZIO: Si invita il lettore a provare il seguente esempio.Collegare il pin 3.3V di una scheda Arduino UNO al pin A0 e leggere

Page 81: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

sul monitor seriale i valori acquisiti dall’ADC quando la scheda èalimentata con i 5V della porta USB. Come si è detto, teoricamenteci si aspetterebbe di misurare un valore costante pari a: ADC = trunc[1024 × 3.3V / 5V] = trunc[675.84] = 675 In realtà, come il lettore potrà verificare, sul monitor seriale sileggono valori oscillanti (nel caso delle mie misure, tra 678 e680). Come mai? Questo dipende dal fatto che il valore acquisitodall'ADC dipende dalla tensione VREF del convertitore (che nel casodi default di 5V fornita dalla porta USB del PC è poco accurata) edal fatto che la tensione sul pin 3.3V è soggetta a una variabilitàper cui non è sempre esattamente pari a 3.300V.Utilizzando un alimentatore esterno e un condensatore da 100nF tra ipin AREF e GND la situazione migliora; infatti, nel caso delle miemisure, adesso sulla porta seriale di Arduino si legge un valorecostante pari a 673, diverso dal valore atteso di 675 ma comunquecompatibile con il sistema di acquisizione. Infatti, misurando conun multimetro digitale professionale la tensione sul piedino 3.3V silegge un valore di 3.304V mentre la tensione sul pin 5V è di 5.025V,per cui sostituendo questi valori nella formula si ottieneeffettivamente: ADC = trunc[1024 × 3.304V / 5.025V] = trunc[673.29] = 673 In altri casi si possono ottenere anche altri valori costanti madiversi da quello calcolato utilizzando i valori di tensionemisurati con il multimetro. Nel mio caso, ad esempio, ho talvoltaottenuto il valore 674. Questo è comunque comprensibile poiché perl’ADC dell’ATmega328, il datasheet riporta un’absolute accuracy di±2 LSB, quindi tutti i valori compresi tra 673 e 677 sonocompatibili con quanto effettivamente misurato.

Page 82: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fig. 44 – Lo schema per l’esempio dell’acquisizione della tensione di 3.3V generata sullascheda Arduino UNO stessa.

Page 83: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

L’accuratezza sulla stima della tensionein ingressoPer valutare gli effetti dell’accuratezza complessivadell’acquisizione dell’ADC sulla stima della tensione in ingresso adArduino, occorre ricordare che ciascun bit della conversionedigitale ha un peso pari alla risoluzione di tensione dell’ADC,ovvero: ΔV = VREF / 2N = VREF / 1024 Pertanto, ad esempio, un’accuratezza di ±3 LSB sull’acquisizionedell’ADC con una VREF = 5V si ottiene un’accuratezza sulla stimadella tensione in ingresso di: ±3 × ΔV = ±3 × VREF / 2N = ±3 × 5V / 1024 ≈ ±15mV La tabella seguente mostra l’accuratezza sulla stima della tensionein ingresso al variare della tensione di riferimento dell’ADC diArduino UNO:

VREF [V] ACCURATEZZA TOTALE DELL’ADC [LSB] ACCURATEZZA DELLA STIMA DELLA TENSIONE[mV]

5.0±3 (con accuratezza VREF di ≈±5mV)±4 (con accuratezza VREF di ≈±20mV)

±15±20

3.3±3 (con accuratezza VREF di ≈±5mV)±4 (con accuratezza VREF di ≈±20mV)

±10±13

1.1±3 (con accuratezza VREF di ≈±5mV)±4 (con accuratezza VREF di ≈±20mV)

±3±4

Per confronto, un multimetro digitale professionale come il Fluke175 (il cui prezzo è di circa 250€) fornisce misure di tensione conrisoluzione di 0.001V e accuratezza totale di 0.15% + 2, ovvero nelcaso di un ingresso pari a 5V l'accuratezza è di 0.15% x 5V + 2 x0.001V = ±9.5mV.Un tipico multimetro digitale hobbistico, come il tascabile AmprobePM51A (il cui prezzo è di circa 35€) è in grado di fornire misure ditensione con risoluzione di 0.001V e un’accuratezza di ±2%, ovverocon una tensione in ingresso di 5V l’accuratezza è di ±100mV.È interessante inoltre ricordare che, essendo l’absolute accuracy la

Page 84: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

stessa (±2 LSB) nel caso di tutti gli ADC a 10-bit deimicroprocessori Atmel AVR (ATmega328, ATmega1280, ATmega2560,ATmega32u4), le considerazioni riportate a proposito di Arduino UNOsono valide anche nel caso di altre schede Arduino (come, adesempio, Leonardo, Yún o Mega) a parità di alimentazione.

Page 85: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

L’accuratezza sulla stima della misura daun sensorePer valutare quanto l’accuratezza sulla stima della tensione iningresso incida sull’accuratezza della misura da un sensore la cuitensione di uscita sia appunto in ingresso all’ADC di Arduino,occorre convertire l’accuratezza della tensione nell’equivalenteaccuratezza della grandezza fisica misurata (tramite il guadagno delsensore) e poi sommare a questo valore l’accuratezza della misuradel sensore stesso che è riportata nel datasheet. Esempio della misura della temperaturaAd esempio, consideriamo il caso in cui la tensione in ingressoall’ADC di Arduino UNO provenga da un sensore di temperaturaanalogico come il TMP36 o LM35. Per entrambi i sensori il guadagno èdi 10mV/°C, mentre l’accuratezza è di ±1°C per il TMP36 e di ±0.2°Cper LM35.Utilizzando una tensione VREF = 5V con accuratezza di circa ±5mV, siè visto sopra che l’accuratezza sulla stima della tensione iningresso è di circa ±15mV, che corrisponde dunque a un’accuratezzain temperatura di: ±15mV / (10mV/°C) = ±1.5°C A questa si deve sommare l’accuratezza del sensore. Nel caso delLM35, si otterrebbe: ±1.5°C + ±0.2°C = ±1.7°C ≈ ±2°C La tabella seguente mostra l’accuratezza sulla stima dellatemperatura misurata nel caso di sensori TMP36 e LM35 al variaredella tensione di riferimento dell’ADC di Arduino UNO: VREF[V]

ACCURATEZZA DELLA STIMADELLATENSIONE [mV]

ACCURATEZZA DELLATEMPERATURA MISURATA [°C]

RISOLUZIONE INTEMPERATURA DELL’ADC

10-bit [°C]TMP36 LM35

5.0

±15 (con accuratezza VREF di ≈±5mV)±20 (con accuratezza VREF di ≈±20mV)

±2.5±3.0

±1.7±2.2 ≈0.5

3.3±10 (con accuratezza VREF di ≈±5mV)±13 (con accuratezza VREF di ≈

±2.0±2.3

±1.2±1.5

≈0.3

Page 86: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

±20mV)

1.1±3 (con accuratezza VREF di ≈±5mV)±4 (con accuratezza VREF di ≈±20mV)

±1.3±1.4

±0.5±0.6 ≈0.1

Si tratta di valori accettabili? I sistemi professionali per ildatalogging di temperature in ambito industriale (impiegati, adesempio, per il monitoraggio delle merci trasportate o dell'arianelle celle frigorifere) hanno una risoluzione di 0.1°C eun’accuratezza tipica di ±0.5°C (che in alcuni dispositivi di fasciaalta su intervalli di temperatura meno estesi, generalmente tra−10°C e +70°C, può essere anche di ±0.3°C). Dispositivi commercialiper misurare la temperatura per usi domestici hanno invecetipicamente una risoluzione di 0.1°C e un’accuratezza di ±1°C pertemperature comprese tra 0°C e +80°C, oppure tra ±2°C e ±5°C perintervalli di temperatura più estesi.Nel caso si desideri ottenere dei livelli di accuratezza più spinta,occorre impiegare sensori con accuratezza migliore come il TexasInstruments LMT70 che ha un’accuratezza tipica di ±0.05°C pertemperature comprese tra +20°C e +42°C. Inoltre, per quanto lamaggior parte dei sensori di temperatura integrati possa presentarelimiti nell’accuratezza, questi possiedono normalmente delle ottimeprestazioni di linearità, per cui spesso ricorrere a unacalibrazione con una temperatura nota (single point calibration) puòportare a risultati comunque veramente accurati. Ad esempio, nelcaso di applicazioni per misure della temperatura corporea, ovveronell’intorno di 37°C, è possibile calibrare il sistema di misurasfruttando come riferimento il punto di ebollizione del Pentano(36.1°C) o il punto di fusione del Gallio (29.7646 °C). Esempio della misura dell’umidità relativaConsideriamo, ad esempio, il sensore Honeywell HIH-4030 perl’umidità relativa (%RH) che, alimentato con una tensione di 5V,fornisce un segnale analogico di uscita come nella tabella seguente:

Page 87: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fig. 45 – La tensione di uscita del sensore Honeywell HIH-4030 al variare dell’umiditàrelativa.

Il guadagno tipico di questo sensore (che rappresenta la pendenzadella linea nel grafico) secondo il datasheet è 30.680 mV/%RH el’accuratezza del sensore è di ±3.5 %RH.Utilizzando una scheda Arduino UNO con una tensione VREF = 5V conaccuratezza di circa ±5mV, si è visto sopra che l’accuratezza sullastima della tensione in ingresso è di circa ±15mV, che in termini diumidità relativa corrisponde a un’accuratezza di: ±15mV / (30.680 mV/%RH) = ±0.49 %RH A questa si deve sommare l’accuratezza del sensore, per cui siottiene un’accuratezza totale di:

Page 88: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

±0.49 %RH + ±3.5 %RH ≈ ±4 %RH

Page 89: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

La calibrazione del riferimento ditensione dell’ADCCome si è visto sopra l’accuratezza della misura dipendenotevolmente dalla qualità del riferimento di tensione utilizzatoche nelle applicazioni pratiche ha una tolleranza non trascurabile:

TIPO DI RIFERIMENTO TENSIONE NOMINALE[V]

ACCURATEZZA(misure)

USB 5.0 ±14.2mVLDO 5.0 ±3.3mVOn-board 3.3V (PC USB) 3.3 ±9.8mVOn-board 3.3V (alimentatore esterno) 3.3 ±7.6mVInternal bandgap (PC USB) 1.1 ±6.3mVInternal bandgap (alimentatoreesterno) 1.1 ±3.4mV

External LM4040-N 2.048 ±2.0mV Conoscere con esattezza la tensione di riferimento utilizzata per ilconvertitore ADC è fondamentale per evitare errori sulla stima dellatensione in ingresso.Infatti, supponiamo ad esempio che la tensione VREF sia in realtà4.980V, ovvero 20mV inferiore al valore nominale; nell’ipotesi cheuna tensione di 2.5V sia in ingresso al convertitore, questoacquisirà: ADC = trunc[2N × VIN / VREF] = trunc[1024 × 2.5V / 4.980V] = 514 Se invece nello sketch si utilizzasse per il riferimento di tensioneuna tensione pari esattamente al valore nominale di 5V, alloral’acquisizione verrebbe erroneamente interpretata come: ṼIN = ADC × VREF / 2N = 514 × 5V / 1024 = 2.510V Pertanto, rispetto alla tensione effettivamente presente in ingressoal convertitore si avrebbe un errore di: 2.510V – 2.500V = 10mV Se la tensione in ingresso provenisse da un sensore di temperaturatipo TMP36 o LM35, si avrebbe un errore di: 10mV / 10mV/°C = 1°C

Page 90: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Per ridurre l’incidenza di questo tipo di errore, è buona normautilizzare nello sketch per la tensione VREF un valore misuratopiuttosto che uno puramente nominale.Esistono sostanzialmente tre metodi per misurare il valore delriferimento di tensione dell’ADC ai fini della calibrazionedell’algoritmo di stima della tensione di ingresso: Misura esterna con un voltmetroFacendo riferimento al diagramma a blocchi dell’ADC, si nota cheindipendentemente dalla modalità impostata con la funzioneanalogReference(), la tensione VREF è sempre presente sul pin AREF.Quindi, su una scheda Arduino è sempre possibile misurarla con unvoltmetro esterno e calibrare la conversione coerentemente in mododa migliorarne l’accuratezza.Ad esempio, nel caso si misuri sul pin AREF una tensione di 4.985V èpossibile definire all’interno del codice la tensione di riferimentocome: float vref = 4.985; // calibrated ADC voltage reference E poi riutilizzare questa costante nel codice per tutte leconversioni.Ovviamente non è possibile utilizzare l’ADC stesso per leggere latensione AREF poiché, essendo l’architettura del convertitore adessa riferita, produrrebbe una lettura sempre uguale a 0x3FF, ovvero210 − 1 = 1023. Misura interna riferita alla tensione interna dibandgapFacendo ancora riferimento al diagramma a blocchi, è possibileconfigurare il multiplexer degli ingressi all’ADC in modo che siaselezionato come ingresso il riferimento interno bandgap, che comesi è detto su Arduino UNO ha un valore nominale di 1.1V. In questocaso, il valore letto dall’ADC è: ADCbg = trunc[210 × 1.1 / VREF] = trunc[1024 × 1.1 / VREF] =trunc[1126.4 / VREF] Supponendo di essere nel caso di default con la tensione VREF

Page 91: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

impostata alla tensione AVCC e che questa sia una tensione idealestabile a 5V, allora la lettura dell’ADC sarebbe: ADCbg = trunc[1126.4 / 5] = trunc[225.28] = 225 Se però la tensione di riferimento si discosta dal valore ideale di5V allora la lettura della tensione di riferimento bandgap saràdiversa dal valore atteso di 225. In particolare esiste unarelazione inversa: se la VREF diminuisce, leggeremo valori maggioridi 225, in caso contrario leggeremo valori minori di 225. L’idea èappunto quella di utilizzare questa lettura per risalire allatensione VREF effettiva: VREF ≈ 1.1 × 1024 / ADCbg = 1126.4 / ADCbg Questo metodo di lettura del riferimento di tensione non richiedeuno strumento di misura esterno e in linea di principio consente direalizzare una sorta di calibrazione periodica, monitorando neltempo le eventuali fluttuazioni della tensione VREF. Tuttavia,questo metodo è fortemente legato all’accuratezza della tensione diriferimento bandgap che, come si è visto, a temperatura ambiente puòvariare anche di ±20mV rispetto al valore nominale di 1.1V. Questocomporta che il valore atteso della lettura dell’ADC con in ingressoil riferimento bandgap interno possa in realtà essere compreso tra221 e 229, così una tensione ideale stabile VREF = 5.0V sarebbe inrealtà erroneamente ricalibrata a un valore compreso tra 4.919V e5.097V, ovvero con un errore di circa ±90mV che si riverberebberosul segnale acquisito (ad esempio, nel caso di una misura ditemperatura si potrebbe avere anche un errore di ±9°C).Pertanto questo metodo di calibrazione, sebbene accreditato inalcuni forum in rete, è certamente sconsigliato. Misura interna riferita a una tensione esternaSu alcuni forum in rete è suggerita anche un’altra possibilità,simile al metodo in precedenza illustrato, che consistenell’acquisire il segnale di ingresso insieme a una tensionecostante di valore noto con cui operare una calibrazione medianteuna scalatura in modo che se la tensione nota viene acquisita con unvalore diverso da quello atteso allora il valore corrispondente allatensione da acquisire è scalato di conseguenza. In pratica, se latensione da 5V che l’ADC utilizza come riferimento di default

Page 92: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

subisce variazioni dovute a rumore o ad altri carichi da essaalimentati, il valore della conversione della tensione di ingressonota varia di conseguenza e pertanto permette di compensare ilvalore della lettura dell’uscita del sensore.Tuttavia, nella pratica anche questo metodo è sconsigliabile perchénon sufficientemente accurato. Infatti, a causa dell’errore diquantizzazione il rapporto tra i due valori interi acquisitidall’ADC, in quanto troncati, produce risultati oscillanti. ESERCIZIO: Come esercizio valutare l’implementazione di quest’ultimometodo considerando il seguente schema in cui si acquisisce sul pinA1 il segnale da un sensore di temperatura tipo LM35 e sul pin A0 latensione di 3.3V generata dalla scheda Arduino UNO e impiegata comeriferimento per la calibrazione:

Page 93: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fig. 46 – Lo schema per l’esempio sulla valutazione della misura interna riferita a unatensione esterna.

Un esempio di sketch in questo caso è: unsigned int ADC_value = 0; // variable storing the ADC readingunsigned int ADC_reference = 0; // variable storing the ADC reading at the reference voltagefor the calibrationfloat V_reference = 3.3; // set the reference voltage for the calibrationfloat sensor_voltage = 0.0; // variable storing the calculated voltage void setup() bitSet(DIDR0, ADC0D); // disable digital input on ADC0 bitSet(DIDR0, ADC1D); // disable digital input on ADC1 Serial.begin(9600); // baud rate for the serial communication

Page 94: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

void loop() ADC_value = analogRead(1); // read the analog input ADC_reference = analogRead(0); // read the reference voltage for the calibration sensor_voltage = V_reference * (float)ADC_value / (float)ADC_reference; // calculate thevoltage with the calibration Serial.println(sensor_voltage, 2); // print the voltage with 2 decimal places delay(1000); // wait for a second

Page 95: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

La calibrazione dell’ADCGli eventuali errori di offset e di guadagno dell’ADC possono essereridotti con una calibrazione. Sfortunatamente i microprocessoriAtmel delle schede Arduino non offrono meccanismi interni di auto-calibrazione, quindi la calibrazione deve essere previstadall’utente.Ad esempio, è possibile eseguire la calibrazione una sola voltaall’inizio dell’utilizzo (la cosiddetta power up calibration) oppureprevedere una calibrazione periodica durante l’esecuzione del codice(la cosiddetta run time calibration) per ovviare a eventualiproblemi di deriva termica, specialmente nel caso di impieghi sutempi lunghi.In generale, la calibrazione dell’ADC è realizzata in due fasidistinte: in una prima fase, si compensa l’errore di offset mentrenella seconda è compensato l’errore di guadagno. Esistono varieimplementazioni della procedura di calibrazione. Si suggerisce allettore di consultare l’Application Note AN2989 di Freescale e laAVR120 di Atmel dove ne sono indicate alcune di riferimento.

Page 96: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

IL CAMPIONAMENTOIl teorema del campionamento In generale, campionare un segnale significa registrarne il valore acerti istanti e il numero di campioni registrati al secondo (ovverola frequenza di campionamento) deve essere sufficientemente elevatoin relazione alla velocità di variazione del segnale, che aumenta alcrescere delle componenti ad alta frequenza contenute dal segnalestesso.Com’è noto, questo problema è oggetto del teorema del campionamento,per il quale dato un segnale a tempo continuo e a banda limitataFMAX, la minima frequenza di campionamento FS (generalmente indicatain letteratura come frequenza di Nyquist) necessaria affinché ilsegnale campionato contenga la stessa informazione del segnaleoriginario (cioè sia possibile ricostruire il segnale a partiredalla sequenza dei suoi campioni) è: FS ≥ 2 × FMAX In altre parole, il minimo sampling rate deve essere almeno ildoppio della banda del segnale da campionare. Se questa relazionenon è rispettata, la ricostruzione basata sui singoli campioniproduce un segnale assai diverso da quello originario: questofenomeno è chiamato aliasing e non è correggibile a posteriori, madeve essere risolto a monte del convertitore.Per evitare il fenomeno dell’aliasing esistono principalmente duesoluzioni: Aumentare la frequenza di campionamento Introdurre un filtro passa-basso (anti-aliasing) prima delconvertitore L’aumento della frequenza di campionamento non è sempre perseguibilepoiché, a causa dei limiti hardware e dell’architettura delconvertitore, può comportare una riduzione della risoluzioneeffettiva, quella che in letteratura è indicata come EffectiveNumber Of Bits (ENOB).L’introduzione del filtro è invece generalmente più semplice daimplementare. I filtri anti-aliasing sono di tipo passa-basso (lowpass) e hanno lo scopo di eliminare le frequenze del segnale

Page 97: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

superiori a FS / 2, anche se nella realtà non trattandosi di filtriideali si tende a prevedere un certo margine e progettarli con unafrequenza di taglio inferiore (ad esempio, FS / 2.56). Infatti, aldi sopra di questa frequenza la banda del segnale non ècompletamente azzerata, ma è attenuata con un fattore che nel casodi filtri del primo ordine è di 20dB/decade, mentre nei filtri delsecondo ordine è di 40dB/decade e, in generale, un filtro passa-basso di ordine N attenua N × 20dB/decade, a patto però diutilizzare un maggior numero di componenti (induttori econdensatori) e quindi con un maggiore costo e spazio perrealizzarli.

Page 98: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

La frequenza di campionamento conl’ATmega328Le schede Arduino basate sul microprocessore ATmega328 hannogeneralmente un system clock di 16MHz, determinato da un quarzomontato sulla scheda stessa. Fanno eccezione poche versioni (tra cuiLilyPad, Fio e Pro Mini da 3.3V) in cui il system clock è di 8MHz.Il clock del convertitore (ADC clock) è ottenuto dal system clocktramite un divisore di frequenza (prescaler) il cui valore èdeterminato in base al contenuto dei primi tre bit (ADPS2, ADPS1,ADPS0) del registro ADCSRA (ADC Control and Status Register A).Per modificare i bit dei registri si utilizzano le funzioni sbi() ecbi() e i valori programmabili sono 2, 4, 8, 16, 32, 64 e 128, comeriassunto nella tabella seguente:

ADPS2 ADPS1 ADPS0 DIVISORE DELPRESCALER

0 0 1 20 1 0 40 1 1 81 0 0 161 0 1 321 1 0 641 1 1 128

Secondo il datasheet dell’ATmega328, affinché sia garantita larisoluzione di 10-bit, la frequenza di clock ottimale per l’ADC deveessere compresa tra 50kHz e 200kHz. A frequenze maggiori di questointervallo, la risoluzione non è più garantita. Nelle schede ArduinoUNO il prescaler di default è configurato per una divisione di 128,per cui si ottiene un ADC clock di: 16MHz / 128 = 125kHz che è appunto una frequenza contenuta all’interno dell’intervallo difunzionamento ottimale.Questa configurazione di default con il divisore di 128 è contenutanel file wiring.c del software di Arduino: sbi(ADCSRA, ADPS2);sbi(ADCSRA, ADPS1);sbi(ADCSRA, ADPS0); La seguente tabella mostra le possibili opzioni dell’ADC clock

Page 99: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

(espresso in kHz) in base al system clock della scheda e al divisoredel prescaler:

SYSTEM CLOCKFREQUENCY[MHz]

DIVISORE DEL PRESCALER

2 4 8 16 32 64 128

8 4000 2000 1000 500 250 125 62.512 6000 3000 1500 750 375 187.5 93.816 8000 4000 2000 1000 500 250 12520 10000 5000 2500 1250 625 313 156

In alcune applicazioni in cui i vincoli di banda sul segnale diingresso siano limitanti (come nel caso dei segnali audio) èpossibile utilizzare frequenze di campionamento maggiori di quellanominale di 125kHz, programmando diversamente il divisore delprescaler e/o utilizzando una diversa frequenza del system clock(ovvero ricorrendo a versioni di Arduino con un diverso quarzomontato sulla scheda).L’accuratezza dell’ADC dipende dall’ADC clock, la cui massimafrequenza come si è detto non deve superare 200kHz affinché ilcircuito di conversione operi in condizioni ottimali. Tuttavia,nella pratica si rileva che impostando frequenze dell’ADC clock finoa valori di 500kHz/1MHz la risoluzione effettiva (ENOB) dell’ADC nonsi riduce significativamente. Per frequenze maggiori di 1MHz ilcomportamento non è però caratterizzato.Ad esempio, su una scheda Arduino UNO, per ottenere un ADC clock di1MHz occorre configurare il divisore a 16 inserendo le seguentirighe di codice all’interno della sezione void setup(): sbi(ADCSRA,ADPS2);cbi(ADCSRA,ADPS1);cbi(ADCSRA,ADPS0);

Page 100: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Il tempo di conversioneIl tempo di conversione è il tempo necessario affinché il segnale iningresso al convertitore sia campionato e convertito su uno deilivelli di quantizzazione. Ovviamente, è importante che il segnalerimanga stabile durante questo intervallo per evitare un erroresulla conversione.A questo tempo si deve aggiungere anche quello computazionalenecessario per elaborare il dato acquisito secondo quanto definitonello sketch. Tuttavia, nelle applicazioni pratiche questo tempo dielaborazione è generalmente molto più piccolo di quello necessarioall’acquisizione e pertanto non sarà qui considerato.

Fig. 47 – Il tempo di conversione dell’ADC e l’intervallo di campionamento.

L’architettura SAR dell’ADC dell’ATmega328 determina che, terminatala prima conversione, ciascuna conversione ADC richieda 13 cicli diADC clock, che nelle condizioni di default di una scheda Arduino UNOcorrisponde a una frequenza di campionamento di:

Page 101: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

FS = 125kHz / 13 = 9.615kHz ovvero a un intervallo di campionamento teorico di: 1 / 9.615kHz = 104µs Proviamo adesso a valutare il tempo di conversione “effettivo” diuna scheda Arduino UNO con microprocessore ATmega328. Lo sketch dautilizzare è il seguente: unsigned int samples = 1000;unsigned long time;unsigned long duration;unsigned int dummy_input; void setup() Serial.begin(9600); // baud rate for the serial communication void loop() time = micros(); for (int i = 0; i < samples; i++) dummy_input = analogRead(0); duration = micros() - time; Serial.println(duration); La funzione micros() riporta il numero di microsecondi trascorsi daquando è iniziato a girare il programma su Arduino. Sulle schede conclock a 16MHz (come Arduino UNO, Duemilanove, Nano) questa funzioneha una risoluzione di 4 microsecondi, ovvero il valore che produce èsempre un multiplo di 4. Sulle schede con clock a 8MHz (comeLilyPad), questa funzione ha invece una risoluzione di 8microsecondi, ovvero il valore che produce è sempre un multiplo di8.Sulla base di circa 12000 misure eseguite a temperatura ambiente sultempo necessario a convertire 1000 acquisizione (su un totale cioèdi circa 12 milioni di valori) il test ha prodotto questi risultati: valore minimo: 112.000μs valore medio: 112.009μs valore massimo: 112.024μs Si tratta di valori molto stabili, da cui si ricava una stima per iltempo di acquisizione di 112μs (leggermente superiore al valore

Page 102: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

teorico atteso di 104µs).

Fig. 48 – La distribuzione delle misure del tempo di conversione dell'ADC di una schedaArduino UNO.

ESERCIZIO: Si suggerisce al lettore di provare a ripetere la misuradel tempo di acquisizione utilizzando delle schede Arduino conmicroprocessori diversi dall’ATmega328 (ad esempio, le schedeArduino DUE o Leonardo). Considerando dunque un intervallo di campionamento misurato di 112μssi ricava che la frequenza di campionamento effettiva è: FS = 1 / 112µs = 8.929kHz Da cui, la massima banda del segnale campionabile: FMAX = FS / 2 = 4.464kHz ≈ 4.5kHz Si tratta di una banda sufficientemente ampia per la maggior partedelle applicazioni realizzabili con una scheda Arduino UNO. Traqueste, ad esempio, il monitoraggio di segnali biomedici (battito

Page 103: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

cardiaco < 100Hz, respiro < 10Hz), l’acquisizione di segnali sismici(< 200Hz) o le applicazioni in ambito audio a bassa fedeltà.Infatti, sebbene la banda audio standard si consideri estesa fino a20kHz, la parte più significativa dei segnali audio vocali èconcentrata nelle frequenze più basse e, d’altra parte, lamaggioranza delle persone in età adulta difficilmente percepiscefrequenze superiori a 16kHz. Questo aspetto è sfruttato, ad esempio,nelle trasmissioni di segnali telefonici dove, nonostante la bandasia limitata a 4kHz, la comprensibilità del parlato non èpregiudicata. ATTENZIONE: Nel caso in cui si acquisiscano più segnali analogici inparallelo, la frequenza di campionamento dell’ADC dovrà esseredivisa per il numero dei segnali (a causa del citato meccanismo cheporta a turno i vari canali dal multiplexer al convertitore ADCinterno).

Page 104: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

La scelta della frequenza dicampionamentoCome si è detto, la frequenza di campionamento deve essere almeno ildoppio della banda del segnale da campionare. Tuttavia, nellamaggior parte delle applicazioni con schede Arduino collegate asensori analogici (temperatura, pH, luminosità, umidità relativa,ecc.) i segnali da campionare provengono da sensori che misuranograndezze fisiche che variano lentamente, ovvero con una bandainferiore a 10Hz. Il convertitore ADC della scheda Arduino consentedi rispettare ampiamente la relazione del teorema del campionamentoin quanto, già in condizioni di default, il massimo clock dell’ADC èalmeno un paio di ordini di grandezza maggiore della banda di questisegnali. Pertanto, è più pratico scegliere la frequenza dicampionamento considerando la rapidità con cui può variare ilsegnale da acquisire in relazione all’accuratezza desiderata.Facciamo qualche esempio per fissare le idee.Volendo monitorare con un’accuratezza di 0.1°C la temperaturainterna di una cella termica che può variare di circa 10°C/min, ènecessario campionare la temperatura al più ogni: 0.1°C / 10°C/min = 600ms Quindi una scelta di un intervallo di campionamento di 500ms (ovvero2 volte al secondo) sarebbe adeguata.Consideriamo adesso il caso della misura della temperatura sulbalcone in città. In questo caso, occorre valutare la cosiddettaescursione termica diurna, cioè la differenza fra la massimatemperatura diurna e la minima temperatura notturna. Alle latitudinieuropee, durante l’anno questa escursione è al più di circa 30°Cnell’arco di 12 ore. Quindi la massima variazione di temperatura puòessere stimata come: 30°C / 12h = 2.5°C/h ≈ 0.042°C/min Puntando ancora a un’accuratezza di 0.1°C, è necessario campionareal più ogni: 0.1°C / 0.042°C/min ≈ 143s Quindi una scelta di un intervallo di campionamento di 2 minuti (120secondi) sarebbe adeguata.

Page 105: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Consideriamo il caso della misura dell’umidità relativa (conun’accuratezza di ±5%RH) in un ambiente in cui questa possa variarecon una massima escursione di 80%RH nell’arco di 12 ore, il periododi campionamento dovrà essere al più: 5%RH / (80%RX / 12h) = 45min Quindi una scelta di un intervallo di campionamento di 30 minuti(ovvero 2 volte ogni ora) sarebbe adeguata.

Page 106: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Il campionamento uniformeIn realtà, il problema del campionamento non uniforme con le schedeArduino non è una questione realmente critica nelle applicazionipratiche. Infatti, riprendendo le conclusioni dell’Application Note4466 (Aperture Jitter Calculator for ADCs) di Maxim Integrated, lamassima aperture jitter di un ADC dipende dalla sua risoluzione edalla massima frequenza del segnale di ingresso secondo larelazione: tJ = 1 / (π × fIN_MAX × 2N+1) Nel caso di Arduino UNO, in cui N = 10 e considerando una massimabanda del segnale in ingresso di ≈ 4.5kHz, si ottiene: tJ = 1 / (π × 4500 × 210+1) = 0.035µs Questa tolleranza non sarebbe tuttavia perseguibile a meno diimplementare un campionamento uniforme con un codice opportuno (adesempio, con la gestione dei cosiddetti timer interrupts).Fortunatamente, in presenza di segnali a contenuto frequenziale piùlimitato, la tolleranza sugli istanti di campionamento è decisamentepiù rilassata. Infatti, per segnali con una banda inferiore a 10Hzsi ottiene: tJ = 1 / (π × 10 × 210+1) = 15.6µs E anche considerando un eventuale oversampling a 12-bit si avrebbe: tJ = 1 / (π × 10 × 212+1) = 3.9µs Si tratta di una variazione massima trascurabile se confrontataappunto con il tempo di campionamento che per le applicazioni conquesti segnali su Arduino è generalmente impostata su valori dialmeno 100ms e pertanto ampiamente tollerabile senza dovernecessariamente ricorrere nel codice a un’implementazione di uncampionamento uniforme basato sulle interruzioni del timer.

Page 107: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

LA TECNICA DELL’OVERSAMPLINGLa tecnica dell’oversampling consente di aumentare la risoluzione diun convertitore analogico/digitale operando un campionamento con unafrequenza maggiore di quella inizialmente prevista FS (comunquesuperiore a quella di Nyquist) ed eseguendone un filtraggio a media.Tralasciando la giustificazione teorica, piuttosto complicata perl’utente medio di Arduino, si può sostanzialmente riassumere chenell’ipotesi di voler aumentare la risoluzione di un numeroaggiuntivo B di bit occorre sovra-campionare il segnale di ingressocon una frequenza di 4B × FS, ovvero per ciascun bit aggiuntivo dirisoluzione occorre campionare il segnale quattro volte piùrapidamente. Si è soliti indicare il valore 4B come oversamplingfactor o tasso di sovra-campionamento.Ad esempio, per ottenere una risoluzione di 12-bit da un ADC a 10-bit con frequenza di campionamento di 10Hz, occorre campionare 42 =16 volte più rapidamente, ovvero a 160Hz.La tecnica dell’oversampling trova un corretto impiego quando ilsegnale di ingresso non varia significativamente all’interno dellafinestra temporale in cui si acquisiscono i sovra-campioni, in altreparole quando la tensione che si desidera misurare varia molto piùlentamente del tempo necessario per effettuare le acquisizioni.Tuttavia, all’aumentare dei bit aggiuntivi questo intervallo ditempo aumenta esponenzialmente, come illustrato nel grafico seguente(considerando un tempo di conversione di 112μs):

Page 108: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fig. 49 – L’intervallo di tempo richiesto al variare del numero di extra bit di oversampling.

Per quanto riguarda le formule da impiegare nel codice, occorreconsiderare che la media sui 4B sovra-campioni deve essere scalatadi un valore pari a 2B, poiché i bit aggiuntivi comportano unamoltiplicazione del fondoscala (e quindi dei livelli dellaconversione) appunto di un fattore 2B:

Poiché aumenta il numero di bit complessivi del convertitore edunque anche il numero di livelli su cui viene mappato l’intervallodelle tensioni in ingresso, la risoluzione di tensione di ingressomigliora:

Page 109: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

VREF / 2N+B

La tensione stimata è data da:

Nel caso di un oversampling di 2-bit aggiuntivi a partire da un ADCa 10-bit (come quello di Arduino UNO) occorre utilizzare 42 = 16sovra-campioni e si ottiene una risoluzione di tensione di ingressopari a: 5V / 210+2 = 1.221mV Inoltre si ottiene:

Oltre a consentire un aumento della risoluzione della conversioneanalogico/digitale, la tecnica dell’oversampling offre anche altrivantaggi. Tra questi è utile segnalare la possibilità di impiegaredei filtri passa-basso anti-aliasing con prestazioni nonnecessariamente elevate (e quindi meno complessi e costosi), perchélavorando a frequenze maggiori sono in grado di garantireattenuazioni migliori. Un altro vantaggio consiste nella riduzionedel rumore nella banda di interesse: per ogni bit aggiuntivo dioversampling si ottiene un miglioramento di circa 6dB nel rapportosegnale/rumore Signal-to-Quantization-Noise Ratio (SQNR), questoperò al prezzo di quadruplicare la frequenza di campionamento perciascun bit.Il seguente sketch è un esempio di implementazione di unoversampling a 12-bit (16 sovra-campioni) nel caso di una misura ditensione sul piedino A0 di una scheda Arduino UNO. Considerando untempo di acquisizione di 112µs e nell’ipotesi che la tensione siacampionata ogni secondo, il tempo di campionamento da utilizzare

Page 110: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

nello sketch per l’oversampling può essere calcolato come: Δt = 1s / 16 − 112µs ≈ 62ms byte analogPin = 0; // set the analog input to pinunsigned int total = 0; // variable storing the ADC sumfloat vref = 5.0; // set the ADC voltage reference (it’s strongly suggested to use a measuredvoltage)float voltage = 0.0; // variable storing the calculated voltage void setup() bitSet(DIDR0, ADC0D); // disable digital input on ADC0 Serial.begin(9600); // baud rate for the serial communication void loop() total = 0; for (int i = 0; i < 16; i++) unsigned int a = analogRead(analogPin); // read the input on analogPin total += a; // accumulate delay(62); // delay to define the sampling time voltage = (float)total * vref / 16384.0; // calculate the corresponding voltage Serial.println(voltage, 3); // print the voltage with 3 decimal places Il seguente sketch implementa alcune modifiche rispetto alprecedente in modo da potersi adattare al fattore di oversamplingdesiderato e al tempo di campionamento scelto per il segnale, che suArduino UNO per la limitazione del tipo unsigned int può essere almassimo: (216 − 1)ms = 65535ms = 65.535s byte analogPin = 0; // set the analog input to pinunsigned int total = 0; // variable storing the ADC sum (<= 65535)float vref = 5.0; // set the ADC voltage reference (it’s strongly suggested to use a measuredvoltage)float voltage = 0.0; // variable storing the calculated voltageunsigned int main_sampling_time_ms = 1000; // variable storing the main sampling time in ms(<= 65535)byte extrabits = 2; // set the number of the additional bits of the oversampling (<= 4)float oversampling_factor = pow(4.0, (float)extrabits);unsigned int oversampling_time = (unsigned int)((float)main_sampling_time_ms -(oversampling_factor * 0.112)); void setup() bitSet(DIDR0, ADC0D); // disable digital input on ADC0

Page 111: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Serial.begin(9600); // baud rate for the serial communication void loop() total = 0; for (int i = 0; i < oversampling_factor; i++) unsigned int a = analogRead(analogPin); // read the input on analogPin total += a; // accumulate voltage = (float)total * vref / (1024.0 * oversampling_factor); // calculate thecorresponding voltage Serial.println(voltage, 3); // print the voltage with 3 decimal places delay(oversampling_time); // delay to define the sampling time Questo sketch è molto flessibile e funziona anche nel caso specialein cui non si implementi alcun oversampling, ovvero extrabits = 0.Essendo la variabile total di tipo unsigned long, il massimooversampling_factor compatibile con questo sketch è: (216 – 1) / (210 – 1) = 65535 / 1023 = 64.061 Da cui, il massimo extrabits è: LN(64.061) / LN(4) = 4.159 ≈ 4 Ovvero, questo sketch supporta oversampling fino a 14-bit.Nel caso in cui la tensione acquisita provenga da un sensore ditemperatura con un guadagno di 10mV/°C (come LM35), allora volendomisurare la temperatura è sufficiente modificare lo sketch comesegue: float temperature = 0.0; // variable storing the calculated temperature......void loop()...... voltage = (float)total * vref / (1024.0 * oversampling_factor); // calculate thecorresponding voltage temperature = voltage * 100.0; // calculate the corresponding temperature (10mV = 1°C) Serial.println(temperature, 1); // print the temperature with 1 decimal places delay(oversampling_time); // delay to define the sampling time ESERCIZIO: Come esercizio, si suggerisce al lettore di implementarela tecnica dell’oversampling, considerando anche la compensazione

Page 112: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Half LSB Adder dell’errore di quantizzazione per la quale la formuladella tensione stimata diventa:

Il seguente sketch è un esempio che mostra l’impiego di unoversampling a 12-bit (42 = 16 sovra-campioni) nel caso di unamisura di tensione ogni 500ms, implementando anche la compensazioneHalf LSB Adder dell’errore di quantizzazione. In questo esempio,come tensione di ingresso all’ADC della scheda Arduino UNO è statautilizzata la scarica di un condensatore precedentemente caricatocon il regolatore LDO 3.3V presente sulla scheda stessa. byte analogPin = 0; // set the analog input to pinunsigned int total = 0; // variable storing the ADC averaged sumfloat ADC_over_value = 0.0; // variable storing the oversampling ADC valuefloat voltage = 0.0; // variable storing the calculated voltagefloat vref = 5.020; // set the ADC voltage reference (value measured with a multimeter) void setup() bitSet(DIDR0, ADC0D); // disable digital input on ADC0 Serial.begin(9600); // baud rate for the serial communication void loop() total = 0; for (int i = 0; i < 16; i++) unsigned int a = analogRead(analogPin); // read the input on analogPin with 10-bit total += a; // accumulate delay(31); // delay to define the oversampling time = 500ms / 16 ADC_over_value = (float)total / 16.0 + 0.125; // average and compensate the quantizationerror [0.125 = 0.5 / 4] voltage = ADC_over_value * vref / 1024.0; // calculate the corresponding 12-bit voltage Serial.println(voltage, 3); // print the 12-bit voltage

Page 113: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fig. 50 – Lo schema per l’esempio del campionamento con oversampling a 12-bit della scaricadi un condensatore.

Page 114: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Fig. 51 – I valori di tensione ottenuti nell’esempio del campionamento con oversampling a 12-bit della scarica del condensatore.

Page 115: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Massimo oversamplingPotrebbe sembrare che, a patto di avere un segnale di ingressosufficientemente lento, aumentando il fattore di oversampling siapossibile migliorare la risoluzione dell’ADC indefinitamente. Mafino a che punto ha effettivamente senso spingersi con la tecnicadell’oversampling? La risposta è legata al rumore del segnale daacquisire e alla velocità con cui esso varia. In particolare,occorre rispettare il più stringente dei due vincoli seguenti. Oversampling vs. rumoreIl primo vincolo deriva dalla constatazione per cui è inutilescegliere un numero di bit tale che la risoluzione di tensione diingresso risulti inferiore al rumore di tensione del segnale daacquisire.Consideriamo, ad esempio, la tensione di 3.3V generata sulla schedaArduino UNO su cui si è misurato un rumore con un valore quadraticomedio RMS (Root Mean Square) di circa 100µV.Com’è noto, dal valore RMS si può stimare il valore picco-picco delrumore moltiplicando per un fattore pari a 6.6, ovvero: 6.6 × 100µV = 660µV Quindi, con una tensione VREF = 5V, si ottiene un numero di bit di: log2(5V / 660µV) = 12.887 ≈ 13 E dunque in questo caso, rispetto ai 10-bit di default, èragionevole implementare al massimo 3 bit di oversampling.Consideriamo, un altro esempio. Nel caso dell’accelerometro AnalogDevices ADXL50, la cui densità spettrale di rumore è 125µV/√Hzsupponendo che l’uscita sia filtrata passa-basso a 10Hz, si ricavaun valore quadratico medio (RMS) del rumore di: 125µV/√Hz × √10Hz ≈ 395µV Da cui si può stimare il valore picco-picco del rumore di tensione: 6.6 × 395µV ≈ 2.61mV Quindi, con una tensione VREF = 5V, si ottiene un numero di bit di:

Page 116: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

log2(5V / 2.61mV) = 10.9 ≈ 11 E dunque in questo caso, rispetto ai 10-bit di default, èragionevole implementare al massimo 1 bit di oversampling. Inoltre,essendo la sensibilità dell’accelerometro di 19mV/g (dove 1g =9.81m/s2) il valore picco-picco del rumore in termini diaccelerazione è pari a: 2.61mV / 19mV/g = 0.137g = 1.35m/s2 ESERCIZIO: Analog Devices ha sviluppato nuove generazioni diaccelerometri con prestazioni migliorate, come l’ADXL78 la cui lasensibilità è 55mV/g e la densità spettrale di rumore è 1.1mg/√Hz,ovvero: 55mV/g × 1.1mg/√Hz = 60.5µV/√Hz Supponendo ancora che la banda sia limitata a 10Hz, calcolare quantibit di oversampling è ragionevole implementare in questo casorispetto ai 10-bit di default e tensione VREF = 5V. Oversampling vs. velocità di variazioneIl secondo vincolo è legato alla considerazione per cui il massimonumero di bit di oversampling deve essere scelto anche in relazionealla rapidità di variazione del segnale che si desidera acquisire.Implementare l’oversampling richiede infatti di acquisire un numerodi sovra-campioni che cresce esponenzialmente all’aumentare delnumero di bit di oversampling. Considerando una scheda Arduino conun tempo di acquisizione di 112µs, 6 bit di oversampling richiedono: 46 × 112µs ≈ 460ms Mentre 9 bit richiedono: 49 × 112µs ≈ 29.4s Ad esempio, come si è detto più sopra, volendo monitorare conun’accuratezza di 0.1°C la temperatura interna di una cella termicache può variare di circa 10°C/min, è necessario campionare latemperatura al più ogni:

Page 117: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

0.1°C / 10°C/min = 600ms Quindi in questo caso il numero di bit di oversampling rispetto ai10-bit di default potrà essere al massimo log4(600ms / 112µs) ≈ 6

Page 118: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Le cifre significative in caso dioversamplingCon la tecnica dell’oversampling aumentano le cifre significative sucui ha senso rappresentare i valori acquisiti dall’ADC.Facendo riferimento alle considerazioni precedenti relative almassimo oversampling per misure di temperatura con un sensore ditipo TMP36 o LM35, la tabella seguente riassume la risoluzione e ilnumero di cifre significative al variare della tensione diriferimento e del numero di bit:

VREF [V] BITRISOLUZIONEDI TENSIONE

[mV]

DECIMALISIGNIFICATIVI DELLATENSIONE (in Volt)

RISOLUZIONE DITEMPERATURA

[°C]

DECIMALISIGNIFCATIVI DELLATEMPERATURA (in °C)

5 10 4.883 3 0.488 13.3 10 3.223 3 0.322 12.56 10 2.500 3 0.250 11.1 10 1.074 3 0.107 15 11 2.441 3 0.244 13.3 11 1.611 3 0.161 12.56 11 1.250 3 0.125 11.1 11 0.537 4 0.054 25 12 1.221 3 0.122 13.3 12 0.806 4 0.081 22.56 12 0.625 4 0.063 21.1 12 0.269 4 0.027 25 13 0.610 4 0.061 23.3 13 0.403 4 0.040 22.56 13 0.313 4 0.031 21.1 13 0.134 4 0.013 2

ESERCIZIO: Volendo utilizzare una scheda Arduino UNO per misurareuna temperatura è preferibile utilizzare un oversampling a 12-bitcon tensione VREF = 5V o un oversampling a 11-bit con tensione VREF =1.1V ?

Page 119: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

La frequenza di campionamento conoversamplingCome si è detto, in presenza di segnali che variano lentamente,ovvero con una banda inferiore a 10Hz, è possibile scegliere lafrequenza di campionamento considerando la rapidità con cui puòvariare il segnale da acquisire in relazione all’accuratezzadesiderata. Tuttavia, considerando di implementare la tecnicadell’oversampling, occorre ridurre l’intervallo di campionamento delfattore di oversampling. Ad esempio, riprendendo il caso dellamisura della temperatura sul balcone in città con Arduino UNO percui si era stimato necessario campionare al più ogni 143 secondi,aumentando la risoluzione da 10-bit a 12-bit (quindi con un fattoredi oversampling di 42 = 16), il massimo periodo di campionamentoscende a: 143s / 16 ≈ 9s In questo caso, una scelta adeguata potrebbe essere quella dicampionare la temperatura ogni 3.75 secondi così che, dopo 16campioni (ovvero ogni minuto), si otterrebbe in uscita il valorefinale a 12-bit.Volendo invece applicare un oversampling a 13-bit, ovvero con 43 =64 campioni, il massimo periodo di campionamento scende a: 143s / 64 ≈ 2.23s Anche in questo caso, una scelta adeguata potrebbe essere quella dicampionare la temperatura ogni 937 millisecondi così che dopo 64campioni (ovvero circa 1 minuto) si avrebbe in uscita il valorefinale a 13-bit. ESERCIZIO: Considerando una scheda Arduino UNO, valutarel’intervallo di campionamento per misurare con un’accuratezza di0.1°C la temperatura di una serra o di un appartamento dotato disistema di riscaldamento in cui la temperatura può variare di 10°Cin un’ora, nell’ipotesi di utilizzare un oversampling a 12-bit.

Page 120: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

Filtraggi avanzati per l’oversamplingA seconda delle applicazioni il filtro che opera la media sui 4Bcampioni aggiuntivi dell’oversampling può essere opportunamentemodificato in modo da adattarsi al particolare tipo di segnale daacquisire. Filtri a media ponderataSi tratta sempre di filtri di tipo FIR (Finite Impulse Response),dove segnale di uscita è ottenuto come la combinazione lineare di unnumero finito di campioni in ingresso. Per ottenere un oversamplingpiù “reattivo”, ovvero con una media che risponda più rapidamentealle variazioni del segnale, è possibile attribuire dei pesi diversiai campioni in modo che il contributo di quelli acquisiti prima siamaggiore.Quindi dove nel codice si calcolava la media aritmetica

si introducono i pesi, ovvero:

scegliendoli in modo che: p0 > p1 > … > p4B-1 e che:

La scelta può essere fatta in vari modi. Ad esempio, una soluzione èquella di utilizzare dei pesi decrescenti in modo lineare e, nel

Page 121: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

caso di oversampling a 12-bit, un’implementazione con numerirazionali può essere la seguente: p0 = 1.15; p1 = 1.13; p2 = 1.11; p3 = 1.09;p4 = 1.07; p5 = 1.05; p6 = 1.03; p7 = 1.01;p8 = 0.99; p9 = 0.97; p10 =0.95; p11 = 0.93;p12 = 0.91; p13 = 0.89; p14 = 0.87; p15 = 0.85 È molto utilizzata anche la cosiddetta Exponentially Weighted MovingAverage (EWMA) per la quale i pesi diminuiscano esponenzialmente.Per cui, ad esempio, un’implementazione con numeri razionali nelcaso di un oversampling a 11-bit può essere la seguente: p0 = 2.7; p1 = 0.9; p2 = 0.3; p3 = 0.1 Svantaggi nell’utilizzo della finestra mobileDal punto di vista dell’elaborazione del segnale, il filtro FIR conmedia a finestra mobile di durata L = 4B passi utilizzato perottenere l’oversampling è un filtro passa-basso la cui frequenza ditaglio è circa: FS / 2L = FS / (2 × 4B) = FS / 22B+1

Dove FS è la frequenza di campionamento del convertitore.Nel dominio del tempo la media smorza le variazioni realizzando uneffetto di smoothing sul segnale, quindi le transizioni brusche sonoattenuate. Infatti, questo filtraggio ha una risposta al gradinocaratterizzata da un ritardo di gruppo pari alla metà dei passi,ovvero 4B / 2. In termini temporali, detto τS l’intervallo dicampionamento, il ritardo introdotto dall’oversampling è τS × 4B / 2 In pratica, dovendo il filtro acquisire più letture e poi mediarle,il tempo di elaborazione dei dati aumenta e si riduce la risposta infrequenza del sistema e dunque anche la sua reattività.Nell’acquisizione di segnali analogici con Arduino è moltoimportante stabilire quale possa essere un ritardo accettabile perla particolare applicazione. La tabella seguente mostra i valori diritardo che si ottengono nel caso di τS = 100ms al crescere dei bit

Page 122: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

aggiuntivi di oversampling:

BIT aggiuntivi(oversampling) BIT totali FATTORE DI

OVERSAMPLINGRitardo

[campioni]Ritardo (τS =

100ms)1 11 4 2 200 ms2 12 16 8 800 ms3 13 64 32 3.2 s4 14 256 128 12.8 s

Filtri a medianaIl filtraggio a media dell’oversampling è efficace specialmente inpresenza di rumore gaussiano sui segnali in ingresso. Quando invecesono presenti disturbi impulsivi di ampiezza significativa, il lorocontributo nella media può incidere significativamente sul risultatofinale. In questo caso è preferibile utilizzare filtri non linearicome quello basato sulla mediana, che considera un certo numero dicampioni, li riordina in modo ascendente (o discendente) e poi neritorna il valore centrale.Tuttavia, se si sostituisse integralmente il filtraggio a mediadell’oversampling con quello a mediana non si otterrebbe il relativoaumento della risoluzione poiché questo deriva appunto dall’effettodella media dei valori quantizzati dell’ADC che genera nuovi livelliintermedi. Infatti, la mediana consentirebbe soltanto di escludere ivalori quantizzati dell’ADC corrispondenti a picchi anomali dovutial rumore sul segnale di ingresso, ma non produrrebbe un aumentodella risoluzione.Per ottenere dunque una buona immunità ai disturbi impulsivi e unaumento della risoluzione dell’ADC è necessario combinare i duefiltraggi a livello di codice con il seguente algoritmo: si acquisisce inizialmente un numero di campioni M maggiore diquello richiesto dal normale oversampling, ovvero M > 4B (convienescegliere un numero M pari) si ordinano i campioni aggiuntivi in ordine crescente (odecrescente); si esegue la media aritmetica sui 4B valori al centrodell’ordinamento, escludendo cioè dal calcolo i campioni più grandie più piccoli tra quelli acquisiti. Il rovescio della medaglia è che occorre acquisire un numeromaggiore di campioni e che l’ordinamento richiede un impegnocomputazionale più oneroso.Il numero di campioni che occorre acquisire in più rispetto a quelli

Page 123: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

richiesti dal normale oversampling dipende dall’ampiezza deidisturbi impulsivi a cui è soggetto il segnale di ingresso.Di seguito è riportato un esempio di sketch che implementa questofiltraggio nel caso di un oversampling a 13-bit con un’acquisizionedi M = 96 campioni anziché i 43 = 64 richiesti, nel caso di unamisura con un sensore di temperatura LM35 alimentato dalla tensione5V della scheda Arduino UNO, a sua volta alimentata con unalimentatore esterno, che in questo caso è da 9V. Si utilizza uncampionamento di 25ms e come tensione di riferimento per ilconvertitore la tensione bandgap di 1.1V generata internamenteall’ATmega328. In questo caso la risoluzione di temperatura iningresso è: ΔT = ΔV / G = VREF / (G × 2N) = 1.1V / (10mV/°C × 212) ≈ 0.01°C

Fig. 52 – Lo schema per l’esempio dell’acquisizione con filtraggio nel caso di unoversampling a 13-bit.

Page 124: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

byte analogPin = 0; // set the analog input to pin A0unsigned int total = 0; // variable storing the ADC averaged sumfloat ADC_value = 0.0; // variable storing the ADC readingunsigned int dummyreadings = 63; // set the number of initial ADC readings to discardfloat voltage = 0.0; // variable storing the calculated voltagefloat temperature = 0.0; // variable storing the calculated temperaturefloat vref = 1.090; // set the ADC voltage reference (it’s strongly suggested to use acalibrated voltage)unsigned int samples[95]; void setup() bitSet(DIDR0, ADC0D); // disable digital input on ADC0 analogReference(INTERNAL); for (int i = 0; i < dummyreadings; i++) unsigned int a = analogRead(analogPin); // ADC readings to discard Serial.begin(9600); // baud rate for the serial communication void loop() for (int i = 0; i < 96; i++) unsigned int a = analogRead(analogPin); // read the input on analogPin int j; if (a < samples[0] || i == 0) j = 0; //insert at the first position else for (j = 1; j < i; j++) if (samples[j - 1] <= a && samples[j] >= a) // j is the insert position break; for (int k = i; k > j; k--) // move all values higher than the current reading up one position samples[k] = samples[k - 1]; samples[j] = a; //insert the current reading total = 0; for (int i = 16; i < 80; i++) total += samples[i]; // accumulate ADC_value = (float)total / 64.0 + 0.0625; // average and compensate the quantization error[0.0625 = 0.5 / 8] voltage = ADC_value * vref / 1024.0; // calculate the corresponding voltage temperature = 100.0 * voltage; // calculate the corresponding temperature Serial.println(temperature, 2); // print the voltage with 2 decimal places delay(989); // delay to define the sampling time of 1s (1s = 1000ms = 989ms + 96samples x

Page 125: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

112us)

Page 126: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

BIBLIOGRAFIA Texas Instruments, LM35 Precision Centigrade Temperature Sensors,Rev. F, 01/2016. Atmel, ATmega48A/PA/88A/PA/168A/PA/328/P Datasheet Complete, Rev.J, 11/2015. Texas Instruments, LMT70, LMT70A ±0.05°C Precision AnalogTemperature Sensor, RTD and Precision NTC Thermistor IC, Rev. A,07/2015. M. Banzi & M. Shiloh, Getting Started with Arduino, O'Reilly Make,3rd Ed, 2014. T. Karvinen, K. Karvinen, V. Valtokari, Make: Sensors – A Hands-OnPrimer for Monitoring the Real World with Arduino and Raspberry Pi,O'Reilly Make, 2014. E. Williams, Make: AVR Programming Learning to Write Software forHardware, O'Reilly Make, 2014. A. Trevennor, Experimenting with AVR Microcontrollers, Apress,2014. J. Blum, Exploring Arduino: Tools and Techniques for EngineeringWizardry, John Wiley & Sons, 2013. Atmel, AVR127: Understanding ADC Parameters, 2013. Silicon Labs, AN118: Improving ADC resolution by oversampling andaveraging, 2013. C. Man, MT-229: Quantization Noise: An Expanded Derivation of theEquation SNR = 6.02 N + 1.76 dB, Analog Devices, 2012. Analog Devices, MT-228: High Speed ADC Analog Input InterfaceConsiderations, 2012. O. Leuthold, Investigation on Atmega328 Accuracy, 2012. M. Margolis, Arduino Cookbook, O'Reilly, 2nd Ed, 2011. D. Wheat, Arduino Internals, Apress, 2011. Atmel, Analog-to-Digital Converter in the SAM3S4, 2011. Freescale Semiconductor, AN2989: Application Note for Design,Accuracy, and Calibration of Analog to Digital Converters on theMPC5500 Family, 2010. NXP Semiconductors, AN10974 – LPC176x/175x 12-bit ADC designguidelines, 2010. Maxim Integrated, AN4466: Aperture Jitter Calculator for ADCs,2009. Honeywell, HIH-4030/31 Series – Humidity Sensors, 03/2008. Actel, Improving ADC Results Through Oversampling and Post-Processing of Data, 2007. Atmel, AVR120: Characterization and Calibration of the ADC on an

Page 127: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

AVR, 2006. N. Gray, ABCs of ADCs – Analog-to-Digital Converter Basics,National Semiconductor, 2006. Atmel, AVR121: Enhancing ADC resolution by oversampling, 2005. STMicroelectronics, AN1636: Understanding and minimising ADCconversion errors, 2003. Microchip, AN693: Understanding A/D Converter PerformanceSpecifications, 2002. S.W. Smith, The Scientist and Engineer's Guide to Digital SignalProcessing, 1997.

Page 128: La Conversione Analogico/Digitale conamici.cgel.me/libri/Giulio.Tamberi.La.conversione.ana... · 2017. 4. 10. · Atmel AVR: ─ ATmega328: è presente sulla celebre scheda Arduino/Genuino

CONTATTIGiulio Tamberi è nato a Livorno ed è cresciuto a La Spezia. Si èlaureato in Ingegneria Elettronica presso l’Università di Pisa. Daalcuni anni vive a Torino dove si è occupato della progettazionehardware di dispositivi mobile per il settore delleTelecomunicazioni. Attualmente è responsabile della qualità diprodotti elettronici in ambito Automotive. È un maker, appassionatodi tecnologie emergenti come la stampa 3D e, ovviamente,dell’universo Arduino.È possibile contattare l’autore per suggerimenti, idee o progetti aiseguenti recapiti:[email protected]://it.linkedin.com/in/giuliotamberihttps://twitter.com/giuliotamberi