Quando si opera con più ingressi analogici di Arduino possono accadere anomalie nella lettura. Questo accade perché la porta ADC è, in realtà, multiplexata. Se l’impedenza del sensore è maggiore di 10 kOhm, la lettura precedente da un pin può influenzare la lettura successiva su un pin diverso. Vediamo come risolvere tale problematica.
Il problema
L’utilizzo di un solo ingresso analogico, con Arduino, non comporta alcun problema. La lettura di un solo sensore, infatti, avviene nel migliore dei modi e i valori digitalizzati seguono fedelmente i risultati provenienti dal sensore. Se, invece, vengono utilizzati più sensori collegati a diverse porte analogiche, si possono verificare errori di lettura. Le successive letture, sovente, vengono influenzate dalle precedenti letture e sembrano non appartenere al dominio dei sensori utilizzati. Questo problema accade perché Arduino ha un ADC che è multiplexato tra gli ingressi analogici. Se l’impedenza del sensore è maggiore di 10 kOhm, la lettura precedente da un pin può influenzare la lettura successiva su un pin diverso. In altre parole la MCU di Arduino ha solo un singolo ADC. Per leggere i diversi pin analogici utilizza un multiplexer per collegare il pin che si desidera leggere al singolo ADC. L’ADC all’interno dell’MCU ha un condensatore “sample and hold” al suo interno. Quando si cambia il canale di acquisizione nello sketch, le cariche di questo condensatore sono trasportate da un canale di ingresso a quello successivo. Se il successivo canale di ingresso ha un’impedenza molto alta, le cariche sul condensatore influiscono sulla lettura. Gli altri pin non hanno nulla ad esso collegato, quindi la loro tensione è fluttuante.
Le soluzioni
Vi sono diverse soluzioni per aggirare il problema. Una di queste prevede di usare due funzioni analogRead() per ogni pin, possibilmente anche con un breve ritardo tra di loro. Si deve scartare la prima lettura e si deve usare la seconda. Il seguente codice di esempio fornisce subito l’idea della soluzione:
//---------ADC 0--------------
sensorValue0 = analogRead(A0);
delay(5);
sensorValue0 = analogRead(A0);
//---------ADC 1--------------
sensorValue1 = analogRead(A1);
delay(5);
sensorValue1 = analogRead(A1);
//---------ADC 2--------------
sensorValue2 = analogRead(A2);
delay(5);
sensorValue2 = analogRead(A2);
Se la velocità di acquisizione non è particolarmente importante, si possono eseguire più di due letture (ad esempio 10) e prendere sempre l’ultima. Il codice di esempio è il seguente:
//---------ADC 0-------------- for(int k=1;k<=10;k++) { sensorValue0 = analogRead(A0); delay(5); } //---------ADC 1-------------- for(int k=1;k<=10;k++) { sensorValue1 = analogRead(A1); delay(5); } //---------ADC 2-------------- for(int k=1;k<=10;k++) { sensorValue2 = analogRead(A2); delay(5); }
Conclusioni
Si ricorda di non applicare una tensione maggiore di 5 V all’ingresso dell’ADC, pena il danneggiamento del microcontrollore ATmega328P. Sarebbe anche consigliabile collegare a massa tutti gli ingressi analogici non utilizzati da A0 a A5.