#include <LiquidCrystal_PCF8574.h>
#include <Bounce2.h> // Librería para antirrebote profesional
// Configuración LCD
LiquidCrystal_PCF8574 lcd(0x27);
// Pines de entrada
#define PIN_I0 18
#define PIN_I1 19
#define PIN_I2 23
// Pines de salida
#define Q0 15
#define Q1 2
#define Q2 5
// Instancias de Bounce para cada entrada
Bounce debouncer0 = Bounce();
Bounce debouncer1 = Bounce();
Bounce debouncer2 = Bounce();
// Variables para mantener el estado de las salidas (Toggle)
bool estadoQ0 = false;
bool estadoQ1 = false;
bool estadoQ2 = false;
char texto[] = "I/O Digitales";
byte alto [] = { 0b0000, 0b1111, 0b1111, 0b1111, 0b1111, 0b1111, 0b1111, 0b0000 };
byte bajo [] = { 0b0000, 0b1111, 0b1001, 0b1001, 0b1001, 0b1001, 0b1111, 0b0000 };
void setup() {
// Configurar las entradas con la librería Bounce
// attach() configura el pin y el modo INPUT_PULLUP internamente
debouncer0.attach(PIN_I0, INPUT_PULLUP);
debouncer0.interval(10); // Intervalo de 10ms para el antirrebote
debouncer1.attach(PIN_I1, INPUT_PULLUP);
debouncer1.interval(10);
debouncer2.attach(PIN_I2, INPUT_PULLUP);
debouncer2.interval(10);
// Configurar salidas
pinMode(Q0, OUTPUT);
pinMode(Q1, OUTPUT);
pinMode(Q2, OUTPUT);
// Inicializar LCD
lcd.begin(20, 4);
lcd.createChar(0, bajo);
lcd.createChar(1, alto);
delay(200);
lcd.setBacklight(255);
}
void loop() {
// Actualizar el estado de los botones
debouncer0.update();
debouncer1.update();
debouncer2.update();
// fell() detecta cuando la entrada pasa de HIGH a LOW (cuando presionas)
if (debouncer0.fell()) {
estadoQ0 = !estadoQ0; // Cambiar estado
}
if (debouncer1.fell()) {
estadoQ1 = !estadoQ1;
}
if (debouncer2.fell()) {
estadoQ2 = !estadoQ2;
}
// Escribir físicamente en las salidas
digitalWrite(Q0, estadoQ0);
digitalWrite(Q1, estadoQ1);
digitalWrite(Q2, estadoQ2);
// Mostrar en LCD
estados();
}
void estados() {
lcd.setCursor(0,0);
lcd.print(texto);
lcd.setCursor(0,1);
lcd.print("I: ");
// Mostramos el estado físico actual del botón (invertido para el icono)
// !debouncer.read() nos da 1 si está presionado
lcd.write((byte)!debouncer0.read());
lcd.write((byte)!debouncer1.read());
lcd.write((byte)!debouncer2.read());
lcd.setCursor(0,2);
lcd.print(" 012");
lcd.setCursor(0,3);
lcd.print("Q: ");
// Mostramos el estado enclavado (Toggle)
lcd.write((byte)estadoQ0);
lcd.write((byte)estadoQ1);
lcd.write((byte)estadoQ2);
}