Quando si legge un ingresso analogico usando la funzione analogRead(), si ottiene un numero compreso tra 0 e 1023. Ma quando si vuole generare un segnale PWM usando la funzione analogWrite(), si deve fornire un numero compreso tra 0 e 255. La funzione map() stabilisce una scala tra due intervalli di diversa larghezza.
Level = map(Level, 0, 1023, 0, 255);
Nell'esempio precedente, la funzione map() riceve, come primo parametro, una misura che rientra nell'intervallo tra 0 e 1023 (II e III parametro). Calcola il fattore di scala tra il primo intervallo e il secondo (0, 255) e restituisce il valore che, in proporzione, corrisponde nel secondo intervallo.
Se esiste la possibilità che il numero fornito a map() sia esterno all'intervallo 0-1023, allora la funzione restituirebbe numeri esterni all'intervallo 0-255. Per questa ragione, si usa la funzione constrain() che limita i numeri all'interno dell'intervallo 0-255. Se il numero cade all'esterno dell'intervallo verrà approssimato, altrimenti resta lo stesso valore.
Level = constrain(Level, 0, 255);
Il programma usa la fotoresistenza per controllare l'intensità luminosa del LED.
Notare che la d.d.p. prelevata sul partitore di tensione, non varia tra 0 e 5V, quindi i numeri letti oscilleranno, ad esempio, tra 300 (ombra) a 800 (luce). Di conseguenza, il LED non sarà mai completamente spento o completamente acceso.
Ci sono due funzioni manualTune() e autoTune()(togliere il commento per provare ciascuna di esse) che consentono di variare i limiti dell'intervallo.
Le due funzioni modificano la variabile lightLevel per coprire correttamente il range da acceso a spento.
Con l'istruzione digitalWrite si illumina il LED in base al valore di lightLevel. Per ottenere il comportamento opposto sostituire lightLevel con 255-lightLevel.
const int sensorPin =0 ;const int/ = ledPin 9 ;int lightLevel, high =0 ,low =1023 ;void setup() {pinMode( ;ledPin ,OUTPUT )} void loop() {lightLevel =analogRead( ; // si legge un numero tra 0 e 1023sensorPin )manualTune() ; // modifica manuale del range da luce a ombra.// autoTune() ; // modifica automaticaanalogWrite( ; // Ora si regola l'intensità luminosa del LED:ledPin, lightLevel )}
La funzione manualTune() consente di tarare l'intervallo. Si dovrebbe trovare, con vari tentativi, il numero corrispondente al livello di ombra tollerato, oltre il quale accendere il LED, e il livello di luce in corrispondenza del quale spegnere il LED. Il numero più piccolo corrisponde all'ombra e il numero più grande corrisponde alla luce.
Per individuare l'ampiezza dell'intervallo, modificare manualmente gli estremi specificati nella funzione map(). Provare a cambiare 0, 1023 in un intervallo più piccolo (da 300 a 800 per esempio). Se il LED non si spegne completamente, ridurre il numero più grande. Se il LED è sempre acceso, aumentare il numero più piccolo.
void manualTune() {lightLevel =map( ;lightLevel ,0, 1023, 0, 255 )lightLevel =constrain(lightLevel, 0, 255) ;}
La funzione autoTune() regola automaticamente l'intervallo. In questa funzione si utilizzano le due variabili low (che era stata inizializzata a 1023, il valore massimo) e high (che era stata inizializzata a 0, il valore minimo) per memorizzare il valore minimo e il valore massimo letto da analogRead().
I valori calcolati vengono passati alla funzione map(). Ai due valori, però viene aggiunto un offset, per impedire al LED di dare una luce tremolante.
void autoTune() {if ( lightLevel <low ) {low =lightLevel ;} if ( lightLevel >high ) {high =lightLevel ;} lightLevel = map( ;lightLevel, low +30 ,high -30, 0, 255 )lightLevel =constrain( ;lightLevel ,0, 255 )}
Scegliere un valore al di sotto del quale viene richiamata una funzione che fa lampeggiare il LED per 3 volte.