#include <LiquidCrystal.h>
#include <Bounce2.h> // Asegúrate de instalar esta librería desde el gestor de librerías
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
// Definición de Estados
enum {Seleccion, Proceso, Finalizado, Pausado};
unsigned char Estado = Seleccion;
// Variables para Dobladora
int meta = 0;
int meta2 = 0;
int cuenta = 0;
// Pines
const int pin1 = 1;
const int pin13 = 13; // LED integrado usualmente
const int btnDiez = 32; // +10
const int btnCincuenta = 34; // +50
const int btnCien = 36; // +100
const int btnArranque = 22; // Arranque
const int btnParo = 24; // Paro
const int btnReset = 26; // Reset
const int sensor = 42; // Sensor
const int pulso = 48; // Salida Relevador/Valvula
// Creación de objetos Bounce
Bounce dbDiez = Bounce();
Bounce dbCincuenta = Bounce();
Bounce dbCien = Bounce();
Bounce dbArranque = Bounce();
Bounce dbParo = Bounce();
Bounce dbReset = Bounce();
Bounce dbSensor = Bounce();
// Intervalo de rebote en milisegundos
const int DEBOUNCE_INTERVAL = 25; // 25ms es buen estándar para botones humanos
const int SENSOR_INTERVAL = 5; // Menor tiempo para el sensor para no perder hojas rápidas
void setup() {
Serial.begin(9600);
Serial.println("Iniciando.");
lcd.begin(16, 2);
pinMode(pin13, OUTPUT);
pinMode(pin1, OUTPUT);
pinMode(pulso, OUTPUT);
// Configuración de botones con Bounce2
// Usamos attach(pin, INPUT) asumiendo que tienes resistencias pull-down externas.
// Si no tienes resistencias, usa INPUT_PULLUP y cambia la lógica.
dbDiez.attach(btnDiez, INPUT);
dbDiez.interval(DEBOUNCE_INTERVAL);
dbCincuenta.attach(btnCincuenta, INPUT);
dbCincuenta.interval(DEBOUNCE_INTERVAL);
dbCien.attach(btnCien, INPUT);
dbCien.interval(DEBOUNCE_INTERVAL);
dbArranque.attach(btnArranque, INPUT);
dbArranque.interval(DEBOUNCE_INTERVAL);
dbParo.attach(btnParo, INPUT);
dbParo.interval(DEBOUNCE_INTERVAL);
dbReset.attach(btnReset, INPUT);
dbReset.interval(DEBOUNCE_INTERVAL);
dbSensor.attach(sensor, INPUT);
dbSensor.interval(SENSOR_INTERVAL); // El sensor suele necesitar respuesta más rápida
// Mensaje inicial
lcd.clear();
lcd.print("LISTO");
delay(1000);
lcd.clear();
}
void loop() {
// 1. Actualizar todos los botones/sensores al inicio del loop
dbDiez.update();
dbCincuenta.update();
dbCien.update();
dbArranque.update();
dbParo.update();
dbReset.update();
dbSensor.update();
digitalWrite(pin13, LOW);
digitalWrite(pin1, LOW);
// Máquina de estados
switch (Estado) {
case Seleccion:
// --- Lógica de Botones (Usando .rose() que significa que pasó de LOW a HIGH) ---
if (dbDiez.rose()) {
meta += 10;
}
if (dbCincuenta.rose()) {
meta += 50;
}
if (dbCien.rose()) {
meta += 100;
}
if (dbReset.rose()) {
meta = 0;
lcd.clear();
}
if (dbArranque.rose()) {
if (meta > 0) {
meta2 = meta;
cuenta = 0; // Reiniciamos cuenta al arrancar
Estado = Proceso;
lcd.clear();
lcd.setCursor(3, 0);
lcd.print("ARRANQUE");
delay(1000);
lcd.clear();
}
}
// --- Actualización LCD ---
// (Se imprime siempre, idealmente solo debería imprimirse si cambia el valor para evitar parpadeo)
lcd.setCursor(0, 0);
lcd.print("META: "); // Espacios para limpiar residuos
lcd.setCursor(6, 0);
lcd.print(meta);
lcd.setCursor(0, 1);
lcd.print("Cuenta: ");
lcd.setCursor(8, 1);
lcd.print(cuenta);
break;
case Proceso:
// Imprimir info
lcd.setCursor(0, 0);
lcd.print("META: ");
lcd.print(meta);
lcd.setCursor(0, 1);
lcd.print("Cuenta: ");
lcd.print(cuenta);
// --- Lógica de Control ---
if (meta > 0) {
// Control de Válvula basado en estado actual del sensor
if (dbSensor.read() == LOW) {
digitalWrite(pulso, HIGH);
Serial.println(("PRENDO"));
} else {
digitalWrite(pulso, LOW);
Serial.println(("APAGO"));
}
// Conteo: Detectar Flanco de Bajada (Falling Edge) HIGH -> LOW
// Según tu código original: "if (anterior42!=reading42 and reading42==LOW)"
if (dbSensor.fell()) {
meta--;
cuenta++;
}
// Paro de emergencia
if (dbParo.read() == HIGH) { // Si se mantiene presionado o se presiona
Estado = Pausado;
digitalWrite(pulso, LOW); // Apagar válvula por seguridad
lcd.clear();
}
} else {
// Meta llegó a 0
Estado = Finalizado;
digitalWrite(pulso, LOW);
}
break;
case Finalizado:
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("IMPRESOS AGLEZCA");
digitalWrite(pulso, LOW);
delay(2000); // Damos tiempo para leer
lcd.clear();
// Reinicio automático según tu lógica original
// meta = meta2; // Si quieres que se repita la meta anterior automáticamente
// cuenta = 0;
// Estado = Proceso;
// NOTA: Normalmente iría a Selección, pero tu código original volvía a Proceso.
// Lo dejaré regresando a SELECCION para que sea más seguro, si quieres automático descomenta arriba.
meta = 0;
cuenta = 0;
Estado = Seleccion;
break;
case Pausado:
lcd.setCursor(6, 0);
lcd.print("PAUSA");
digitalWrite(pulso, LOW);
if (dbReset.rose()) {
lcd.clear();
meta = 0;
meta2 = 0;
cuenta = 0;
Estado = Seleccion;
Serial.println("Seleccion");
}
if (dbArranque.rose()) {
Serial.println("Proceso");
lcd.clear();
Estado = Proceso;
}
break;
}
}