In questo tutorial imparerai come far lampeggiare più LED insieme ma con frequenze, ritardi e cicli di lavoro diversi usando un Arduino o ESP32.
Far lampeggiare un singolo LED è facile ed è uno dei primi esempi che si imparano iniziando a programmare con Arduino. Tuttavia, far lampeggiare più LED in modo indipendente con frequenze diverse può diventare piuttosto complicato. In questo tutorial useremo la libreria ezOutput per semplificare il tutto. Ti mostrerò anche come convertire frequenze e cicli di lavoro in tempi di ritardo.
Ma prima di tutto, diamo un’occhiata ai componenti necessari.
Componenti necessari
Ecco la lista dei componenti necessari. Ho usato un Arduino Uno per questo progetto, ma qualsiasi altra scheda Arduino, o scheda ESP8266/ESP32 funzionerà altrettanto bene. E naturalmente, se hai già LED e resistori adatti (220Ω), non è necessario acquistarli.

Arduino Uno

Cavo USB per Arduino UNO

Set di fili Dupont

Breadboard

Kit di resistori e LED

Arduino IDE
Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.
Cos’è la Frequenza
Prima di costruire il circuito e scrivere il codice, facciamo una breve chiacchierata su cosa sia effettivamente la frequenza. Questo semplificherà le cose più avanti. Penso che la definizione più semplice di frequenza sia la seguente:
La frequenza è il numero di volte in cui un modello o evento si ripete in un secondo.
Per esempio, se un LED si accende e spegne quattro volte in un secondo, lampeggerebbe con una frequenza di 4 Hertz (Hz). Guarda l’immagine sotto, dove illustriamo il segnale di commutazione per un LED.

L’evento di accensione e spegnimento del LED avviene 4 volte in 1 secondo. Quindi la frequenza è 4 Hz. Se accendessimo e spegnessimo il LED 10 volte in un secondo, lampeggerebbe con una frequenza di 10Hz.
Comunemente, la formula per la frequenza f è data da 1 diviso per il tempo T necessario per completare un ciclo (evento di commutazione):

È la stessa cosa, solo al contrario ; ) Per esempio, se accendiamo e spegniamo il LED quattro volte in un secondo (=4Hz), significa che ci vogliono T =1/4 = 0,25 secondi per un evento di commutazione. Mettiamolo nella formula sopra: 1/T = 1/0,25s = 4Hz.
Frequenza di un’onda sinusoidale
Nota che la frequenza non è limitata a impulsi rettangolari o eventi di commutazione. Possiamo calcolare la frequenza per qualsiasi tipo di modello o evento ripetuto. Un caso frequente è un’onda sinusoidale, che potremmo usare per far pulsare (aumentare e diminuire) la luminosità di un LED.
L’esempio sotto mostra un’onda sinusoidale su due periodi. Supponiamo che un periodo duri 0,1 secondi. L’onda sinusoidale avrebbe quindi una frequenza di 10Hz.

Funzione tone() di Arduino
Nota che il linguaggio Arduino ha una funzione integrata chiamata tone() che permette di creare un segnale a onda quadra con frequenza da 16Hz fino a 4MHz (usando un Arduino Uno). Tuttavia, per la maggior parte delle applicazioni in cui vuoi far lampeggiare i LED, anche la frequenza più bassa di 16Hz è tipicamente troppo veloce. Spesso vogliamo lampeggiare più lentamente e quindi non possiamo usare tone() .
Inoltre, tone() può generare solo onde quadre con ciclo di lavoro al 50%. Parliamo brevemente dei cicli di lavoro e perché questo è un limite quando vogliamo far lampeggiare i LED.
Cos’è il ciclo di lavoro
Supponiamo di voler accendere e spegnere un LED ogni secondo. Ora sappiamo che sarebbe una frequenza di 1Hz. Ma per quanto tempo durante quel secondo il LED dovrebbe essere acceso e per quanto spento? Se vogliamo che sia acceso per il 50% di quel secondo (=0,5), allora il ciclo di lavoro è del 50%. La definizione di ciclo di lavoro è la seguente:
Il ciclo di lavoro è la percentuale di tempo in cui un segnale è alto rispetto al tempo totale di un periodo.
Quindi, se accendiamo il LED solo per 0,1 secondi durante quel secondo e lo lasciamo spento per i restanti 0,9 secondi, il ciclo di lavoro sarà del 10%. L’immagine sotto illustra tre onde quadre con cicli di lavoro diversi.

Potresti pensare di poter usare il segnale PWM generato da analogWrite() per far lampeggiare i LED con cicli di lavoro diversi. Tuttavia, ancora una volta la frequenza del segnale PWM è troppo alta ( 490Hz / 980Hz ) per far lampeggiare i LED, anche se puoi modificare un po’ la frequenza. Ma è un po’ complesso e comunque non ci dà le frequenze che solitamente vogliamo per far lampeggiare i LED.
Far lampeggiare un singolo LED
Far lampeggiare un singolo LED con una data frequenza e ciclo di lavoro è facile. Prendiamo l’esempio di prima e vogliamo far lampeggiare un LED con frequenza 1Hz e ciclo di lavoro 50%. Significa che dobbiamo accendere il LED per 0,5 sec = 500 msec, spegnerlo per altri 0,5 sec e ripetere il ciclo. Questo è essenzialmente il noto esempio Blink:
void loop() {
digitalWrite(ledPin, HIGH);
delay(500);
digitalWrite(ledPin, LOW);
delay(500);
}
Potremmo farlo in modo un po’ più elegante e flessibile implementando una funzione blink() per far lampeggiare un LED con una data frequenza f e un ciclo di lavoro dc :
void blink(int ledPin, float f, float dc) {
digitalWrite(ledPin, HIGH);
delay(1000 * dc / f);
digitalWrite(ledPin, LOW);
delay(1000 * (1 - dc) / f);
}
Questo è essenzialmente lo stesso di prima ma calcoliamo il delay() basandoci sulla frequenza e sul ciclo di lavoro. Il ritardo per la fase accesa del LED è 1000 * dc / f basandoci sulla formula della frequenza discussa sopra. Il calcolo per la fase spenta è lo stesso ma con la percentuale rimanente del ciclo di lavoro 1 – dc invece di dc.
Una implementazione completa per un LED collegato al pin 9 che lampeggia con frequenza 1Hz e ciclo di lavoro 50% sarebbe così:
int ledPin = 9;
void setup() {
pinMode(ledPin, OUTPUT);
}
void blink(int ledPin, float f, float dc) {
digitalWrite(ledPin, HIGH);
delay(1000 * dc / f);
digitalWrite(ledPin, LOW);
delay(1000 * (1 - dc) / f);
}
void loop() {
// 1 Hz, 50% duty cycle
blink(ledPin, 1, 0.5);
}
Funziona bene per un singolo LED ma non per più LED con frequenze diverse! Prova. Per esempio, non puoi far lampeggiare due LED, uno con frequenza 1Hz e l’altro con frequenza 2Hz, usando il codice seguente.
// This doesn't work!
void loop() {
// 1 Hz, 50% duty cycle
blink(ledPin1, 1, 0.5);
// 2 Hz, 50% duty cycle
blink(ledPi2, 2, 0.5);
}
Il motivo è che i ritardi (lampeggi) non vengono eseguiti in modo indipendente (in parallelo) ma in sequenza.
Se vuoi far lampeggiare più LED con frequenze e cicli di lavoro diversi, le cose si complicano molto. Abbiamo un tutorial su questo: Control Multiple LEDs With Different Delays with Arduino . E se ti serve più background su come far lampeggiare i LED, dai un’occhiata a How To Blink An LED Using Arduino (4 Different Ways ).
Tuttavia, in questo tutorial useremo la libreria ezOutput per controllare più LED lampeggianti. Questo semplificherà molto il nostro compito.
Usare la libreria ezOutput per far lampeggiare i LED
Per prima cosa, devi installare la ezOutput library tramite il Library Manager prima di poterla usare.

Funzioni principali della libreria ezOutput
La libreria ezOutput ha varie funzioni ma ne useremo solo tre.
La funzione ezOutput() prende un pin come input e crea un oggetto ezOutput attorno ad esso. Fornisce le funzioni speciali per il pin di cui parleremo dopo.
ezOutput(int pin)
Con la funzione blink() puoi spegnere un pin ( low ) e accenderlo ( high ) per intervalli di tempo dati ( lowTime , highTime ). Gli intervalli di tempo sono in millisecondi.
void blink(unsigned long lowTime, unsigned long highTime)
Potresti farlo anche con la funzione delay() , come abbiamo visto nell’esempio sopra. Ma la funzione blink() ha il vantaggio di poter essere chiamata indipendentemente per pin diversi con ritardi diversi.
Per farlo, devi chiamare la funzione loop() dell’oggetto ezObject() all’interno del loop principale di Arduino.
void loop(void)
Sembra complicato? In realtà è molto semplice. Vediamo un esempio.
Far lampeggiare tre LED con tempi di ritardo diversi
Nel codice di esempio qui sotto, faremo lampeggiare tre LED collegati ai pin 11, 10 e 9 con tre frequenze e cicli di lavoro diversi.
#include "ezOutput.h"
ezOutput led1(11);
ezOutput led2(10);
ezOutput led3(9);
void setup() {
led1.blink(500, 500); // 1Hz, dc=50%
led2.blink(250, 250); // 2Hz, dc=50%
led3.blink(10, 90); // 10Hz, dc=90%
}
void loop() {
led1.loop();
led2.loop();
led3.loop();
}
Librerie e oggetti
Iniziamo includendo la libreria “ezOutput.h”. Poi creiamo tre istanze della classe ezOutput chiamate led1, led2 e led3, ciascuna corrispondente a un LED collegato ai pin 11, 10 e 9 rispettivamente.
#include "ezOutput.h" ezOutput led1(11); ezOutput led2(10); ezOutput led3(9);
Funzione Setup
Nella funzione setup() configuriamo ogni LED per lampeggiare a una frequenza e ciclo di lavoro specifici usando il metodo blink() della libreria ezOutput . I parametri degli intervalli di tempo passati al metodo blink() sono scelti in modo da rappresentare la frequenza e il ciclo di lavoro mostrati nei commenti.
led1.blink(500, 500); // 1Hz, 50% duty cycle led2.blink(250, 250); // 2Hz, 50% duty cycle led3.blink(10, 90); // 10Hz, 90% duty cycle
Per esempio, per led1 : se vogliamo una frequenza di lampeggio di 1Hz e un ciclo di lavoro del 50%, dobbiamo accendere il LED per 500 msec e poi spegnerlo per altri 500 msec. Quindi passiamo un tempo spento di 500msec e un tempo acceso di 500msec a blink per ottenere questo.
Se dimezziamo i tempi di ritardo (250msec), il LED lampeggia il doppio più veloce, quindi con frequenza 2Hz per led2 .
E se vogliamo cambiare il ciclo di lavoro dobbiamo modificare il rapporto tra i tempi acceso e spento. Quindi, per led3 il tempo acceso è 90msec e il tempo spento è 10msec, che dà un ciclo di lavoro del 90% e una frequenza di 10Hz.
Funzione Loop
Nella funzione loop() chiamiamo continuamente il metodo loop() per ogni oggetto LED. Questo assicura che ogni LED lampeggi in modo indipendente e secondo i parametri di lampeggio impostati nella funzione setup() .
void loop() {
led1.loop();
led2.loop();
led3.loop();
}
Questo codice funziona bene ma devi convertire frequenze di lampeggio e cicli di lavoro in tempi acceso e spento per la funzione blink. Possiamo rendere questo più comodo racchiudendo questa parte in una funzione personalizzata.
Far lampeggiare tre LED con frequenze diverse
Nel codice di esempio seguente facciamo esattamente la stessa cosa dell’esempio sopra. Tre LED ai pin 11, 10 e 9 lampeggiano con frequenze 1Hz, 2Hz, 10Hz e cicli di lavoro 50%, 50%, 90%, rispettivamente.
#include "ezOutput.h"
ezOutput led1(11);
ezOutput led2(10);
ezOutput led3(9);
void setFrequency(ezOutput &led, float f, float dc=0.5) {
led.blink(1000*(1-dc)/f, 1000*dc/f);
}
void setup() {
setFrequency(led1, 1, 0.5);
setFrequency(led2, 2, 0.5);
setFrequency(led3, 10, 0.9);
}
void loop() {
led1.loop();
led2.loop();
led3.loop();
}
Tuttavia, abbiamo aggiunto la nostra funzione setFrequency() che prende una frequenza f e un ciclo di lavoro dc e li converte nei parametri lowTime e highTime necessari per la funzione blink() .
void setFrequency(ezOutput &led, float f, float dc=0.5) {
led.blink(1000*(1-dc)/f, 1000*dc/f);
}
Invece di blink() ora possiamo chiamare setFrequency() nella funzione setup() direttamente con frequenze e cicli di lavoro.
void setup() {
setFrequency(led1, 1, 0.5);
setFrequency(led2, 2, 0.5);
setFrequency(led3, 10, 0.9);
}
Nota che forniamo i cicli di lavoro come rapporto (0,9) e non come percentuale (90%). Se vuoi, basta dividere il parametro dc per 100 all’interno della funzione.
Con la funzione setFrequency() ora puoi lavorare con frequenze e cicli di lavoro, invece che con tempi acceso e spento, se ti è più comodo.
Questo codice funziona anche per ESP32 e ESP8266. Basta selezionare la scheda corretta e cambiare le costanti dei pin di conseguenza. Per esempio, io uso i seguenti pin sulla mia scheda WEMOS Lolin ESP32 lite:
ezOutput led1(GPIO_NUM_22); ezOutput led2(GPIO_NUM_19); ezOutput led3(GPIO_NUM_23);
Ora costruiamo il circuito con i tre LED che vogliamo far lampeggiare.
Circuito di lampeggio con tre LED
L’immagine seguente mostra il circuito di lampeggio con i suoi tre LED e i resistori di limitazione della corrente.

Costruirlo è facile. Prima collega il ground (GND) dell’Arduino alla linea di massa della breadboard (filo blu). Poi posiziona i tre LED. Assicurati che i piedini corti dei LED (catodo) siano collegati alla linea di massa.
Ognuno dei piedini lunghi dei LED è collegato a un resistore di limitazione da 220Ω. I resistori sono collegati ai pin GPIO 11, 10 e 9 dell’Arduino. Ecco fatto, il circuito di lampeggio è pronto.
Il breve video seguente mostra il codice e il circuito in azione. I LED lampeggiano con frequenze di 1Hz, 2Hz, 10Hz e cicli di lavoro di 50%, 50%, 90%, rispettivamente.

Divertiti a sperimentare con frequenze diverse, cicli di lavoro e più LED.
Conclusioni
In conclusione, abbiamo imparato con successo come far lampeggiare più LED insieme con frequenze, ritardi e cicli di lavoro diversi usando un Arduino o ESP32. Comprendendo i concetti di frequenza e ciclo di lavoro, siamo stati in grado di creare un circuito per controllare i LED e scrivere il codice necessario per ottenere i pattern di lampeggio desiderati.
La libreria ezOutput ha reso tutto molto semplice e hai potuto vedere che è facile aggiungere funzioni personalizzate per renderlo ancora più comodo.
Se hai domande, dai un’occhiata alle FAQ o scrivi un commento.
Divertiti ; )
Domande frequenti
D: Posso usare diversi tipi di LED con frequenze variabili nello stesso circuito?
R: Sì, puoi usare diversi tipi di LED con frequenze variabili nello stesso circuito. Basta regolare i tempi di ritardo nel codice per ogni LED per ottenere la frequenza di lampeggio desiderata.
D: È possibile sincronizzare il lampeggio di più LED con frequenze diverse?
R: Anche se può essere difficile sincronizzare il lampeggio di più LED con frequenze molto diverse, puoi sperimentare regolando i tempi di ritardo per ottenere un pattern visivamente piacevole. Considera l’uso di array o funzioni per gestire la temporizzazione di ogni sequenza di lampeggio dei LED.
D: Posso controllare la luminosità di ogni LED insieme alla sua frequenza?
R: Sì, potresti usare un segnale PWM durante il tempo acceso del LED per ottenere questo effetto. Tuttavia, la libreria ezOutput non supporta questo direttamente. Dovresti modificare ed estendere il codice.
D: Come posso aggiungere più LED al circuito e controllarli individualmente?
R: Per aggiungere più LED al circuito e controllarli individualmente, puoi collegare ogni LED a un pin digitale separato su Arduino o ESP32. Poi, nel codice, definisci variabili per il tempo di ritardo e il ciclo di lavoro di ogni LED per controllarli indipendentemente.
D: Qual è il numero massimo di LED che posso far lampeggiare simultaneamente con frequenze diverse?
R: Il numero massimo di LED che puoi far lampeggiare simultaneamente con frequenze diverse dipende dalla potenza di calcolo e dalla memoria del tuo microcontrollore. In genere, puoi controllare più LED con frequenze variabili finché hai abbastanza pin digitali e memoria disponibile per il codice.
D: Posso usare componenti esterni come transistor o shift register per espandere il numero di LED controllabili?
R: Sì, puoi usare componenti esterni come transistor o shift register per espandere il numero di LED controllabili. Usando questi componenti, puoi aumentare efficacemente il numero di LED che puoi controllare con Arduino o ESP32, permettendo pattern di illuminazione più complessi. Per maggiori dettagli dai un’occhiata al nostro tutorial: More Arduino Outputs With 74HC595 Shift Register .
D: Come calcolo il tempo di ritardo per una frequenza specifica di lampeggio?
R: Per calcolare il tempo di ritardo per una frequenza specifica di lampeggio, puoi usare la formula: tempo di ritardo = 1 / (2 * frequenza). Per esempio, se vuoi che un LED lampeggi a 2 Hz (con ciclo di lavoro 50%), il tempo di ritardo sarà di 250 millisecondi.
D: Come posso creare pattern di LED più complessi, come effetti di dissolvenza o pulsazione?
R: Per creare pattern di LED più complessi come effetti di dissolvenza o pulsazione, puoi incorporare logiche aggiuntive nel codice usando tecniche come l’interpolazione lineare per gli effetti di dissolvenza o funzioni sinusoidali per gli effetti di pulsazione. Manipolando i livelli di luminosità nel tempo, puoi ottenere pattern di illuminazione dinamici.
D: È possibile sincronizzare il lampeggio dei LED con eventi o sensori esterni?
R: Sì, è possibile sincronizzare il lampeggio dei LED con eventi o sensori esterni incorporando letture di sensori o trigger di eventi nel codice. Per esempio, puoi regolare la frequenza di lampeggio dei LED in base a input di sensori come intensità luminosa, temperatura o rilevamento di movimento.
D: Posso implementare pattern di lampeggio diversi, come sequenze alternate o casuali, per più LED?
R: Sì, puoi implementare pattern di lampeggio diversi come sequenze alternate o casuali per più LED definendo pattern o sequenze uniche per ogni LED nel codice. Tuttavia, per questi effetti usare uno shift register è spesso più semplice. Per maggiori dettagli dai un’occhiata al nostro tutorial: More Arduino Outputs With 74HC595 Shift Register
D: Come posso far lampeggiare i LED in un pattern specifico, come un battito cardiaco o un’onda?
R: Per far lampeggiare i LED in pattern specifici come un battito cardiaco o un’onda, puoi definire sequenze personalizzate di stati acceso e spento per ogni LED nel codice. Programmando la temporizzazione e le transizioni tra questi stati, puoi creare pattern di lampeggio unici che imitano vari effetti.
D: Posso incorporare suoni o musica per sincronizzare il lampeggio dei LED con segnali audio?
R: Sì, puoi sincronizzare il lampeggio dei LED con suoni o musica analizzando segnali audio o integrando librerie audio nel codice. Rilevando battiti o frequenze nell’input audio, puoi coordinare i pattern di lampeggio dei LED per abbinare il ritmo o l’intensità del suono, migliorando l’esperienza audiovisiva.
D: Come posso rendere i pattern dei LED interattivi, rispondendo a input utente o comandi esterni?
R: Per rendere i pattern dei LED interattivi e reattivi a input utente o comandi esterni, puoi implementare protocolli di comunicazione come Bluetooth o Wi-Fi per ricevere comandi da uno smartphone o computer. Interpretando questi input nel codice, puoi regolare dinamicamente i pattern dei LED in base alle interazioni dell’utente o trigger esterni.

