Simulador interactivo en tiempo real y guía didáctica paso a paso del código C++.
En la imagen de la Práctica 2 se utiliza una placa Arduino Mega 2560. Los componentes están cableados de la siguiente forma:
| Componente | Pines Arduino | Configuración Eléctrica |
|---|---|---|
| 9 Diodos LED | 13 al 5 (Desc.) | Ánodos (+) a pines digitales mediante resistencia limitadora de 220Ω / 330Ω a GND. (Lógica HIGH = ON). |
| Pulsador 1 | Pin 22 | Resistencia Pull-Down (10 kΩ a GND). Al pulsar envía 5V (HIGH). |
| Pulsador 2 | Pin 24 | Resistencia Pull-Down (10 kΩ a GND). Al pulsar envía 5V (HIGH). |
| Pulsador 3 | Pin 26 | Resistencia Pull-Down (10 kΩ a GND). Al pulsar envía 5V (HIGH). |
| Pulsador 4 | Pin 28 | Resistencia Pull-Down (10 kΩ a GND). Al pulsar envía 5V (HIGH). |
const byte pinesLeds[] = {13, 12, 11, 10, 9, 8, 7, 6, 5};
const byte totalLeds = sizeof(pinesLeds) / sizeof(pinesLeds[0]);
Esto permite añadir o quitar LEDs cambiando únicamente el arreglo sin tener que modificar el resto del código.
En lugar de ejecutar bucles infinitos dentro de la lectura del botón, se utiliza la variable modoActual como memoria (1: ON, 2: OFF, 3: Rápida, 4: Lenta). Al presionar un botón solo se actualiza el estado y el bucle loop() despacha la función correcta.
Si utilizáramos delay(300), el microcontrolador quedaría "congelado" esperando que transcurran los milisegundos. Durante ese tiempo, cualquier pulsación de botón sería completamente ignorada. Con millis(), el procesador evalúa constantemente la diferencia de tiempo transcurrido (millis() - tiempoAnterior >= retardo) y puede responder a los botones de forma instantánea.
Cumpliendo el requerimiento de la práctica, cada acción está aislada en su propia función:
encenderTodos(), apagarTodos(), secuencia(retardo) y reiniciarSecuencia().
El microcontrolador detiene su reloj interno en una espera activa. Durante 300 ms (o 1000 ms), no ejecuta ninguna instrucción:
El microcontrolador gira miles de veces por segundo en el loop(), consultando el cronómetro y los pulsadores:
Estructurado con modularidad, funciones reutilizables y temporización no bloqueante.
/*
* Práctica 2: Pulsadores, LEDs y secuencias con funciones
* Arduino Mega 2560
*
* Mapeo de pines:
* - LEDs (izquierda a derecha): 13, 12, 11, 10, 9, 8, 7, 6, 5
* - Pulsadores (izquierda a derecha): 22, 24, 26, 28
*/
// Pines de los 9 LEDs (de izquierda a derecha)
const byte pinesLeds[] = {13, 12, 11, 10, 9, 8, 7, 6, 5};
const byte totalLeds = sizeof(pinesLeds) / sizeof(pinesLeds[0]);
// Pines de los 4 pulsadores
const byte pinPul1 = 22; // Botón 1: Enciende todos
const byte pinPul2 = 24; // Botón 2: Apaga todos
const byte pinPul3 = 26; // Botón 3: Secuencia rápida
const byte pinPul4 = 28; // Botón 4: Secuencia lenta
// Variable para recordar el modo activo (1: ON, 2: OFF, 3: Rápida, 4: Lenta)
int modoActual = 2; // Inicia con todos apagados
// Variables para el control de tiempo y paso de secuencias sin bloquear
unsigned long tiempoAnterior = 0;
int pasoSecuencia = 0;
void setup() {
// Configuración de los pines de LEDs como salida
for (byte i = 0; i < totalLeds; i++) {
pinMode(pinesLeds[i], OUTPUT);
}
// Configuración de los pulsadores como entrada
pinMode(pinPul1, INPUT);
pinMode(pinPul2, INPUT);
pinMode(pinPul3, INPUT);
pinMode(pinPul4, INPUT);
// Estado inicial: todos apagados
apagarTodos();
}
void loop() {
// 1. Leer los pulsadores y actualizar el modo activo
leerPulsadores();
// 2. Ejecutar la función correspondiente al modo seleccionado
ejecutarModo();
}
// -------------------------------------------------------------
// FUNCIONES DE CONTROL Y LECTURA
// -------------------------------------------------------------
void leerPulsadores() {
if (digitalRead(pinPul1) == HIGH) {
if (modoActual != 1) {
modoActual = 1;
encenderTodos();
}
}
else if (digitalRead(pinPul2) == HIGH) {
if (modoActual != 2) {
modoActual = 2;
apagarTodos();
}
}
else if (digitalRead(pinPul3) == HIGH) {
if (modoActual != 3) {
reiniciarSecuencia();
modoActual = 3;
}
}
else if (digitalRead(pinPul4) == HIGH) {
if (modoActual != 4) {
reiniciarSecuencia();
modoActual = 4;
}
}
}
void ejecutarModo() {
switch (modoActual) {
case 1:
encenderTodos();
break;
case 2:
apagarTodos();
break;
case 3:
// Secuencia rápida: retardo de 80 ms por LED
secuencia(80);
break;
case 4:
// Secuencia lenta: retardo de 300 ms por LED
secuencia(300);
break;
}
}
void reiniciarSecuencia() {
apagarTodos();
pasoSecuencia = 0;
tiempoAnterior = millis();
}
// -------------------------------------------------------------
// FUNCIONES PEDIDAS PARA LOS LEDS
// -------------------------------------------------------------
// Función Botón 1: Enciende todos los LEDs
void encenderTodos() {
for (byte i = 0; i < totalLeds; i++) {
digitalWrite(pinesLeds[i], HIGH);
}
}
// Función Botón 2: Apaga todos los LEDs
void apagarTodos() {
for (byte i = 0; i < totalLeds; i++) {
digitalWrite(pinesLeds[i], LOW);
}
}
// Función Botones 3 y 4:
// Enciende de izquierda a derecha progresivamente y, al llegar al final,
// apaga todos y vuelve a empezar.
void secuencia(int retardo) {
if (millis() - tiempoAnterior >= (unsigned long)retardo) {
tiempoAnterior = millis();
if (pasoSecuencia < totalLeds) {
digitalWrite(pinesLeds[pasoSecuencia], HIGH);
pasoSecuencia++;
} else {
// Llegó al último: apaga todos y vuelve a empezar
apagarTodos();
pasoSecuencia = 0;
}
}
}