En este tutorial aprenderás a hacer parpadear múltiples LEDs juntos pero con diferentes frecuencias, retardos y ciclos de trabajo usando un Arduino o ESP32.
Hacer parpadear un solo LED es fácil y uno de los primeros ejemplos que aprendes al comenzar con la programación de Arduino. Sin embargo, hacer parpadear múltiples LEDs de forma independiente con diferentes frecuencias puede ser bastante complicado. En este tutorial usaremos la biblioteca ezOutput para simplificarlo. También te mostraré cómo convertir frecuencias y ciclos de trabajo en tiempos de retardo.
Pero antes de eso, veamos las piezas necesarias.
Piezas necesarias
A continuación la lista de piezas necesarias. Usé un Arduino Uno para este proyecto, pero cualquier otra placa Arduino, o placa ESP8266/ESP32 funcionará igual de bien. Y por supuesto, si ya tienes LEDs y resistencias adecuadas (220Ω), no necesitas comprarlos.

Arduino Uno

Cable USB para Arduino UNO

Juego de cables Dupont

Protoboard

Kit de resistencias y LEDs

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.
Qué es la frecuencia
Antes de construir el circuito y escribir el código, hablemos brevemente sobre qué es la frecuencia. Esto facilitará las cosas más adelante. Creo que la definición más sencilla de frecuencia es la siguiente:
La frecuencia es el número de veces que un patrón o evento se repite dentro de un segundo.
Por ejemplo, si un LED se enciende y apaga cuatro veces en un segundo, parpadeará con una frecuencia de 4 Hertz (Hz). Mira la imagen abajo, donde ilustramos la señal de conmutación para un LED.

El evento de encender y apagar el LED ocurre 4 veces en 1 segundo. Por lo tanto, la frecuencia es 4 Hz. Si encendiéramos y apagáramos el LED 10 veces en un segundo, parpadearía con una frecuencia de 10Hz.
Comúnmente, la fórmula para la frecuencia f se da como 1 dividida por el tiempo T que tarda en completarse un patrón (un evento de conmutación):

Es lo mismo, solo al revés ; ) Por ejemplo, si encendemos y apagamos el LED cuatro veces en un segundo (=4Hz), significa que T =1/4 = 0.25 segundos para un evento de conmutación. Pongámoslo en la fórmula anterior: 1/T = 1/0.25s = 4Hz.
Frecuencia de una onda senoidal
Ten en cuenta que la frecuencia no se limita a pulsos rectangulares o eventos de conmutación. Podemos calcular la frecuencia para cualquier tipo de patrón o evento repetitivo. Un caso frecuente es una onda senoidal, que podríamos usar para pulsar (atenuar hacia arriba y abajo) el brillo de un LED.
El ejemplo abajo muestra una onda senoidal durante dos periodos. Supongamos que un periodo dura 0.1 segundos. La onda senoidal tendría entonces una frecuencia de 10Hz.

Función tone() de Arduino
Ten en cuenta que el lenguaje Arduino tiene una función incorporada llamada tone() que permite crear una señal de onda cuadrada con una frecuencia que va desde 16Hz hasta 4MHz (usando un Arduino Uno). Sin embargo, para la mayoría de aplicaciones donde quieres hacer parpadear LEDs, incluso la frecuencia más baja de 16Hz suele ser demasiado rápida. A menudo queremos parpadear más lento y por eso no podemos usar tone() .
Además, tone() solo puede generar ondas cuadradas con un ciclo de trabajo del 50%. Hablemos rápidamente sobre los ciclos de trabajo y por qué eso es una limitación cuando queremos hacer parpadear LEDs.
Qué es el ciclo de trabajo
Supongamos que quieres encender y apagar un LED cada segundo. Ahora sabemos que eso sería una frecuencia de 1Hz. Pero ¿por cuánto tiempo durante ese segundo debería estar el LED encendido y por cuánto apagado? Si queremos que esté encendido el 50% de ese segundo (=0.5), eso sería un ciclo de trabajo del 50%. La definición de ciclo de trabajo es la siguiente:
El ciclo de trabajo es el porcentaje de tiempo que una señal está en alto comparado con el tiempo total de un periodo.
Entonces, si encendemos el LED solo por 0.1 segundos durante ese segundo, y lo dejamos apagado los restantes 0.9 segundos, eso sería un ciclo de trabajo del 10%. La imagen abajo ilustra tres ondas cuadradas con diferentes ciclos de trabajo.

Podrías pensar que podrías usar la señal PWM generada por analogWrite() para hacer parpadear LEDs con diferentes ciclos de trabajo. Sin embargo, nuevamente la frecuencia de la señal PWM es demasiado alta ( 490Hz / 980Hz ) para hacer parpadear LEDs, aunque puedes cambiar un poco la frecuencia. Pero es algo complejo y aún así no nos da las frecuencias que usualmente queremos para parpadear LEDs.
Hacer parpadear un solo LED
Hacer parpadear un solo LED con una frecuencia y ciclo de trabajo dados es fácil. Supongamos que tomamos nuestro ejemplo anterior y queremos hacer parpadear un LED con frecuencia 1Hz y ciclo de trabajo 50%. Eso significa que tenemos que encender el LED por 0.5 seg = 500 ms, apagarlo por otros 0.5 seg y repetir el ciclo. Eso es esencialmente el conocido ejemplo Blink:
void loop() {
digitalWrite(ledPin, HIGH);
delay(500);
digitalWrite(ledPin, LOW);
delay(500);
}
Podríamos hacerlo un poco más elegante y flexible implementando una función blink() para hacer parpadear un LED con una frecuencia dada f y un ciclo de trabajo dc :
void blink(int ledPin, float f, float dc) {
digitalWrite(ledPin, HIGH);
delay(1000 * dc / f);
digitalWrite(ledPin, LOW);
delay(1000 * (1 - dc) / f);
}
Esto es esencialmente lo mismo que antes pero calculamos el delay() basado en la frecuencia y el ciclo de trabajo. El retardo para la fase encendida del LED es 1000 * dc / f basado en la fórmula de frecuencia discutida arriba. El cálculo para la fase apagada es igual pero con el porcentaje restante del ciclo de trabajo 1 – dc en lugar de dc.
Una implementación completa para un LED conectado al pin 9 que parpadea con frecuencia 1Hz y ciclo de trabajo 50% sería así:
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);
}
Esto funciona bien para un solo LED pero no para múltiples LEDs con diferentes frecuencias. Pruébalo. Por ejemplo, no puedes hacer parpadear dos LEDs, uno con frecuencia 1Hz y otro con frecuencia 2Hz, usando el siguiente código.
// 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);
}
La razón es que los retardos (parpadeos) no se ejecutan de forma independiente (en paralelo) sino en secuencia.
Si quieres hacer parpadear múltiples LEDs con diferentes frecuencias y ciclos de trabajo, las cosas se complican mucho más. Tenemos un tutorial sobre eso: Control Multiple LEDs With Different Delays with Arduino . Y si necesitas más información sobre cómo hacer parpadear LEDs, echa un vistazo a How To Blink An LED Using Arduino (4 Different Ways ).
Sin embargo, en este tutorial vamos a usar la biblioteca ezOutput para controlar múltiples LEDs parpadeantes. Esto simplificará mucho nuestra tarea.
Usando la biblioteca ezOutput para hacer parpadear LEDs
Primero, necesitas instalar la ezOutput library a través del Library Manager antes de poder usarla.

Funciones principales de la biblioteca ezOutput
La biblioteca ezOutput tiene varias funciones pero solo necesitaremos tres.
La función ezOutput() , toma un pin como entrada y crea un objeto ezOutput alrededor de él. Proporciona las funciones especiales de pin que discutiremos a continuación.
ezOutput(int pin)
Con la función blink() puedes apagar un pin ( low ) y encenderlo ( high ) por intervalos de tiempo dados ( lowTime , highTime ). Los intervalos de tiempo están en milisegundos.
void blink(unsigned long lowTime, unsigned long highTime)
Podrías hacer eso con la función delay() también, como vimos en el ejemplo anterior. Pero la función blink() tiene la ventaja de que puede ser llamada independientemente para diferentes pines con diferentes retardos.
Para que eso suceda, necesitas llamar a la función loop() del ezObject() dentro del loop principal de Arduino.
void loop(void)
¿Suena complicado? En realidad es muy fácil. Veamos un ejemplo.
Hacer parpadear tres LEDs con diferentes tiempos de retardo
En el código de ejemplo abajo, haremos parpadear tres LEDs conectados a los pines 11, 10 y 9 con tres frecuencias y ciclos de trabajo diferentes.
#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();
}
Bibliotecas y objetos
Comenzamos incluyendo la biblioteca «ezOutput.h». Luego creamos tres instancias de la clase ezOutput llamadas led1, led2 y led3, cada una correspondiente a un LED diferente conectado a los pines 11, 10 y 9 respectivamente.
#include "ezOutput.h" ezOutput led1(11); ezOutput led2(10); ezOutput led3(9);
Función Setup
En la función setup() configuramos cada LED para que parpadee a una frecuencia y ciclo de trabajo específicos usando el método blink() de la biblioteca ezOutput . Los parámetros de intervalo de tiempo pasados al método blink() están elegidos para representar la frecuencia y ciclo de trabajo mostrados en los comentarios.
led1.blink(500, 500); // 1Hz, 50% duty cycle led2.blink(250, 250); // 2Hz, 50% duty cycle led3.blink(10, 90); // 10Hz, 90% duty cycle
Por ejemplo, para led1 : si queremos una frecuencia de parpadeo de 1Hz y un ciclo de trabajo del 50%, tenemos que encender el LED por 500 ms y luego apagarlo por otros 500 ms. Así que pasamos un tiempo apagado de 500 ms y un tiempo encendido de 500 ms a blink para lograr esto.
Si reducimos los tiempos de retardo a la mitad (250 ms), nuestro LED parpadea el doble de rápido, lo que nos da una frecuencia de 2Hz para led2 .
Y si queremos cambiar el ciclo de trabajo, necesitamos cambiar la proporción entre los tiempos encendido y apagado. Así, para led3 el tiempo encendido es 90 ms y el tiempo apagado es 10 ms, lo que nos da un ciclo de trabajo del 90% y una frecuencia de 10Hz.
Función Loop
En la función loop() llamamos continuamente al método loop() para cada objeto LED. Esto asegura que cada LED parpadee de forma independiente y según los parámetros de parpadeo establecidos en la función setup() .
void loop() {
led1.loop();
led2.loop();
led3.loop();
}
Este código funciona bien pero tienes que convertir frecuencias de parpadeo y ciclos de trabajo en tiempos encendido y apagado para la función blink. Podemos hacerlo más cómodo envolviendo esta parte en una función personalizada.
Hacer parpadear tres LEDs con diferentes frecuencias
Así que, en el siguiente ejemplo de código hacemos exactamente lo mismo que en el ejemplo anterior. Tres LEDs en los pines 11, 10 y 9 parpadearán con frecuencias 1Hz, 2Hz, 10Hz y ciclos de trabajo 50%, 50%, 90%, respectivamente.
#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();
}
Sin embargo, añadimos nuestra propia función setFrequency() que toma una frecuencia dada f y un ciclo de trabajo dc y los convierte en los parámetros lowTime y highTime necesarios para la función blink() .
void setFrequency(ezOutput &led, float f, float dc=0.5) {
led.blink(1000*(1-dc)/f, 1000*dc/f);
}
En lugar de blink() ahora podemos llamar a setFrequency() en la función setup() , directamente con frecuencias y ciclos de trabajo.
void setup() {
setFrequency(led1, 1, 0.5);
setFrequency(led2, 2, 0.5);
setFrequency(led3, 10, 0.9);
}
Ten en cuenta que proporcionamos los ciclos de trabajo como una proporción (0.9) y no como un porcentaje (90%). Si quieres usar porcentaje, solo divide el parámetro dc por 100 dentro de la función.
Con la función setFrequency() ahora puedes trabajar con frecuencias y ciclos de trabajo, en lugar de tiempos encendido y apagado, si te resulta más cómodo.
Este código también funcionará para ESP32 y ESP8266. Solo selecciona la placa correcta y cambia las constantes de los pines en consecuencia. Por ejemplo, yo uso los siguientes pines en mi placa WEMOS Lolin ESP32 lite:
ezOutput led1(GPIO_NUM_22); ezOutput led2(GPIO_NUM_19); ezOutput led3(GPIO_NUM_23);
A continuación, construyamos el circuito con los tres LEDs que queremos hacer parpadear.
Circuito de parpadeo con tres LEDs
La siguiente imagen muestra el circuito de parpadeo con sus tres LEDs y resistencias limitadoras de corriente.

Construirlo es fácil. Primero conecta tierra (GND) del Arduino con el riel de tierra de la protoboard (cable azul). Luego coloca los tres LEDs. Asegúrate de que los pines cortos de los LEDs (cátodo) estén conectados al riel de tierra.
Cada uno de los pines largos de los LEDs está conectado a una resistencia limitadora de corriente de 220Ω. Las resistencias están conectadas a los pines GPIO 11, 10 y 9 del Arduino. Y eso es todo. Ahí tienes tu circuito de parpadeo.
El siguiente video corto muestra el código y el circuito en acción. Los LEDs parpadean con frecuencias de 1Hz, 2Hz, 10Hz y ciclos de trabajo de 50%, 50%, 90%, respectivamente.

Diviértete experimentando con diferentes frecuencias, ciclos de trabajo y más LEDs.
Conclusiones
En conclusión, hemos aprendido con éxito cómo hacer parpadear múltiples LEDs juntos con diferentes frecuencias, retardos y ciclos de trabajo usando un Arduino o ESP32. Al entender los conceptos de frecuencia y ciclo de trabajo, pudimos crear un circuito para controlar los LEDs y escribir el código necesario para lograr los patrones de parpadeo deseados.
La biblioteca ezOutput hizo esto muy simple y pudiste ver que es fácil añadir tus propias funciones personalizadas para hacerlo aún más cómodo.
Si tienes alguna pregunta, echa un vistazo a las FAQ o escribe un comentario.
Diviértete ; )
Preguntas frecuentes
P: ¿Puedo usar diferentes tipos de LEDs con frecuencias variables en el mismo circuito?
R: Sí, puedes usar diferentes tipos de LEDs con frecuencias variables en el mismo circuito. Simplemente ajusta los tiempos de retardo en tu código para cada LED para lograr la frecuencia de parpadeo deseada.
P: ¿Es posible sincronizar el parpadeo de múltiples LEDs con diferentes frecuencias?
R: Aunque puede ser complicado sincronizar el parpadeo de múltiples LEDs con frecuencias significativamente diferentes, puedes experimentar ajustando los tiempos de retardo para lograr un patrón visualmente atractivo. Considera usar arrays o funciones para gestionar el tiempo de la secuencia de parpadeo de cada LED.
P: ¿Puedo controlar el brillo de cada LED junto con su frecuencia?
R: Sí, podrías usar una señal PWM durante el tiempo encendido del LED para lograr este efecto. Sin embargo, la biblioteca ezOutput no soporta esto directamente. Tendrías que modificar y ampliar el código.
P: ¿Cómo puedo añadir más LEDs al circuito y controlarlos individualmente?
R: Para añadir más LEDs al circuito y controlarlos individualmente, puedes conectar cada LED a un pin digital separado en el Arduino o ESP32. Luego, en tu código, define variables para el tiempo de retardo y ciclo de trabajo de cada LED para controlarlos de forma independiente.
P: ¿Cuál es el número máximo de LEDs que puedo hacer parpadear simultáneamente con diferentes frecuencias?
R: El número máximo de LEDs que puedes hacer parpadear simultáneamente con diferentes frecuencias depende de la potencia de procesamiento y memoria de tu microcontrolador. Normalmente, puedes controlar múltiples LEDs con frecuencias variables siempre que tengas suficientes pines digitales y memoria disponible para el código.
P: ¿Puedo usar componentes externos como transistores o registros de desplazamiento para ampliar el número de LEDs controlables?
R: Sí, puedes usar componentes externos como transistores o registros de desplazamiento para ampliar el número de LEDs controlables. Usando estos componentes, puedes aumentar efectivamente la cantidad de LEDs que puedes controlar con tu Arduino o ESP32, permitiendo patrones de iluminación más complejos. Para más detalles, consulta nuestro tutorial: More Arduino Outputs With 74HC595 Shift Register .
P: ¿Cómo calculo el tiempo de retardo para una frecuencia específica de parpadeo?
R: Para calcular el tiempo de retardo para una frecuencia específica de parpadeo, puedes usar la fórmula: tiempo de retardo = 1 / (2 * frecuencia). Por ejemplo, si quieres que un LED parpadee a 2 Hz (con un ciclo de trabajo del 50%), el tiempo de retardo sería 250 milisegundos.
P: ¿Cómo puedo crear patrones de LED más complejos, como efectos de desvanecimiento o pulsación?
R: Para crear patrones de LED más complejos como efectos de desvanecimiento o pulsación, puedes incorporar lógica adicional en tu código usando técnicas como interpolación lineal para efectos de desvanecimiento o funciones sinusoidales para efectos de pulsación. Manipulando los niveles de brillo a lo largo del tiempo, puedes lograr patrones de iluminación dinámicos.
P: ¿Es posible sincronizar el parpadeo de LEDs con eventos o sensores externos?
R: Sí, es posible sincronizar el parpadeo de LEDs con eventos o sensores externos incorporando lecturas de sensores o disparadores de eventos en tu código. Por ejemplo, puedes ajustar la frecuencia de parpadeo del LED basándote en entradas de sensores como intensidad de luz, temperatura o detección de movimiento.
P: ¿Puedo implementar diferentes patrones de parpadeo, como secuencias alternas o aleatorias, para múltiples LEDs?
R: Sí, puedes implementar diferentes patrones de parpadeo como secuencias alternas o aleatorias para múltiples LEDs definiendo patrones o secuencias únicas para cada LED en tu código. Sin embargo, para tales efectos, usar un registro de desplazamiento suele ser más fácil. Para más detalles, consulta nuestro tutorial: More Arduino Outputs With 74HC595 Shift Register
P: ¿Cómo puedo hacer que los LEDs parpadeen en un patrón específico, como un latido del corazón o una onda?
R: Para hacer que los LEDs parpadeen en patrones específicos como un latido del corazón o una onda, puedes definir secuencias personalizadas de estados encendido y apagado para cada LED en tu código. Programando el tiempo y las transiciones entre estos estados, puedes crear patrones de parpadeo únicos que imitan varios efectos.
P: ¿Puedo incorporar sonido o música para sincronizar el parpadeo de LEDs con señales de audio?
R: Sí, puedes sincronizar el parpadeo de LEDs con sonido o música analizando señales de audio o integrando bibliotecas de sonido en tu código. Detectando ritmos o frecuencias en la entrada de audio, puedes coordinar los patrones de parpadeo de los LEDs para que coincidan con el ritmo o la intensidad del sonido, mejorando la experiencia audiovisual.
P: ¿Cómo puedo hacer que los patrones de LED sean interactivos, respondiendo a entradas de usuario o comandos externos?
R: Para hacer que los patrones de LED sean interactivos y respondan a entradas de usuario o comandos externos, puedes implementar protocolos de comunicación como Bluetooth o Wi-Fi para recibir comandos desde un smartphone o computadora. Interpretando estas entradas en tu código, puedes ajustar dinámicamente los patrones de LED según las interacciones del usuario o disparadores externos.

