Objetivo y caso de uso
Qué construirás: Un temporizador de cuenta regresiva con relé autónomo para taller usando un Arduino UNO R3, pulsadores, un módulo de relé de 1 canal y un zumbador piezoeléctrico. Los usuarios pueden establecer una duración, iniciar una cuenta regresiva no bloqueante con millis(), mantener energizada una carga de 5 V o 12 V a través del relé mientras quede tiempo, y activar una alerta audible cuando el temporizador llegue a 0.
Por qué importa / Casos de uso
- Apagar automáticamente pequeñas cargas de banco como un ventilador de 5 V, una bomba en miniatura o una lámpara de prueba de 12 V después de un ciclo de trabajo fijo de 30 s a 10 min.
- Mejorar la repetibilidad en tareas de taller como calentamiento de adhesivos, extracción de humos de PCB, ciclos de limpieza o activación de útiles donde una temporización consistente importa más que la estimación manual.
- Enseñar habilidades fundamentales de sistemas embebidos en un solo montaje: lectura de botones, temporización de antirrebote en el rango de 10–50 ms, control de relé, retroalimentación con zumbador y lógica de máquina de estados finitos sin usar
delay(). - Funcionar totalmente de forma autónoma después de la carga, con respuesta de botones casi instantánea bajo tiempos de bucle típicos de unos pocos milisegundos y sin necesidad de conexión al PC.
Resultado esperado
- Un temporizador que permite al usuario aumentar o disminuir la duración con pulsadores y luego iniciar o detener la cuenta regresiva de forma fiable.
- Una salida de relé que permanece activa durante el intervalo programado y se apaga inmediatamente cuando expira el tiempo o se cancela el ciclo.
- Un patrón de zumbador al finalizar, por ejemplo 2–3 pitidos cortos durante 1–2 s, para señalar claramente el final de la ejecución temporizada.
- Una implementación de Arduino con baja carga y buena capacidad de respuesta: sin uso significativo de GPU, demanda muy baja de CPU en el ATmega328P y latencia de control inferior a 10 ms para eventos normales de botones y salidas.
Audiencia: principiantes de Arduino, makers, estudiantes y usuarios de talleres de electrónica; Nivel: principiante a intermedio-bajo
Arquitectura/flujo: Los pulsadores alimentan las entradas digitales del UNO; el sketch elimina el rebote de las pulsaciones, actualiza el tiempo seleccionado y rastrea el estado de la cuenta regresiva con millis(); el UNO acciona la entrada del relé para energizar la carga externa durante la ventana activa y conmuta el zumbador piezoeléctrico cuando la cuenta regresiva se completa.
Nota educativa de validación
Antes de publicar este caso, el contenido pasó la puerta automática de validación de Prometeo con estado PASS. El validador comprobó los bloques de código, la estructura del artículo, los comandos copiables y la coherencia con el catálogo de dispositivos soportados.
Evidencia de validación publicada
- Resultado automático: PASS.
- Estructura parseada: 3 apartados, 3 tablas y 2 bloques de código detectados antes de publicar.
- Código comprobado: 1 Arduino/arduino-cli compile, 1 Bash/copy-paste checks.
- Catálogo soportado: el texto se contrastó contra los perfiles de dispositivo validables de Prometeo y los stacks no soportados bloquean la publicación.
- Hallazgos del informe: sin hallazgos bloqueantes.
Esta validación confirma compatibilidad sintáctica y de herramientas para el material publicado, pero no sustituye la prueba física sobre tu hardware, cableado y entorno exactos.
Nota educativa de seguridad
Este prototipo está pensado para educación y experimentación a nivel de banco. Sus límites son importantes:
- No uses este montaje para principiantes para conmutar tensión de red doméstica a menos que estés capacitado y tu laboratorio lo permita explícitamente.
- Los módulos de relé pueden exponer tensiones peligrosas en sus terminales de contacto.
- Para validación en aula, usa solo una carga de CC de baja tensión.
- El lado Arduino y el lado de contactos del relé son dominios eléctricos distintos. Trata con cuidado el cableado de contactos del relé aunque el lado de control sea solo de 5 V.
- No uses este temporizador para controlar:
- herramientas críticas para la seguridad
- sistemas de calefacción desatendidos
- dispositivos médicos
- sistemas de vehículos
- maquinaria de alta potencia
- Si más adelante conectas motores, solenoides u otras cargas inductivas, pueden requerirse protección adicional y un diseño de alimentación adecuado.
- Mantén el cableado aislado, estable y con alivio de tensión. Un cableado de relé flojo puede crear conmutación poco fiable o cortocircuitos peligrosos.
- El zumbador piezoeléctrico es solo una ayuda de alerta. No se garantiza que se oiga en un taller ruidoso.
- Este tutorial muestra un prototipo educativo útil, no un producto certificado.
Prerrequisitos
Antes de empezar, asegúrate de tener:
- Familiaridad básica con el concepto del IDE de Arduino, aunque este tutorial usa Arduino CLI
- Un cable USB para el Arduino UNO R3
- Un ordenador con:
- Arduino CLI instalado
- Un terminal serie disponible, o el Monitor Serie del IDE de Arduino si lo prefieres
- Comprensión básica de:
- Entradas digitales con resistencias pull-up
- Salidas digitales
- Uso seguro de módulos de relé
- Una carga de baja tensión para probar la salida del relé
- Recomendado: una pequeña lámpara de CC, módulo de carga LED, ventilador de baja tensión o línea de alimentación de un pequeño motor de CC a través de los contactos del relé
- No empieces con cargas de red doméstica en un laboratorio para principiantes
Materiales
Usa exactamente la plataforma indicada a continuación.
- Arduino UNO R3 (ATmega328P)
- 3 pulsadores
Etiquetas sugeridas: - ADD
- START/PAUSE
- CANCEL/RESET
- Módulo de relé de 1 canal
- Versión de bobina/módulo de 5 V compatible con lógica Arduino
- Se prefiere un módulo con controlador por transistor y LED indicador de entrada
- Zumbador piezoeléctrico
- Zumbador pasivo o activo; este tutorial asume un zumbador piezoeléctrico simple que puede accionarse desde un pin digital
- Protoboard
- Cables jumper
- Cable USB para Arduino UNO R3
- Opcional pero recomendado:
- Pequeña lámpara o ventilador de CC de baja tensión como carga de prueba conmutada por el relé
- Fuente externa de baja tensión para esa carga de prueba si la carga lo requiere
Configuración/Conexión
Este proyecto usa las resistencias pull-up internas del Arduino para todos los pulsadores. Eso significa que cada botón se conecta entre el pin de entrada y GND. Cuando no se pulsa, la entrada lee HIGH. Cuando se pulsa, lee LOW.
Asignación de pines
| Función | Pin Arduino | Detalles de cableado |
|---|---|---|
| Botón ADD | D2 | Un lado del pulsador a D2, el otro lado a GND |
| Botón START/PAUSE | D3 | Un lado del pulsador a D3, el otro lado a GND |
| Botón CANCEL/RESET | D4 | Un lado del pulsador a D4, el otro lado a GND |
| Entrada de relé | D8 | IN del módulo de relé a D8 |
| Zumbador | D9 | Señal del zumbador a D9, tierra del zumbador a GND |
| VCC del relé | 5V | VCC del módulo de relé a 5V del Arduino |
| GND del relé | GND | GND del módulo de relé a GND del Arduino |
| GND del zumbador | GND | Tierra del zumbador a GND del Arduino |
| Alimentación/datos USB | USB | Arduino al ordenador |
Notas de conexión
- Pulsadores
- Conecta un terminal de cada botón al pin digital asignado.
- Conecta el otro terminal de cada botón a GND.
No se necesitan resistencias externas porque el sketch habilita
INPUT_PULLUP.Módulo de relé
- Conecta:
VCC->5VGND->GNDIN->D8
- Muchos módulos de relé son activos en bajo, lo que significa que el relé se enciende cuando el pin de Arduino entrega
LOW. El código siguiente está escrito para un módulo de relé activo en bajo común e incluye una constante que puedes cambiar si tu módulo es activo en alto.
Zumbador piezoeléctrico
- Conecta el pin positivo/señal a
D9. - Conecta el pin negativo a
GND. Para muchos zumbadores piezoeléctricos pequeños, la conexión directa es aceptable para un prototipo educativo básico.
Lado de contactos del relé
- Los terminales de contacto del relé están separados del lado Arduino.
- Para una salida controlada por temporizador, usa los terminales COM y NO del relé si quieres que la carga se encienda solo mientras la temporización esté activa.
- Mantén tu primera prueba simple:
- Usa una carga de baja tensión
- Usa una fuente conocida y segura
- Verifica que el relé conmuta correctamente antes de conectar algo más complejo
Comportamiento operativo sugerido
- Botón ADD: aumenta el tiempo preestablecido en 1 minuto, de 1 a 60 minutos, luego vuelve a 1
- Botón START/PAUSE: inicia el temporizador si está inactivo; pausa/reanuda si ya está en ejecución
- Botón CANCEL/RESET: detiene el temporizador y vuelve al valor preestablecido actual
- Retroalimentación del zumbador:
- Pitido corto en acciones válidas de botón
- Patrón distintivo de múltiples pitidos cuando se completa el tiempo
Código validado
workshop_countdown_relay_timer.ino
Vista pública parcial del archivo validado. El código completo se muestra a miembros y en PDF/Print.
/*
workshop_countdown_relay_timer.ino
Device model:
Arduino UNO R3 (ATmega328P) + pushbuttons + 1-channel relay module + piezo buzzer
Project goal:
workshop-countdown-relay-timer
Behavior:
- ADD button: increase preset time by 1 minute (1..60, wrap around)
- START/PAUSE button:
* if idle -> start countdown
* if running -> pause
* if paused -> resume
- CANCEL/RESET button:
* stop countdown
* relay off
* restore remaining time to preset
- Relay is active while countdown is running
- Buzzer gives short feedback on actions and a completion pattern at the end
Notes:
- Buttons use INPUT_PULLUP, so pressed = LOW
- Relay modules are often active-low; set RELAY_ACTIVE_LOW accordingly
*/
const byte PIN_BTN_ADD = 2;
const byte PIN_BTN_START = 3;
const byte PIN_BTN_CANCEL = 4;
const byte PIN_RELAY = 8;
const byte PIN_BUZZER = 9;
const bool RELAY_ACTIVE_LOW = true;
const unsigned long DEBOUNCE_MS = 35;
const unsigned long STATUS_PRINT_MS = 1000;
const unsigned long MINUTES_MAX = 60;
const unsigned long DEFAULT_PRESET_MIN = 5;
enum TimerState {
IDLE,
RUNNING,
PAUSED,
FINISHED
};
TimerState timerState = IDLE;
unsigned long presetMinutes = DEFAULT_PRESET_MIN;
unsigned long remainingMs = DEFAULT_PRESET_MIN * 60UL * 1000UL;
unsigned long lastTickMs = 0;
unsigned long lastStatusPrintMs = 0;
struct Button {
byte pin;
bool stableState;
bool lastReading;
unsigned long lastChangeMs;
};
Button btnAdd = {PIN_BTN_ADD, HIGH, HIGH, 0};
Button btnStart = {PIN_BTN_START, HIGH, HIGH, 0};
Button btnCancel = {PIN_BTN_CANCEL, HIGH, HIGH, 0};
void setRelay(bool on) {
if (RELAY_ACTIVE_LOW) {
digitalWrite(PIN_RELAY, on ? LOW : HIGH);
} else {
digitalWrite(PIN_RELAY, on ? HIGH : LOW);
}
}
void beep(unsigned int frequency, unsigned long durationMs) {
tone(PIN_BUZZER, frequency, durationMs);
}
void shortBeep() {
beep(2200, 70);
}
void doubleBeep() {
beep(2000, 60);
delay(100);
beep(2600, 80);
}
void finishBeepPattern() {
for (int i = 0; i < 3; i++) {
beep(1800, 120);
delay(180);
}
beep(2600, 350);
delay(400);
}
bool buttonPressedEvent(Button &button) {
bool reading = digitalRead(button.pin);
if (reading != button.lastReading) {
button.lastChangeMs = millis();
button.lastReading = reading;
}
if ((millis() - button.lastChangeMs) > DEBOUNCE_MS) {
if (reading != button.stableState) {
button.stableState = reading;
// Because INPUT_PULLUP is used, LOW means pressed
if (button.stableState == LOW) {
return true;
}
}
}
return false;
}
void printHelp() {
Serial.println(F("Workshop Countdown Relay Timer"));
Serial.println(F("Buttons:"));
Serial.println(F(" ADD -> +1 minute preset (1..60)"));
Serial.println(F(" START/PAUSE -> start, pause, resume"));
Serial.println(F(" CANCEL -> stop and reset to preset"));
Serial.println();
}
void printStateLine() {
unsigned long totalSeconds = remainingMs / 1000UL;
unsigned int minutesPart = totalSeconds / 60UL;
unsigned int secondsPart = totalSeconds % 60UL;
Serial.print(F("Preset="));
Serial.print(presetMinutes);
Serial.print(F(" min, Remaining="));
if (minutesPart < 10) Serial.print('0');
Serial.print(minutesPart);
Serial.print(':');
if (secondsPart < 10) Serial.print('0');
Serial.print(secondsPart);
Serial.print(F(", State="));
switch (timerState) {
case IDLE: Serial.print(F("IDLE")); break;
case RUNNING: Serial.print(F("RUNNING")); break;
case PAUSED: Serial.print(F("PAUSED")); break;
case FINISHED: Serial.print(F("FINISHED")); break;
}
// .../*
workshop_countdown_relay_timer.ino
Device model:
Arduino UNO R3 (ATmega328P) + pushbuttons + 1-channel relay module + piezo buzzer
Project goal:
workshop-countdown-relay-timer
Behavior:
- ADD button: increase preset time by 1 minute (1..60, wrap around)
- START/PAUSE button:
* if idle -> start countdown
* if running -> pause
* if paused -> resume
- CANCEL/RESET button:
* stop countdown
* relay off
* restore remaining time to preset
- Relay is active while countdown is running
- Buzzer gives short feedback on actions and a completion pattern at the end
Notes:
- Buttons use INPUT_PULLUP, so pressed = LOW
- Relay modules are often active-low; set RELAY_ACTIVE_LOW accordingly
*/
const byte PIN_BTN_ADD = 2;
const byte PIN_BTN_START = 3;
const byte PIN_BTN_CANCEL = 4;
const byte PIN_RELAY = 8;
const byte PIN_BUZZER = 9;
const bool RELAY_ACTIVE_LOW = true;
const unsigned long DEBOUNCE_MS = 35;
const unsigned long STATUS_PRINT_MS = 1000;
const unsigned long MINUTES_MAX = 60;
const unsigned long DEFAULT_PRESET_MIN = 5;
enum TimerState {
IDLE,
RUNNING,
PAUSED,
FINISHED
};
TimerState timerState = IDLE;
unsigned long presetMinutes = DEFAULT_PRESET_MIN;
unsigned long remainingMs = DEFAULT_PRESET_MIN * 60UL * 1000UL;
unsigned long lastTickMs = 0;
unsigned long lastStatusPrintMs = 0;
struct Button {
byte pin;
bool stableState;
bool lastReading;
unsigned long lastChangeMs;
};
Button btnAdd = {PIN_BTN_ADD, HIGH, HIGH, 0};
Button btnStart = {PIN_BTN_START, HIGH, HIGH, 0};
Button btnCancel = {PIN_BTN_CANCEL, HIGH, HIGH, 0};
void setRelay(bool on) {
if (RELAY_ACTIVE_LOW) {
digitalWrite(PIN_RELAY, on ? LOW : HIGH);
} else {
digitalWrite(PIN_RELAY, on ? HIGH : LOW);
}
}
void beep(unsigned int frequency, unsigned long durationMs) {
tone(PIN_BUZZER, frequency, durationMs);
}
void shortBeep() {
beep(2200, 70);
}
void doubleBeep() {
beep(2000, 60);
delay(100);
beep(2600, 80);
}
void finishBeepPattern() {
for (int i = 0; i < 3; i++) {
beep(1800, 120);
delay(180);
}
beep(2600, 350);
delay(400);
}
bool buttonPressedEvent(Button &button) {
bool reading = digitalRead(button.pin);
if (reading != button.lastReading) {
button.lastChangeMs = millis();
button.lastReading = reading;
}
if ((millis() - button.lastChangeMs) > DEBOUNCE_MS) {
if (reading != button.stableState) {
button.stableState = reading;
// Because INPUT_PULLUP is used, LOW means pressed
if (button.stableState == LOW) {
return true;
}
}
}
return false;
}
void printHelp() {
Serial.println(F("Workshop Countdown Relay Timer"));
Serial.println(F("Buttons:"));
Serial.println(F(" ADD -> +1 minute preset (1..60)"));
Serial.println(F(" START/PAUSE -> start, pause, resume"));
Serial.println(F(" CANCEL -> stop and reset to preset"));
Serial.println();
}
void printStateLine() {
unsigned long totalSeconds = remainingMs / 1000UL;
unsigned int minutesPart = totalSeconds / 60UL;
unsigned int secondsPart = totalSeconds % 60UL;
Serial.print(F("Preset="));
Serial.print(presetMinutes);
Serial.print(F(" min, Remaining="));
if (minutesPart < 10) Serial.print('0');
Serial.print(minutesPart);
Serial.print(':');
if (secondsPart < 10) Serial.print('0');
Serial.print(secondsPart);
Serial.print(F(", State="));
switch (timerState) {
case IDLE: Serial.print(F("IDLE")); break;
case RUNNING: Serial.print(F("RUNNING")); break;
case PAUSED: Serial.print(F("PAUSED")); break;
case FINISHED: Serial.print(F("FINISHED")); break;
}
Serial.print(F(", Relay="));
Serial.println((timerState == RUNNING) ? F("ON") : F("OFF"));
}
void resetToPreset() {
remainingMs = presetMinutes * 60UL * 1000UL;
lastTickMs = millis();
}
void handleAddButton() {
// For simplicity in a basic project, allow preset changes only when not running
if (timerState == RUNNING) {
doubleBeep();
Serial.println(F("ADD ignored while running. Pause or cancel first."));
return;
}
presetMinutes++;
if (presetMinutes > MINUTES_MAX) {
presetMinutes = 1;
}
resetToPreset();
if (timerState == FINISHED) {
timerState = IDLE;
}
shortBeep();
Serial.print(F("Preset changed to "));
Serial.print(presetMinutes);
Serial.println(F(" minute(s)."));
printStateLine();
}
void handleStartButton() {
if (timerState == IDLE || timerState == FINISHED) {
resetToPreset();
timerState = RUNNING;
setRelay(true);
lastTickMs = millis();
shortBeep();
Serial.println(F("Countdown started."));
printStateLine();
return;
}
if (timerState == RUNNING) {
timerState = PAUSED;
setRelay(false);
shortBeep();
Serial.println(F("Countdown paused."));
printStateLine();
return;
}
if (timerState == PAUSED) {
timerState = RUNNING;
setRelay(true);
lastTickMs = millis();
shortBeep();
Serial.println(F("Countdown resumed."));
printStateLine();
return;
}
}
void handleCancelButton() {
timerState = IDLE;
setRelay(false);
resetToPreset();
doubleBeep();
Serial.println(F("Countdown canceled and reset to preset."));
printStateLine();
}
void updateTimer() {
if (timerState != RUNNING) {
return;
}
unsigned long now = millis();
unsigned long elapsed = now - lastTickMs;
lastTickMs = now;
if (elapsed >= remainingMs) {
remainingMs = 0;
timerState = FINISHED;
setRelay(false);
Serial.println(F("Countdown complete. Relay turned OFF."));
printStateLine();
finishBeepPattern();
return;
}
remainingMs -= elapsed;
}
void setup() {
pinMode(PIN_BTN_ADD, INPUT_PULLUP);
pinMode(PIN_BTN_START, INPUT_PULLUP);
pinMode(PIN_BTN_CANCEL, INPUT_PULLUP);
pinMode(PIN_RELAY, OUTPUT);
pinMode(PIN_BUZZER, OUTPUT);
setRelay(false);
Serial.begin(9600);
delay(300);
printHelp();
resetToPreset();
printStateLine();
}
void loop() {
if (buttonPressedEvent(btnAdd)) {
handleAddButton();
}
if (buttonPressedEvent(btnStart)) {
handleStartButton();
}
if (buttonPressedEvent(btnCancel)) {
handleCancelButton();
}
updateTimer();
unsigned long now = millis();
if (now - lastStatusPrintMs >= STATUS_PRINT_MS) {
lastStatusPrintMs = now;
printStateLine();
}
}
Qué está haciendo el código
Este sketch usa una máquina de estados con cuatro estados:
IDLE– esperando entrada del usuarioRUNNING– cuenta regresiva activa, relé encendidoPAUSED– cuenta regresiva congelada, relé apagadoFINISHED– la cuenta regresiva llegó a cero, relé apagado, alerta del zumbador completada
Decisiones de diseño importantes y amigables para principiantes:
- Sin bucle de cuenta regresiva bloqueante
El temporizador usamillis()en lugar de undelay()largo, por lo que las pulsaciones de botones siguen siendo responsivas. - Botones con antirrebote
Cada botón se filtra con un pequeño intervalo de antirrebote para reducir activaciones falsas por rebote de contacto. - El tiempo preestablecido y el tiempo restante están separados
presetMinutesalmacena la duración elegida, mientras queremainingMsrastrea lo que queda durante una ejecución. - Salida de estado por serie
El Arduino imprime actualizaciones periódicas, lo que facilita mucho la resolución de problemas durante la validación.
Comandos de compilación/carga/ejecución
Tabla de comandos
| Propósito | Comando |
|---|---|
| Actualizar índice de placas | arduino-cli core update-index |
| Instalar núcleo AVR | arduino-cli core install arduino:avr |
| Compilar sketch | arduino-cli compile --fqbn arduino:avr:uno workshop_countdown_relay_timer |
| Cargar sketch | arduino-cli upload --fqbn arduino:avr:uno --port <PORT> workshop_countdown_relay_timer |
Ejemplo de sesión de terminal
arduino-cli core update-index
arduino-cli core install arduino:avr
arduino-cli compile --fqbn arduino:avr:uno workshop_countdown_relay_timer
arduino-cli upload --fqbn arduino:avr:uno --port <PORT> workshop_countdown_relay_timer
Flujo de trabajo corto
- Crea una carpeta llamada
workshop_countdown_relay_timer. - Guarda el sketch como:
workshop_countdown_relay_timer/workshop_countdown_relay_timer.ino- Abre una terminal en el directorio padre de esa carpeta.
- Ejecuta el comando de compilación.
- Conecta el Arduino UNO R3 por USB.
- Sustituye
<PORT>por tu puerto serie real y ejecuta el comando de carga. - Ejemplo Linux:
/dev/ttyACM0 - Ejemplo Windows:
COM4 - Ejemplo macOS:
/dev/cu.usbmodem14101 - Abre un monitor serie a 9600 baud para observar el estado del temporizador.
Validación paso a paso
Usa estos puntos de control en orden. El objetivo es validar el comportamiento exacto del temporizador de cuenta regresiva con relé para taller.
1. Encendido y estado inactivo
Acción
– Conecta el Arduino por USB.
– Abre el monitor serie a 9600 baud.
Observación esperada
– Deberías ver un banner de inicio como:
– Workshop Countdown Relay Timer
– También deberías ver una línea de estado con:
– Preset=5 min
– State=IDLE
– Relay=OFF
Condición de aprobación
– El relé no está energizado al arrancar.
– El monitor serie muestra el tiempo preestablecido y el estado inactivo sin caracteres aleatorios.
2. Ajuste del preajuste usando el botón ADD
Acción
– Pulsa el botón ADD una vez.
– Luego púlsalo varias veces más.
Observación esperada
– Cada pulsación aumenta el preajuste en 1 minuto.
– El monitor serie informa:
– Preset changed to 6 minute(s).
– y líneas de estado actualizadas
– Después de 60 minutos, la siguiente pulsación vuelve a 1 minuto.
Condición de aprobación
– Una pulsación de botón produce un cambio de preajuste.
– No se produce conteo doble frecuente por rebote del interruptor.
– El temporizador permanece en IDLE y el relé permanece apagado durante el ajuste del preajuste.
3. Iniciar la cuenta regresiva y confirmar la activación del relé
Acción
– Establece un preajuste de prueba corto como 1 minuto.
– Pulsa START/PAUSE una vez.
Observación esperada
– La salida serie dice:
– Countdown started.
– State=RUNNING
– Relay=ON
– El LED indicador del módulo de relé, si está presente, debería cambiar de estado.
– Tu carga de prueba de baja tensión conectada debería encenderse a través del relé.
Condición de aprobación
– El relé se activa solo cuando el temporizador entra en RUNNING.
– El tiempo restante disminuye una vez por segundo en el monitor serie.
4. Comportamiento de pausa, reanudación y cancelación
Acción
– Mientras está en ejecución, pulsa START/PAUSE otra vez.
– Púlsalo una vez más para reanudar.
– Luego pulsa CANCEL/RESET.
Observación esperada
– Al pausar:
– State=PAUSED
– Relay=OFF
– Al reanudar:
– State=RUNNING
– Relay=ON
– Al cancelar:
– Countdown canceled and reset to preset.
– State=IDLE
– Relay=OFF
Condición de aprobación
– La pausa detiene la cuenta regresiva sin perder el tiempo restante.
– La reanudación continúa desde el tiempo restante pausado.
– La cancelación apaga inmediatamente el relé y restaura el valor preestablecido completo.
5. Prueba de finalización de la cuenta regresiva
Acción
– Establece el preajuste en 1 minuto y deja que llegue a cero sin pulsar botones.
Observación esperada
– Al completarse:
– La salida serie informa Countdown complete. Relay turned OFF.
– El estado cambia a FINISHED
– El zumbador emite un patrón de finalización reconocible
– La carga de prueba de baja tensión se apaga en el mismo momento en que el relé se desactiva.
Condición de aprobación
– El relé se apaga automáticamente al agotarse el tiempo.
– El zumbador de finalización suena una vez por cada evento de finalización de cuenta regresiva.
– El sistema no se reinicia por sí solo.
Resolución de problemas
| Síntoma | Causa probable | Solución |
|---|---|---|
| La pulsación del botón no hace nada | Botón cableado a 5V en lugar de GND, pin incorrecto, mal contacto en la protoboard | Verifica que cada botón vaya entre el pin y GND, y coincida con D2/D3/D4 |
| El relé está siempre encendido | El comportamiento activo en bajo del módulo de relé no coincide, o error de cableado | Revisa RELAY_ACTIVE_LOW; si es necesario cámbialo a false y vuelve a cargar |
| El relé hace clic pero la carga no conmuta | Contactos COM/NO/NC cableados incorrectamente | Usa correctamente los terminales de contacto del relé; para comportamiento normal encendido-temporizado usa COM y NO |
| Zumbador silencioso | Polaridad del zumbador invertida, pin incorrecto o tipo de zumbador incompatible | Confirma que el zumbador esté en D9 y GND; prueba otro zumbador piezoeléctrico |
| El monitor serie muestra texto ilegible | Tasa de baudios incorrecta | Ajusta el monitor serie a 9600 baud |
| El temporizador se reinicia inesperadamente | Alimentación USB inestable o ruido de la carga afectando la fuente | Usa un cable USB estable, mantén ordenado el cableado del relé/carga y evita alimentar cargas ruidosas desde la línea de 5V del Arduino |
| Una pulsación provoca dos acciones | Rebote del interruptor o conexión floja | Vuelve a asentar los cables, usa mejores pulsadores y mantén corto el cableado de botones |
| La carga falla | Puerto incorrecto, falta el núcleo de la placa, problema de cable | Vuelve a ejecutar la instalación del núcleo, verifica el puerto, usa un cable USB con capacidad de datos conocido |
Mejoras
Mejoras de usabilidad
- Añade un display de 7 segmentos de 4 dígitos o LCD para mostrar el tiempo restante sin usar el monitor serie.
- Añade una función de pulsación larga en el botón ADD para ajustar el tiempo más rápido.
- Guarda el último preajuste en EEPROM para que el temporizador lo recuerde tras una pérdida de alimentación.
Funciones de control y temporización
- Añade un modo de ajuste de 10 segundos para temporización de procesos cortos.
- Añade una opción de silencio del zumbador después de la ejecución para que el temporizador pueda usarse en aulas más silenciosas.
- Añade un modo de sobretiempo del relé, donde un ventilador sigue funcionando un minuto extra después de que termina un ciclo de trabajo.
Robustez eléctrica
- Usa una carcasa de proyecto adecuada con botones etiquetados.
- Añade terminales de tornillo para el lado de la carga y alivio de tensión para los cables.
- Si conmutas cargas inductivas de CC, añade los métodos de supresión adecuados en el lado de la carga según el módulo y el tipo de carga.
Lista de verificación final
- [ ] Usé Arduino UNO R3 (ATmega328P)
- [ ] Usé 3 pulsadores, módulo de relé de 1 canal y zumbador piezoeléctrico
- [ ] Los botones están cableados desde el pin de entrada a GND
- [ ] El módulo de relé está conectado a 5V, GND y D8
- [ ] El zumbador está conectado a D9 y GND
- [ ] Guardé el archivo como
workshop_countdown_relay_timer/workshop_countdown_relay_timer.ino - [ ] Ejecuté
arduino-cli core update-index - [ ] Ejecuté
arduino-cli core install arduino:avr - [ ] Compilé con
arduino-cli compile --fqbn arduino:avr:uno workshop_countdown_relay_timer - [ ] Cargué con
arduino-cli upload --fqbn arduino:avr:uno --port <PORT> workshop_countdown_relay_timer - [ ] El monitor serie a 9600 baud muestra el estado de inicio
- [ ] ADD cambia el tiempo preestablecido
- [ ] START inicia la cuenta regresiva y enciende el relé
- [ ] PAUSE apaga el relé y conserva el tiempo restante
- [ ] CANCEL detiene el temporizador y restaura el preajuste
- [ ] La finalización de la cuenta regresiva apaga el relé y activa el patrón del zumbador
Encuentra este producto y/o libros sobre este tema en Amazon
Como afiliado de Amazon, gano con las compras que cumplan los requisitos. Si compras a través de este enlace, ayudas a mantener este proyecto.




