Barra de 9 LEDs (Salidas Digitales Arduino Mega)
Conexión: Pin 13 al Pin 5 con resistencias limitadoras a GND
4 Pulsadores de Control (Entradas Digitales Pin 28, 26, 24, 22)
Haz clic en cada botón o usa las teclas 1, 2, 3, 4 de tu teclado
🔌 Asignación de Pines y Circuito Eléctrico
Detalle del montaje en la maqueta Arduino Mega 2560 y cálculo de resistencias.
| LED | Pin Arduino | Color | Conexión | Resistencia |
|---|---|---|---|---|
| LED 1 | Pin 13 | Rojo | Ánodo Pin 13 / Cátodo GND | 220Ω - 330Ω |
| LED 2 | Pin 12 | Ámbar | Ánodo Pin 12 / Cátodo GND | 220Ω - 330Ω |
| LED 3 | Pin 11 | Verde | Ánodo Pin 11 / Cátodo GND | 220Ω - 330Ω |
| LED 4 | Pin 10 | Rojo | Ánodo Pin 10 / Cátodo GND | 220Ω - 330Ω |
| LED 5 | Pin 9 | Ámbar | Ánodo Pin 9 / Cátodo GND | 220Ω - 330Ω |
| LED 6 | Pin 8 | Verde | Ánodo Pin 8 / Cátodo GND | 220Ω - 330Ω |
| LED 7 | Pin 7 | Rojo | Ánodo Pin 7 / Cátodo GND | 220Ω - 330Ω |
| LED 8 | Pin 6 | Ámbar | Ánodo Pin 6 / Cátodo GND | 220Ω - 330Ω |
| LED 9 | Pin 5 | Verde | Ánodo Pin 5 / Cátodo GND | 220Ω - 330Ω |
| Pulsador | Pin Arduino | Acción Ejecutada | Estado Activo |
|---|---|---|---|
| Pulsador 1 | Pin 28 | Enciende todos los LEDs | HIGH (+5V) |
| Pulsador 2 | Pin 26 | Apaga todos los LEDs | HIGH (+5V) |
| Pulsador 3 | Pin 24 | Secuencia 3 (Marquesina cíclica) | HIGH (+5V) |
| Pulsador 4 | Pin 22 | Secuencia 4 (Acumulativo cíclico) | HIGH (+5V) |
⚡ ¿Cómo está conectado el circuito Pull-Down en la maqueta?
En la maqueta web, cada pulsador tiene un terminal conectado a la línea de +5V y el otro terminal conectado simultáneamente al pin digital del Arduino y a GND a través de una resistencia de 4.7 kΩ (amarillo-violeta-rojo).
💻 Código Fuente Arduino (.ino)
Implementación limpia, modular, documentada y lista para cargar en Arduino IDE.
/*
=============================================================================
PROYECTO: Maqueta Arduino Mega 2560 - Práctica 2
SECUENCIA DE LEDS Y PULSADORES MULTITAREA CON MILLIS()
=============================================================================
*/
// --- ASIGNACIÓN DE PINES ---
const uint8_t PINES_LEDS[] = {13, 12, 11, 10, 9, 8, 7, 6, 5};
const uint8_t NUM_LEDS = sizeof(PINES_LEDS) / sizeof(PINES_LEDS[0]);
// Pulsadores reasignados (orden invertido: 28, 26, 24, 22)
const uint8_t PIN_PUL1 = 28; // Ahora el pin 28 enciende todos los LEDs
const uint8_t PIN_PUL2 = 26; // Ahora el pin 26 apaga todos los LEDs
const uint8_t PIN_PUL3 = 24; // Ahora el pin 24 activa la Secuencia 3
const uint8_t PIN_PUL4 = 22; // Ahora el pin 22 activa la Secuencia 4
// --- MÁQUINA DE ESTADOS ---
enum ModoOperacion {
MODO_APAGADO,
MODO_ENCENDIDO,
MODO_SECUENCIA_3,
MODO_SECUENCIA_4
};
ModoOperacion modoActual = MODO_APAGADO;
// --- TEMPORIZACIÓN CON MILLIS() ---
unsigned long tiempoUltimoPaso = 0;
const unsigned long INTERVALO_ANIMACION = 150; // milisegundos por paso
int pasoActual = 0; // Índice de avance en las secuencias
// --- ANTIRREBOTE (DEBOUNCE) Y FLANCOS ---
unsigned long tiempoUltimoRebote = 0;
const unsigned long TIEMPO_DEBOUNCE = 50; // 50 ms
int estadoPrevioPul1 = LOW;
int estadoPrevioPul2 = LOW;
int estadoPrevioPul3 = LOW;
int estadoPrevioPul4 = LOW;
void setup() {
Serial.begin(9600);
// Salidas para los 9 LEDs
for (uint8_t i = 0; i < NUM_LEDS; i++) {
pinMode(PINES_LEDS[i], OUTPUT);
}
// Entradas para los 4 pulsadores (Pull-Down externa)
pinMode(PIN_PUL1, INPUT);
pinMode(PIN_PUL2, INPUT);
pinMode(PIN_PUL3, INPUT);
pinMode(PIN_PUL4, INPUT);
apagarTodos();
}
void loop() {
leerPulsadores();
switch (modoActual) {
case MODO_ENCENDIDO:
// Permanecen encendidos
break;
case MODO_APAGADO:
// Permanecen apagados
break;
case MODO_SECUENCIA_3:
secuencia3(INTERVALO_ANIMACION);
break;
case MODO_SECUENCIA_4:
secuencia4(INTERVALO_ANIMACION);
break;
}
}
// Apaga todos los 9 LEDs
void apagarTodos() {
for (uint8_t i = 0; i < NUM_LEDS; i++) {
digitalWrite(PINES_LEDS[i], LOW);
}
}
// Enciende todos los 9 LEDs
void encenderTodos() {
for (uint8_t i = 0; i < NUM_LEDS; i++) {
digitalWrite(PINES_LEDS[i], HIGH);
}
}
// SECUENCIA 3: Enciende un LED y apaga el anterior (Cíclico)
void secuencia3(unsigned long retardo) {
unsigned long tiempoActual = millis();
if (tiempoActual - tiempoUltimoPaso >= retardo) {
tiempoUltimoPaso = tiempoActual;
apagarTodos();
digitalWrite(PINES_LEDS[pasoActual], HIGH);
pasoActual++;
if (pasoActual >= NUM_LEDS) {
pasoActual = 0; // Vuelve al primer LED (Pin 13)
}
}
}
// SECUENCIA 4: Enciende acumulando hasta el último y luego apaga todo (Cíclico)
void secuencia4(unsigned long retardo) {
unsigned long tiempoActual = millis();
if (tiempoActual - tiempoUltimoPaso >= retardo) {
tiempoUltimoPaso = tiempoActual;
if (pasoActual < NUM_LEDS) {
digitalWrite(PINES_LEDS[pasoActual], HIGH);
pasoActual++;
} else {
apagarTodos();
pasoActual = 0; // Reinicia el ciclo
}
}
}
// LECTURA DE PULSADORES CON DEBOUNCE
void leerPulsadores() {
unsigned long tiempoActual = millis();
if (tiempoActual - tiempoUltimoRebote < TIEMPO_DEBOUNCE) return;
int lecturaPul1 = digitalRead(PIN_PUL1);
int lecturaPul2 = digitalRead(PIN_PUL2);
int lecturaPul3 = digitalRead(PIN_PUL3);
int lecturaPul4 = digitalRead(PIN_PUL4);
// Pulsador 1: Encender todos
if (lecturaPul1 == HIGH && estadoPrevioPul1 == LOW) {
modoActual = MODO_ENCENDIDO;
encenderTodos();
tiempoUltimoRebote = tiempoActual;
}
// Pulsador 2: Apagar todos
else if (lecturaPul2 == HIGH && estadoPrevioPul2 == LOW) {
modoActual = MODO_APAGADO;
apagarTodos();
tiempoUltimoRebote = tiempoActual;
}
// Pulsador 3: Secuencia 3 (Marquesina cíclica)
else if (lecturaPul3 == HIGH && estadoPrevioPul3 == LOW) {
modoActual = MODO_SECUENCIA_3;
apagarTodos();
pasoActual = 0;
tiempoUltimoPaso = tiempoActual - INTERVALO_ANIMACION;
tiempoUltimoRebote = tiempoActual;
}
// Pulsador 4: Secuencia 4 (Acumulativo cíclico)
else if (lecturaPul4 == HIGH && estadoPrevioPul4 == LOW) {
modoActual = MODO_SECUENCIA_4;
apagarTodos();
pasoActual = 0;
tiempoUltimoPaso = tiempoActual - INTERVALO_ANIMACION;
tiempoUltimoRebote = tiempoActual;
}
estadoPrevioPul1 = lecturaPul1;
estadoPrevioPul2 = lecturaPul2;
estadoPrevioPul3 = lecturaPul3;
estadoPrevioPul4 = lecturaPul4;
}
🧠 Fundamentos: ¿Por qué usar millis() y no delay()?
Comparativa arquitectónica de temporización en sistemas embebidos.
❌ El problema de delay() [Bloqueante]
Anti-Patrón
Cuando se invoca delay(150), el microcontrolador entra en un bucle ciego de conteo de ciclos de reloj. Durante ese tiempo:
- No se pueden leer pulsadores: Si el usuario pulsa un botón durante el
delay, la pulsación se pierde por completo. - Paralización total: Ninguna otra tarea, comunicación serial o monitoreo puede ejecutarse.
- Animaciones toscas: Cambiar de secuencia requiere esperar a que termine el ciclo completo.
✅ La ventaja de millis() [No Bloqueante]
Multitarea
La función millis() devuelve el número de milisegundos transcurridos desde que arrancó el Arduino. Funciona como un cronómetro de fondo:
- Respuesta inmediata: El bucle
loop()se ejecuta decenas de miles de veces por segundo, detectando cualquier pulsación al instante. - Cambio de modo fluido: Al pulsar otro botón, se resetea el contador y la nueva animación comienza inmediatamente.
- Escalable a nivel industrial: Permite coordinar múltiples temporizadores, alarmas y sensores concurrentemente.