#include <Arduino.h>
// Entradas - botones
const int encendido_apagado = 34;
const int agua = 35;
const int jabon = 32;
const int inicio_pausa = 33;
// Salidas - LEDs indicadores de botones
const int led_encendido_apagado = 25;
const int led_agua = 26;
const int led_jabon = 27;
const int led_inicio_pausa = 14;
// Motor DC simulado (puente H)
const int motor_A = 12; // Hacia adelante
const int motor_B = 13; // Hacia atrás
// Pines de segmentos del display 7 segmentos (cátodo común)
const int segA = 2;
const int segB = 4;
const int segC = 15;
const int segD = 19;
const int segE = 21;
const int segF = 22;
const int segG = 23;
// LED de fin de ciclo
const int ledFinal = 5;
// Estados posibles
enum Estado {
REPOSO,
LAVADO,
ENJUAGUE,
CENTRIFUGADO
};
Estado estado = REPOSO;
bool enPausa = false;
bool cicloIniciado = false;
// Segmentos para mostrar 0-3 en display
const byte segmentos[4][7] = {
{1,1,1,1,1,1,0}, // 0 - Reposo
{0,1,1,0,0,0,0}, // 1 - Lavado
{1,1,0,1,1,0,1}, // 2 - Enjuague
{1,1,1,1,0,0,1} // 3 - Centrifugado
};
// Estructura para botones con antirrebote
struct Boton {
const int pin;
bool estadoActual = false;
bool estadoAnterior = false;
unsigned long ultimoCambio = 0;
bool fuePresionado = false;
};
Boton btnEncendido = {encendido_apagado};
Boton btnAgua = {agua};
Boton btnJabon = {jabon};
Boton btnInicioPausa = {inicio_pausa};
const unsigned long debounceDelay = 50;
// Nuevos tiempos
const unsigned long duracionLavado = 10000;
const unsigned long duracionEnjuague = 15000;
const unsigned long duracionCentrifugado = 12000;
unsigned long tiempoEstado = 0;
unsigned long tiempoMotor = 0;
bool motorDir = false;
// Antirrebote
void actualizarBoton(Boton &boton) {
bool lectura = digitalRead(boton.pin);
if (lectura != boton.estadoAnterior) {
boton.ultimoCambio = millis();
boton.estadoAnterior = lectura;
}
if ((millis() - boton.ultimoCambio) > debounceDelay) {
if (lectura != boton.estadoActual) {
boton.estadoActual = lectura;
if (boton.estadoActual == HIGH) {
boton.fuePresionado = true;
}
}
}
}
// Mostrar número en display
void mostrarDisplay(int numero) {
digitalWrite(segA, segmentos[numero][0]);
digitalWrite(segB, segmentos[numero][1]);
digitalWrite(segC, segmentos[numero][2]);
digitalWrite(segD, segmentos[numero][3]);
digitalWrite(segE, segmentos[numero][4]);
digitalWrite(segF, segmentos[numero][5]);
digitalWrite(segG, segmentos[numero][6]);
}
// Parpadear LED fin de ciclo
void parpadearFin() {
for (int i = 0; i < 6; i++) {
digitalWrite(ledFinal, HIGH);
delay(300);
digitalWrite(ledFinal, LOW);
delay(300);
}
}
// Control motor
void motorAdelante() {
digitalWrite(motor_A, HIGH);
digitalWrite(motor_B, LOW);
}
void motorAtras() {
digitalWrite(motor_A, LOW);
digitalWrite(motor_B, HIGH);
}
void motorDetener() {
digitalWrite(motor_A, LOW);
digitalWrite(motor_B, LOW);
}
// Actualizar estado general (solo display y mensajes)
void actualizarEstado() {
switch (estado) {
case REPOSO:
mostrarDisplay(0);
Serial.println("🟢 Estado: REPOSO");
break;
case LAVADO:
mostrarDisplay(1);
Serial.println("🧼 Estado: LAVADO");
break;
case ENJUAGUE:
mostrarDisplay(2);
Serial.println("💧 Estado: ENJUAGUE");
break;
case CENTRIFUGADO:
mostrarDisplay(3);
Serial.println("🔄 Estado: CENTRIFUGADO");
break;
}
}
void setup() {
Serial.begin(115200);
pinMode(encendido_apagado, INPUT);
pinMode(agua, INPUT);
pinMode(jabon, INPUT);
pinMode(inicio_pausa, INPUT);
pinMode(led_encendido_apagado, OUTPUT);
pinMode(led_agua, OUTPUT);
pinMode(led_jabon, OUTPUT);
pinMode(led_inicio_pausa, OUTPUT);
pinMode(motor_A, OUTPUT);
pinMode(motor_B, OUTPUT);
pinMode(segA, OUTPUT);
pinMode(segB, OUTPUT);
pinMode(segC, OUTPUT);
pinMode(segD, OUTPUT);
pinMode(segE, OUTPUT);
pinMode(segF, OUTPUT);
pinMode(segG, OUTPUT);
pinMode(ledFinal, OUTPUT);
actualizarEstado();
}
void loop() {
unsigned long ahora = millis();
actualizarBoton(btnEncendido);
actualizarBoton(btnAgua);
actualizarBoton(btnJabon);
actualizarBoton(btnInicioPausa);
// LEDs de botones
digitalWrite(led_encendido_apagado, btnEncendido.estadoActual);
if (!cicloIniciado) {
digitalWrite(led_agua, btnAgua.estadoActual);
digitalWrite(led_jabon, btnJabon.estadoActual);
digitalWrite(led_inicio_pausa, btnInicioPausa.estadoActual);
} else {
digitalWrite(led_agua, LOW);
digitalWrite(led_jabon, LOW);
digitalWrite(led_inicio_pausa, LOW);
}
// Iniciar ciclo
if (estado == REPOSO &&
btnEncendido.estadoActual &&
btnAgua.estadoActual &&
btnJabon.estadoActual &&
btnInicioPausa.fuePresionado) {
estado = LAVADO;
tiempoEstado = ahora;
tiempoMotor = ahora;
cicloIniciado = true;
actualizarEstado();
btnInicioPausa.fuePresionado = false;
}
// Pausar o reanudar
if (btnInicioPausa.fuePresionado) {
enPausa = !enPausa;
Serial.println(enPausa ? "⏸️ Pausado" : "▶️ Reanudado");
btnInicioPausa.fuePresionado = false;
}
// Apagar todo si se presiona el botón de encendido/apagado
if (btnEncendido.fuePresionado) {
if (estado != REPOSO) {
motorDetener();
estado = REPOSO;
cicloIniciado = false;
Serial.println("🔴 Apagado. Todo detenido.");
parpadearFin();
}
btnEncendido.fuePresionado = false;
}
if (enPausa) {
motorDetener();
return;
}
// Máquina de estados
switch (estado) {
case LAVADO:
if (ahora - tiempoEstado < duracionLavado) {
if (ahora - tiempoMotor >= 2000) {
motorDir = !motorDir;
motorDir ? motorAdelante() : motorAtras();
tiempoMotor = ahora;
}
} else {
estado = ENJUAGUE;
tiempoEstado = ahora;
tiempoMotor = ahora;
actualizarEstado();
}
break;
case ENJUAGUE:
if (ahora - tiempoEstado < duracionEnjuague) {
if (ahora - tiempoMotor >= 2000) {
motorDir = !motorDir;
motorDir ? motorAdelante() : motorAtras();
tiempoMotor = ahora;
}
} else {
estado = CENTRIFUGADO;
tiempoEstado = ahora;
tiempoMotor = ahora;
actualizarEstado();
}
break;
case CENTRIFUGADO:
if (ahora - tiempoEstado < duracionCentrifugado) {
motorAdelante();
} else {
motorDetener();
estado = REPOSO;
cicloIniciado = false;
Serial.println("✅ Ciclo completo. Volviendo a REPOSO.");
parpadearFin();
actualizarEstado();
}
break;
}
}