Arduino e il PWM

Da GolemWiki.
Jump to navigation Jump to search

Pulsante-arduino.gif Stai leggendo la guida "Arduino"


Arduino-pwmsig.gif

PWM, Pulse-Width Modulation, significa modulazione a larghezza d'impulso e consente di variare lo stato di un piedino digitale da HIGH a LOW e viceversa in modo periodico. I piedini digitali di Arduino Duemilanove e di Arduino Uno che possono eseguire questa funzionalità sono contrassegnati con PWM o con una tilde ~ e sono i n° 3, 5, 6, 9, 10, 11. Come vedi nell'immagine, l'impulso PWM è caratterizzato da un periodo, evidenziato in rosso, che su Arduino equivale a 20 millisecondi e da un duty cycle, ovvero la percentuale di tempo in cui l'impulso è HIGH. Ma a cosa serve? Abbiamo parlato dei led, che possono accendersi solo con una determinata tensione. Se volessi accenderne uno con una luminosità ridotta potrei collegarlo ad una resistenza maggiore, ma l'energia in eccesso verrebbe dissipata in calore. Attraverso il PWM invece posso variare rapidamente la tensione da 0 a 5v, così il LED passa da acceso a spento in modo talmente veloce che l'occhio non riesce a percepire un netto distacco buio/luce, ma avrà una sensazione di luminosità minore. Quindi, facendo riferimento al grafico in alto, più aumento la durata dello stato HIGH e più il LED sembrerà luminoso.

Esempi di impulsi PWM:
____________________
                     100% -> 255
_____     _____
     |___|     |____ 50%  -> 127
___       ___
   |_____|   |______ 30%  -> 85
_         _
 |_______| |________ 25%  -> 63
Arduino-pwm-schema.gif
//pwm.ino
const short pwm=9;
//Sensore analogico per variare il duty cycle
const short sensore=0;
void setup() {
	pinMode(pwm, OUTPUT);
}
void loop() {
	//Variabile che contiene il valore proporzionato letto dal sensore analogico
	byte valore=map(analogRead(sensore),0,1023,0,255);
	//Il valore viene attuato sul piedino PWM
	analogWrite(pwm,valore);
	//Piccola pausa
	delay(10);
}

Questo programma ti consente di sperimentare facilmente come funziona il PWM: se hai collegato tutto correttamente avrai costruito un varialuce, perché ruotando il potenziometro vedrai l'intensità luminosa del led variare. Riprendiamo un po' la teoria, dell'impulso posso variare la percentuale di tempo "HIGH", ovvero il duty cycle: questa percentuale viene espressa con un valore 0-255 (nota le potenze del 2 ricorrenti), e puoi variarlo facilmente con un sensore analogico, tipo il solito potenziometro; ruotandolo "al massimo" vedrai il led completamente acceso, che piano piano si spegne se ruoti la manopola del potenziometro. Per convertire il range 0-1023 in 0-255 ho usato la funzione map(), che avevamo già visto.

Musica, arduino!

Un buzzer: piccolo altoparlante

Chi ha studiato un po' di fisica o acustica saprà che il suono non è altro che una vibrazione, e che le casse suonano perché una sottile membrana magnetizzata viene eccitata a frequenza determinata da un'elettrocalamita, quindi si potrebbe usare il PWM per far suonare degli speaker. Detto così è molto tirato via, però è il principio applicabile in linea di massima per generare suoni su un piccolo altoparlante: il buzzer. Se hai un computer rotto lo puoi trovare lì, è quel componente che fa il bip all'accensione.

Per usarlo ti basta collegare il filo nero a massa, e quello rosso ad un piedino (se hai colori diversi fai una prova, e se funziona male li inverti), a questo punto carica il seguente listato;

#define DO3 262
#define RE3 294
#define MI3 330
#define FA3 349
#define SOL3 392
#define LA3 440
//...
const short buzzer=3;
void setup() {
}

void loop() {
	tone(buzzer, LA3);
	delay(500); //Suona il La per mezzo secondo
	noTone(buzzer);
	delay(500); //Mezzo secondo di pausa
	tone(buzzer, DO3);
	delay(300); //Suona il Do per 300 millisecondi
	noTone(buzzer);
	delay(500); //Mezzo secondo di pausa
}

Come saprai, il La fondamentale ha una frequenza di 440Hz, ma siccome la frequenza PWM è fissa a 50Hz è stata realizzata una funzione apposita che consente di variarla; per far suonare il buzzer basta chiamare Tone(pin,frequenza), e per farlo smettere noTone(pin).