capita abbastanza spesso di voler far lampeggiare un LED, e non a caso il primissimo esempio e' Blink. Tuttavia, Blink ha la caratteristica non del tutto ottimale di utilizzare chiamate a delay() (che sono bloccanti) per determinare il tempo di lampeggio. Come conseguenza, Arduino non puo' eseguire altre istruzioni mentre aspetta di dover cambiare lo stato del LED e produrre il lampeggio. Ci sono altre soluzioni basate sulla memorizzazione del numero di millisecondi passati dall'inizio e confrontarli con il valore voluto, ma anch equesti metodi richiedono una contabilita' che personalmente trovo noiosa.
Vi propongo uno sketch breve breve in cui, una volta definito che un LED deve lampeggiare, il lampeggiamento viene gestito "in automatico" tramite una routine di servizio all'interruzione di fine corsa del Timer0, la stessa che e' usata per la funzione millis(). L'estensione a periodi diversi da 200 ms e a Duty Cycle diversi dal 50% e' lasciata per esercizio. Senza ulteriore indugio:
Codice: Seleziona tutto
// 98 chiamate della routine di interrupt del Timer0,
// ossia 98*1.024 millisecondi = 100.4 ms
#define TLAMPEGGIO 98
// Definiamo anche a quale pin e' connesso il LED che deve lampeggiare
#define QUALEPIN 13
int conteggioLed; // Contatore per sapere quante volte
// e' stata gia' eseguita la ISR del Timer0
bool statoLed; // Se true il LED lampeggia
bool lampeggioLed; // per ricordare se il LED e' ON o OFF
void setup() {
// Il Timer0 e' gia' usato per la funzione millis(), quindi
// noi ci agganciamo e lampeggiamo il LED quando necessario
TIMSK0 |= _BV(OCIE0A);
// Ricordiamoci di definire il pin del LED come uscita
pinMode(QUALEPIN, OUTPUT);
// e finalmente, inizializziamo le variabili conteggioLed
conteggioLed = 0;
// e lampeggioLed (spento)
lampeggioLed = false;
}
// Questa funzione e' chiamata ogni millisecondo (per cui manteniamola breve!)
SIGNAL(TIMER0_COMPA_vect)
{
if (!statoLed) { // il LED deve stare spento
digitalWrite(QUALEPIN, LOW); // E basta...
} else { // il LED deve lampeggiare
conteggioLed++; // Incrementiamo il contatore delle esecuzioni
if (conteggioLed >= TLAMPEGGIO) { // Sono passati 100 ms
lampeggioLed = !(lampeggioLed); // Invertiamo lo stato
// Scriviamo il nuovo valore sul PIN
digitalWrite(QUALEPIN, (lampeggioLed ? HIGH : LOW));
// Azzeriamo il conteggio per ricominciare
conteggioLed = 0;
}
}
}
void loop() {
statoLed = true; // Non bisogna dimenticarsi di dare l'ordine di lampeggiare!
// Metti qui il codice da eseguire ripetutamente mentre il LED lampeggia
while(1) {
// Non fare niente! Arduino in vacanza!
}
}