Arduino Mega 2560 • Práctica 2

Pulsadores, LEDs y Secuencias con Funciones

Simulador interactivo en tiempo real y guía didáctica paso a paso del código C++.

9
LEDs (13..5)
4
Pulsadores (22..28)
OFF
Modo Activo
Banco de Pruebas: LEDs y Pulsadores en Tiempo Real
Usa los botones o las teclas 1 2 3 4
Pulsador 1 1
Pin 22 • HIGH
Enciende todos los 9 LEDs y los mantiene encendidos
Pulsador 2 2
Pin 24 • HIGH
Apaga todos los 9 LEDs y los mantiene apagados
Pulsador 3 3
Pin 26 • HIGH
Secuencia rápida acumulativa (80 ms por LED)
Pulsador 4 4
Pin 28 • HIGH
Secuencia lenta acumulativa (300 ms por LED)
Velocidad de Simulación:
Modo Operativo (modoActual)
2 (APAGADOS)
Paso Actual (pasoSecuencia)
0 / 9
Tiempo Simulado (millis())
0 ms
Retardo de Secuencia
N/A

1. Mapeo de Pines y Conexiones Físicas

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).
¿Por qué se usa una resistencia Pull-Down?
Si conectaras el pulsador directamente sin resistencia a tierra, cuando nadie lo presiona el pin quedaría "al aire" (estado de alta impedancia o flotante). El pin captaría ruido electromagnético ambiental, detectando pulsaciones falsas al azar. La resistencia Pull-Down garantiza un nivel lógico LOW (0V) estable en reposo.

2. Claves de Programación del Código C++

A. Arrays y cálculo dinámico de tamaño:

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.

B. Máquina de Estados (modoActual):

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.

C. La magia de millis() vs delay():

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.

D. Modularidad (Usar Funciones):

Cumpliendo el requerimiento de la práctica, cada acción está aislada en su propia función: encenderTodos(), apagarTodos(), secuencia(retardo) y reiniciarSecuencia().

¿Por qué tu código usa `millis()` y no `delay()`? Comparativa Gráfica

❌ Enfoque con `delay()` (Bloqueante)

El microcontrolador detiene su reloj interno en una espera activa. Durante 300 ms (o 1000 ms), no ejecuta ninguna instrucción:

LED 1 ON → delay(300) [CONGELADO] → LED 2 ON...
¡Si pulsas el Botón 2 (Apagar) mientras está en delay(), NO responde!

✔️ Enfoque con `millis()` (No Bloqueante - Tu Código)

El microcontrolador gira miles de veces por segundo en el loop(), consultando el cronómetro y los pulsadores:

¿Pasó el tiempo? No → Lee pulsadores → ¿Pasó? No → Lee...
¡Respuesta instantánea! Puedes cambiar de modo en cualquier microsegundo.
Código C++ para Arduino IDE (.ino)

Estructurado con modularidad, funciones reutilizables y temporización no bloqueante.

practica2_arduino_leds.ino Arduino Mega 2560 • C++
/*
 * 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;
    }
  }
}
Comprueba tus conocimientos sobre la Práctica
1. ¿Qué nivel de voltaje lee el pin de Arduino cuando se presiona un pulsador configurado en circuito Pull-Down?
A) LOW (0 Voltios) porque la resistencia va a tierra
B) HIGH (5 Voltios) porque el pulsador conecta la línea con VCC (+)
C) Un voltaje flotante indeterminado entre 1V y 4V
2. En la función `secuencia(retardo)`, ¿cuál es la ventaja clave de usar `millis() - tiempoAnterior >= retardo` frente a `delay(retardo)`?
A) Hace que los LEDs brillen con mayor intensidad luminosa
B) Ahorra memoria RAM al no necesitar variables de tipo long
C) Permite que el microcontrolador siga leyendo los pulsadores sin congelar la ejecución
3. ¿Qué hace la línea `const byte totalLeds = sizeof(pinesLeds) / sizeof(pinesLeds[0]);`?
A) Calcula automáticamente la cantidad de elementos en el arreglo dividiendo el tamaño total en bytes entre el tamaño de un elemento
B) Configura la velocidad de transmisión de los LEDs en el puerto serie
C) Convierte los números de pin de hexadecimal a decimal
Código copiado al portapapeles