Arduino: gestire gli ingressi analogici e le uscite PWM
Come sfruttare al massimo i comandi analogRead e analogWrite
Un punto di forza delle schede Arduino è sicuramente la semplicità con la quale ci hanno abituato a prelevare informazioni analogiche e gestire uscite digitali denominate PWM.
Ciò nonostante, se questa semplicità è stata complice ed amica dei neofiti, rischia di creare confusione e comporta forti limitazioni all’utilizzo dei microcontrollori presenti sulle schede.
Provvediamo quindi a fare subito chiarezza: gli ingressi analogici (che all’occorrenza possono essere utilizzati anche come uscite digitali) sono a tutti gli effetti degli ADC, ovvero dei convertitori analogico digitali. Tali convertitori prelevano una tensione confinata tra un valore di riferimento (0V, GND) e un valore massimo (identificato da qui in avanti con Vref). Tali parametri, per motivi legati alla prima scheda arduinoUNO, sono stati bloccati come standard: Vref viene fissata a 5V o 3.3V a seconda della scheda (e quindi il pin analogico può leggere valori da 0V a 5V o da 0V a 3.3V) e la risoluzione di lettura è di 8 bit (dove 2^8 = 1024 che sono gli intervalli di lettura). Banalmente, eseguendo la relazione Vref/intervalli si ricava la minima variazione rilevabile dall’ingresso analogico, ovvero circa 4,9 mV per alimentazione 5V e circa 3,3mV per le schede alimentate a 3,3V.
In certe occasioni può essere necessaria una risoluzione migliore e quindi si hanno due strade:
- Cambiare tensione Vref riducendola (con l’accortezza che poi di non superare tale valore all’ingresso analogico). Tale possibilità è realizzabile su tutte le schede Arduino, ma ogni microcontrollore ha i suoi parametri predefiniti riportati di seguito.
- Cambiare risoluzione di lettura da 8 bit a 12 bit. Di conseguenza 2^12 = 4096 intervalli che a loro volta permettono di calcolare 5V/4096 = 1,22 mV di sensibilità.
Se le due soluzioni non bastassero si possono utilizzare insieme per migliorare maggiormente l’accuratezza di lettura.
Introduciamo quindi il comando analogReference(TIPOLOGIA) il quale permette di modificare Vref andando di conseguenza a modificare la sensibilità di lettura. Le soglie di tensione adottabili sono riportate di seguito e suddivise per scheda.
Per modificare i bit di risoluzione di lettura analogica, invece, bisogna introdurre il comando analogReadResolution(BIT). Esso è disponibile per un numero limitato di schede poiché tale possibilità è integrata solo in alcuni microcontrollori. Le schede interessate sono: Arduino Zero, Arduino Due, tutta la famiglia MKR, Arduino Nano 33 (BLE e IoT) e la recente Portenta H7. Di default la risoluzione è impostata a 10 bit (quindi 2^10= 1024 intervalli), per le schede elencate si può impostare a 12 bit (quindi 2^12= 4096 intervalli). Effettuare una lettura analogica a 12bit comporta che la sensibilità diventa 5V/4096=1,22 mV (contro i 4,9mV di una lettura 10 bit).
Le stesse logiche sono riportabili anche nei termini della gestione dei terminali PWM i quali permettono una conversione da digitale ad analogico dove l’uscita viene discretizzata a vari livelli di tensione. Questo, grazie ad un onda quadra a dutycycle variabile e frequenza fissa, permette di ottenere un numero preciso di livelli di tensione compresi tra 0 e la tensione di alimentazione (5V o 3.3V). Tutte le schede Arduino sono impostate per gestire i terminali PWM a 8bit (da cui 2^8=256 livelli di tensione, pertanto se l’alimentazione è 5V basterà eseguire il calcolo 5V/256 per ottenere l’intervallo minimo di uscita, ovvero circa 19,5mV). Tale impostazione si può modificare sulle schede Arduino Due, la famiglia MKR e Arduino Zero con il comando analogWriteResolution(BIT).
Modificando la risoluzione a 12 bit significa che i livelli disponibili saranno 2^12=4096 e che l’intervallo minimo di tensione risulterà essere 3.3V/4096 = 0,8mV (ho riportato 3.3V nell’esempio poiché tali schede possiedono questa tensione di alimentazione).