Lettura di un segnale analogico (lezione 4)
Introduzione
I fenomeni fisici, in natura, hanno quasi sempre un comportamento analogico, se noi consideriamo, per esempio, le variazioni della temperatura terrestre, la pressione atmosferica, la velocità del vento e così via, lascio a voi altri esempi, queste grandezze variano in modo continuo e per essere trattate, elaborate, da un dispositivo, come un microcontrollore, è necessario che esse siano convertite in forma digitale.
Il processo di conversione di un segnale analogico in forma digitale richiede l’utilizzo di un dispositivo ADC (Analog to Digital Converter).
Nella stragrande maggioranza dei casi, i microcontrollori, internamente, sono dotati di almeno un ADC, nel nostro caso, il microcontrollore di Arduino Uno, ATMEGA328, è equipaggiato con ben sei ADC, vista l’importanza di questo tipo di periferica, Microchip, azienda produttrice del suddetto microcontrollore, non ha lesinato con il numero di periferiche.
Nell’articolo che seguirà, approfondiremo i seguenti argomenti:
- Come gestire con Arduino la conversione e la lettura di un segnale analogico
- Come gestire, attivare e leggere la porta seriale di Arduino
Approfondimenti ADC (Analog to Digital Converter)
La decodifica di un segnale analogico nella forma digitale avviene tramite dei livelli di quantizzazione, cioè, l’intervallo di tensione su cui deve operare il nostro dispositivo, è suddiviso in intervalli costanti e in questo caso parliamo di quantizzazione uniforme (sarà discussione di un altro articolo l’approfondimento di altre tipologie di quantizzazione).
Il processo di conversione da analogico a digitale implica un errore di approssimazione, infatti, se il valore di tensione che deve essere convertito cade tra due livelli di quantizzazione, bisogna decidere a quale livello deve essere associato e la differenza tra il livello di quantizzazione associato e valore vero, corrisponde all’errore di approssimazione del sistema.
L’errore massimo si ottiene quando il valore da convertire cade proprio a metà tra i due livelli di quantizzazione.
Facciamo un esempio per chiarire il concetto del processo di quantizzazione, l’ADC del microcontrollore ATmega328, ha una risoluzione di 10 bit, questo equivale a dire che abbiamo 210 = 1024 combinazioni decifrabili, pertanto, se dobbiamo campionare un segnale analogico compreso nell’intervallo di tensione 0-5V, poiché, la tensione può assumere qualsiasi valore, in questo intervallo, ci sono infinite possibili combinazioni, ma il nostro ADC ha la possibilità di decodificare “solo” 1024 combinazioni.
La quantizzazione uniforme prevede la suddivisione, dell’intervallo di tensione, per il numero di combinazioni che l’ADC può discriminare:
5/1023= 4,88 10-3 V
Abbiamo diviso per 1023, poiche’ bisogna discriminare anche il valore zero.
L’intervallo di tensione dei livelli di quantizzazione è di 4,88 mV, nella Figura 1, è riportato un grafico sul processo di quantizzazione uniforme, ad ogni intervallo di tensione d’ingresso all’ADC, è associato un livello di decodifica, che per semplicita’ abbiamo inserito solo 8 livelli.
Con Vcon indica la tensione d’ingresso che deve essere convertita compresa tra due livelli di codifica (100 e 101), pertanto il sistema deve effettuare una approssimazione per difetto o eccesso.
Gli ingressi, in cui sono stati associati gli ADC sono contrassegnati sulla serigrafia della scheda con i simboli da A0 a A5 , come possiamo osservare dalla seguente Figura 2:
Leggere la tensione ai capi di un potenziometro
A titolo d’esempio, in questo articolo didattico, leggeremo la tensione ai capi di un potenziometro, tramite l’ADC integrato nel microcontrollore ATmega328, montato sulla scheda di Arduino Uno.
Il potenziometro ha tre terminali, e deve essere collegato come nella Figura 3.
A differenza del resistore che ha un valore di resistenza costante, il potenziometro, grazie ad una manopola o vite, presente al centro del dispositivo (vedi Figura 4), il valore di resistenza presente tra uno dei due terminali laterali e quello centrale può essere variato.
Se applichiamo una tensione ai due terminali esterni, al variare della rotazione della manopola, sia ha una variazione della tensione d’uscita sul terminale centrale.
Con il sistema appena descritto, possiamo variare la tensione all’ingresso dell’ADC e stampare, sul terminale del PC, il valore di tensione analogico letto.
// Sketch per la lettura dell'uscita di un potenziometro const int POT=0; // Ingresso del potenziometro A0 int val = 0; Variabile dove e' memorizzato la lettura del segnale analogico int Vpot = 0; Variabile dove e' memorizzatala conversione in tensione del valore digitale void setup() { Serial.begin(9600); } void loop() { val = analogRead(POT); Serial.println(val); delay(500); Vpot = (5/1023) * val Serial.println(Vpot); delay(500); }
Per leggere e convertire il segnale analogico usiamo la funzione analogRead(), tra le parentesi deve essere inserito il numero del pin , in cui è presente l’ADC ed è collegata l’uscita del potenziometro.
Analizziamo nel dettaglio il codice, svolge due principali azioni:
- Legge il segnale analogico
- Stampa sul terminale il valore analogico letto
Nel setup() la funzione Serial.begin() configura la seriale e tra le parentesi deve essere inserito il valore del Baud Rate (velocità di trasmissione dei dati) che non può essere scelto a piacere, ma deve essere selezionato tra i valori indicati nella tabella:
Baud Rate (Velocita’ di Trasmissione) |
300 bps |
1200 bps |
2400 bps |
4800 bps |
7200 bps |
4800 bps |
19.2 Kbps |
38.4 Kbps |
57.6 Kbps |
115.2 Kbps |
- val = analogRead(POT);
Legge il valore di tensione convertito e lo inserisce nella variabile “val”
- Serial.println(val);
Stampa sul terminale il valore della variabile “val”
- delay(500);
Ad ogni lettura ho inserito un ritardo di 500 ms per evitare letture troppo rapide.
I valori letti da Arduino sono compresi tra 0 e 1023, come abbiamo descritto in precedenza. Se ad ogni codice digitale letto volessimo associare un valore analogico di tensione, possiamo usare la seguente equazione:
- Vpot = (5/1023) * val;