#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define ENCODER_PINA 2
#define ENCODER_PINB 3
#define BUTTON_PIN 4
LiquidCrystal_I2C lcd(0x27, 16, 2); // Dirección I2C y tamaño del LCD
volatile int encoderPos = 0;
volatile int lastEncoderPos = 0;
volatile boolean buttonPressed = false;
unsigned long buttonPressTime = 0;
enum MenuState {
MAIN_MENU,
SUB_MENU_BOMBA,
SUB_MENU_AJUSTE_MAXIMA,
SUB_MENU_AJUSTE_MINIMA
};
MenuState currentMenu = MAIN_MENU;
int bombaSelected = 1; // Valor predeterminado de la bomba seleccionada
int presionMaxima = 100; // Valor predeterminado de presión máxima
int presionMinima = 50; // Valor predeterminado de presión mínima
void setup() {
pinMode(ENCODER_PINA, INPUT_PULLUP);
pinMode(ENCODER_PINB, INPUT_PULLUP);
pinMode(BUTTON_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(ENCODER_PINA), handleEncoder, CHANGE);
lcd.begin(16, 2);
lcd.print(" Menu con");
lcd.setCursor(0, 1);
lcd.print(" Encoder");
delay(2000);
lcd.clear();
lcd.print("Menu Principal");
}
void loop() {
handleButton();
if (currentMenu == MAIN_MENU) {
handleMainMenu();
} else if (currentMenu == SUB_MENU_BOMBA) {
handleSubMenuBomba();
} else if (currentMenu == SUB_MENU_AJUSTE_MAXIMA) {
handleSubMenuAjusteMaxima();
} else if (currentMenu == SUB_MENU_AJUSTE_MINIMA) {
handleSubMenuAjusteMinima();
}
}
void handleEncoder() {
int aState = digitalRead(ENCODER_PINA);
int bState = digitalRead(ENCODER_PINB);
if (aState != lastEncoderPos) {
if (bState != aState) {
encoderPos++;
} else {
encoderPos--;
}
lastEncoderPos = aState;
}
}
void handleButton() {
int buttonState = digitalRead(BUTTON_PIN);
if (buttonState == LOW) {
unsigned long currentTime = millis();
unsigned long buttonDuration = currentTime - buttonPressTime;
if (buttonDuration > 1000) {
buttonPressed = true;
} else {
buttonPressTime = currentTime;
}
} else {
if (buttonPressed) {
handleButtonPress();
buttonPressed = false;
}
}
}
void handleButtonPress() {
if (currentMenu == MAIN_MENU) {
currentMenu = SUB_MENU_BOMBA;
lcd.clear();
lcd.print("Seleccione bomba:");
lcd.setCursor(0, 1);
lcd.print("Bomba " + String(bombaSelected));
} else if (currentMenu == SUB_MENU_BOMBA) {
currentMenu = SUB_MENU_AJUSTE_MAXIMA;
lcd.clear();
lcd.print("Ajustar Maxima");
} else if (currentMenu == SUB_MENU_AJUSTE_MAXIMA) {
currentMenu = SUB_MENU_AJUSTE_MINIMA;
lcd.clear();
lcd.print("Ajustar Minima");
} else if (currentMenu == SUB_MENU_AJUSTE_MINIMA) {
// Aquí podrías implementar acciones adicionales si se necesita.
// Por ejemplo, guardar la configuración en la memoria no volátil (EEPROM).
currentMenu = MAIN_MENU;
lcd.clear();
lcd.print("Menu Principal");
lcd.setCursor(0, 1);
lcd.print("Bomba " + String(bombaSelected));
}
}
void handleMainMenu() {
// No se necesita hacer nada especial aquí para el menú principal.
}
void handleSubMenuBomba() {
// Aquí mostramos en pantalla las opciones disponibles y actualizamos la variable bombaSelected.
lcd.clear();
lcd.print("Seleccione bomba:");
lcd.setCursor(0, 1);
lcd.print("Bomba " + String(bombaSelected));
// Si el encoder ha girado, actualizamos la selección de la bomba.
if (encoderPos != lastEncoderPos) {
bombaSelected = constrain(bombaSelected + encoderPos - lastEncoderPos, 1, 2);
lcd.setCursor(0, 1);
lcd.print("Bomba " + String(bombaSelected));
lastEncoderPos = encoderPos;
}
}
void handleSubMenuAjusteMaxima() {
// Si el encoder ha girado, actualizamos el ajuste de presión máxima.
if (encoderPos != lastEncoderPos) {
// Dividimos el valor del encoder entre 4 para obtener ajustes más lentos.
int delta = (encoderPos - lastEncoderPos) / 4;
presionMaxima = constrain(presionMaxima + delta, 0, 200);
lcd.clear();
lcd.print("Ajustar Maxima");
lcd.setCursor(0, 1);
lcd.print("Max: " + String(presionMaxima) + " Min: " + String(presionMinima));
lastEncoderPos = encoderPos;
}
}
void handleSubMenuAjusteMinima() {
// Si el encoder ha girado, actualizamos el ajuste de presión mínima.
if (encoderPos != lastEncoderPos) {
// Dividimos el valor del encoder entre 4 para obtener ajustes más lentos.
int delta = (encoderPos - lastEncoderPos) / 4;
presionMinima = constrain(presionMinima + delta, 0, presionMaxima);
lcd.clear();
lcd.print("Ajustar Minima");
lcd.setCursor(0, 1);
lcd.print("Max: " + String(presionMaxima) + " Min: " + String(presionMinima));
lastEncoderPos = encoderPos;
}
}