#include <Wire.h>                      // needed for LCD with PCF8574 port expander
#include <LiquidCrystal_I2C.h>
#include <Stepper.h>




const int stepsPerRevolution = 400; // Define el número de pasos por revolución del motor
const long duration1 = 195000; // Define la duración del programa en milisegundos (3 minutos 15 segund
const long duration2 = 30000;
const int sensor_pin = A10; // Pin del sensor analógico
const int relay_pin = 13;   // Pin del rele
const int threshold = 500; // Umbral para apagar la bomba de agua

int pulsador = digitalRead(5);
const byte thermoDO  = 6;
const byte thermoCS  = 5;
const byte thermoCLK = 4;
constexpr byte cols = 20;              // columns/characters per row
constexpr byte rows = 4;               // how many rows
constexpr byte addr = 0x27;            // set the LCD address to 0x3F or 0x27
LiquidCrystal_I2C lcd(addr, cols, rows);               // create lcd object - with support of special characters
Stepper myStepper(stepsPerRevolution, 8, 10, 9, 11);


// this example uses buttons to navigate through the menu
constexpr byte upButton = A0;
constexpr byte downButton = A1;
constexpr byte backButton = A2;
constexpr byte selectButton = A3;
constexpr byte encoderButton = 4;
constexpr byte start = 2;



// prototype

void action0(byte, byte, byte, int);
void action1(byte, byte, byte, int);
void action2(byte, byte, byte, int);
void action3(byte, byte, byte, int);
void action4(byte, byte, byte, int);
void action5(byte, byte, byte, int);
void action6(byte, byte, byte, int);
void action7(byte, byte, byte, int);
void back(byte, byte, byte, int);

#include "menu.h"
//each menu line needs an prompter (text to be displayed) and a function will should be called

//const char theString[] PROGMEM ="Option F";  // https://forum.arduino.cc/t/progmem-and-class-constructor/346118/3

MenuLine menu0line0("C41", action0);
MenuLine menu0line1("c41 program", action1);
MenuLine menu0line2("BYN0", action2);
MenuLine menu0line3("byn 1", action3);
MenuLine menu0line4("byn 2", action4);
MenuLine menu0line5("byn 3", action5);

MenuLine menuLineOnOff0("Off", action5);
MenuLine menuLineOnOff1("On", action5);
MenuLine menuLineOnOffBack("(return)", back);

MenuLine menuLineRGB0("6 minutos", action4);
MenuLine menuLineRGB1("7 minutos", action4);
MenuLine menuLineRGB2("8 minutos", action4);
MenuLine menuLineRGB3("9 minutos", action4);
MenuLine menuLineRGB4("10 minutos", action4);
MenuLine menuLineRGBBack("(return)", back);


MenuLine menuLineSpeed0("slow", action6);
MenuLine menuLineSpeed1("medium", action6);
MenuLine menuLineSpeed2("fast", action6);
MenuLine menuLineBack("(return)", back);
MenuLine menuLineNothing("nothing");

MenuLine menuLineOKOff0("Off", action7);
MenuLine menuLineOKOff1("On", action7);
MenuLine menuLineOKOffBack("(return)", back);

// menu screens are collection of several lines:
MenuScreen menuScreenMain(&menu0line0, &menu0line1, &menu0line2, &menu0line3, &menu0line4, &menu0line5);
MenuScreen menuScreenOnOff(&menuLineOnOff0, &menuLineOnOff1, &menuLineBack);
MenuScreen menuScreenRGB(&menuLineRGB0, &menuLineRGB1, &menuLineRGB2, &menuLineRGB3, &menuLineRGB4, &menuLineBack);
MenuScreen menuScreenSpeed(&menuLineSpeed0, &menuLineSpeed1, &menuLineSpeed2, &menuLineNothing, &menuLineBack); 
MenuScreen menuScreenoknook(&menuLineOKOff0, &menuLineOKOff1, &menuLineBack);           // example of screen with exit/back/return
// menu system is the collection of several menu screens:
MenuSystem<LiquidCrystal_I2C> menuSystem(lcd, rows, &menuScreenMain, &menuScreenOnOff, &menuScreenRGB, &menuScreenSpeed);

// besser wäre etwas ala "ID" und "option"

void action0(byte screen, byte id, byte line, int value)                       // do what ever is needed
{
  Serial.println(F("action0"));
  (void)screen;  // if you don't use the screen, avoid warning for unused varialbe
  (void)id;
  (void)line;
  (void)value;

  lcd.clear();
  lcd.print("-Ejecutando C41");
  

  delay(1500);
  lcd.clear();
  lcd.setCursor(3,1);
  lcd.print("ingresando agua");
  delay(2000);
  
  
 
  for(int  i = 0; i >= 2;i++ ){

    analogRead(A10);

    if (analogRead(A10) < 100)
    {
    digitalWrite(13, LOW);
    Serial.println("dentro del loop");
    delay(1000);
    
    }
    
    else if (analogRead(A10) > 100)
    {
    digitalWrite(13, HIGH);
    Serial.println("fuera del loop");
    delay(1000);
    i=i-1;
    }


  }


  lcd.clear();
  lcd.print("CALENTANDO");
  lcd.setCursor(2,1);
  lcd.print("QUIMICOS");

  delay (2000);
  
  lcd.clear();
  lcd.setCursor(0, 0); // Coloca el cursor en la primera columna de la primera fila
  lcd.print("Tiempo restante:"); // Imprime el texto "Tiempo restante:" en el LCD)
 

  long startTime = millis(); // Guarda el tiempo actual en milisegundos en la variable startTime
  long elapsedTime = 0; // Inicializa la variable elapsedTime en 0

  while (elapsedTime < duration1) { // Mientras elapsedTime sea menor que la duración del programa
    myStepper.step(stepsPerRevolution); // Gira el motor 400 pasos a la derecha
    Serial.println("clockwise");
    delay(1000); // Espera 500 milisegundos
    myStepper.step(-stepsPerRevolution); // Gira el motor 400 pasos a la izquierda
    Serial.println("counterclockwise");
    delay(1000); // Espera 500 milisegundos
    elapsedTime = millis() - startTime; // Actualiza elapsedTime con la diferencia entre el tiempo actual y startTime
    
    long remainingTime = duration1 - elapsedTime; // Calcula el tiempo restante como la diferencia entre la duración del programa y elapsedTime
    int minutes = remainingTime / 60000; // Calcula el número de minutos restantes
    int seconds = (remainingTime % 60000) / 1000; // Calcula el número de segundos restantes
    
    lcd.setCursor(0, 1); // Coloca el cursor en la primera columna de la segunda fila
    lcd.print(minutes); // Imprime el número de minutos restantes en el LCD
    lcd.setCursor(1, 1); // Coloca el cursor en la primera columna de la segunda fila
    lcd.print(":"); // Imprime el número de minutos restantes en el LCD
    // Verifica si el número de segundos es menor que 10
    lcd.setCursor(2, 1);
     if (seconds < 10) {
     lcd.print("0"); // Imprime un cero adicional si el número de segundos es menor que 10
    }

    lcd.print(seconds); // Imprime el número de segundos restantes en el LCD
     
  }

  


   Serial.print("SALISTE DEL BUCLE");
   delay(1000);

 

  






  





  

  menuSystem.screen = 0;
  menuSystem.show();
}

//switch to menuScreen 1
void action1(byte screen, byte id, byte line, int value)
{
  Serial.println(F("action1"));
  (void)screen;
  (void)id;
  (void)line;
  (void)value;
  menuSystem.setId(menuSystem.getLine()); // preserve former line into id
  menuSystem.setScreen(1);

  menuSystem.show();
}

//switch to menuScreen 2
void action2(byte screen, byte id, byte line, int value)
{
  Serial.println(F("action2"));
  (void)screen;
  (void)id;
  (void)line;
  (void)value;
  menuSystem.setId(menuSystem.getLine());  // preserve former screen into id
  menuSystem.setScreen(2);
  menuSystem.show();
}

void action3(byte screen, byte id, byte line, int value)
{
  Serial.println(F("action3"));
  (void)screen;
  (void)id;
  (void)line;
  (void)value;
  menuSystem.setId(menuSystem.getLine());// preserve former screen into id
  menuSystem.setScreen(3);
  menuSystem.show();
}

void action4(byte screen, byte id, byte line, int value)
{
  Serial.println(F("action4"));
  (void)screen;
  (void)id;
  (void)line;
  (void)value;
  lcd.clear();
  lcd.print(F("-Executing E"));
  delay(1500);
  menuSystem.setLine(4);
  menuSystem.setScreen(0);
  menuSystem.show();
}

void action5(byte screen, byte id, byte line, int value)
{
  Serial.print(F("Action5 "));
  Serial.print(F(" screen=")); Serial.print(screen);
  Serial.print(F(" id=")); Serial.print(id);
  Serial.print(F(" line=")); Serial.print(line);
  Serial.print(F(" value=")); Serial.println(value);
  lcd.clear();
  lcd.print(F("-Executing F"));
  delay(1500);
  menuSystem.setLine(5);
  menuSystem.setScreen(0);
  menuSystem.setId(0);
  menuSystem.show();
}

void action6(byte screen, byte id, byte line, int value)
{
  Serial.print(F("Action6 "));
  Serial.print(F(" screen=")); Serial.print(screen);
  Serial.print(F(" id=")); Serial.print(id);
  Serial.print(F(" line=")); Serial.print(line);
  Serial.print(F(" value=")); Serial.println(value);
  lcd.clear();
  lcd.print("-Executing G");
  delay(1500);
  menuSystem.setLine(6);
  menuSystem.setScreen(0);
  menuSystem.setId(0);
  menuSystem.show();
}

void action7(byte screen, byte id, byte line, int value)
{
  Serial.println(F("action7"));
  (void)screen;
  (void)id;
  (void)line;
  (void)value;
  lcd.clear();
  lcd.print("-Executing #7");
  delay(1500);
  menuSystem.setLine(7);
  menuSystem.setScreen(0);
  menuSystem.setId(0);
  menuSystem.show();
}

void action8(byte screen, byte id, byte line, int value)
{
  Serial.println(F("action8"));
  (void)screen;
  (void)id;
  (void)line;
  (void)value;
  lcd.clear();
  lcd.print(F("-Executing #8"));
  delay(1500);
  menuSystem.setScreen(0);
  menuSystem.setId(0);
  menuSystem.show();
}

void back(byte screen, byte id, byte line, int value)
{
  Serial.println(F("back"));
  (void)screen;
  (void)id;
  (void)line;
  (void)value;
  menuSystem.cursorBack();
}

void readButton()
{
  if (digitalRead(downButton) == LOW) {
    menuSystem.cursorDown();
    delay(100);                        // dirty delay to debounce button
    while (!digitalRead(downButton));  // wait for button release
  }

  if (digitalRead(upButton) == LOW) {
    menuSystem.cursorUp();
    delay(100);                        // dirty delay to debounce button
    while (!digitalRead(upButton));
  }

  if (digitalRead(backButton) == LOW) {
    menuSystem.cursorBack();
    delay(100);                        // dirty delay to debounce button
    while (!digitalRead(backButton));
  }

  if (digitalRead(selectButton) == LOW) {
    menuSystem.activate();             // activate the current line
    delay(100);                        // dirty delay to debounce button
    while (!digitalRead(selectButton));
  }

  if (digitalRead(encoderButton) == LOW) {
    menuSystem.activate();             // activate the current line
    delay(100);                        // dirty delay to debounce button
    while (!digitalRead(encoderButton));
  }



}
#define ENCODER_CLK 2
#define ENCODER_DT  3
void readEncoder() {
  int dtValue = digitalRead(ENCODER_DT);
  if (dtValue == HIGH) {
    Serial.println("up");
    menuSystem.cursorUp();
  }
  if (dtValue == LOW) {
    Serial.println("down");
    menuSystem.cursorDown();
  }
}

int read_analog_sensor() {
  return analogRead(sensor_pin); // Leer el valor del sensor analógico
}

void turn_on_pump() {
  digitalWrite(relay_pin, HIGH); // Enviar un voltaje alto al pin del rele para encender la bomba de agua
}

void turn_off_pump() {
  digitalWrite(relay_pin, LOW); // Enviar un voltaje bajo al pin del rele para apagar la bomba de agua
}

void control_pump() {
  for(int  i = 0; i = 2;i++ ){

    if (read_analog_sensor < 100)
    {
    turn_off_pump();
    delay(1000);}
    
    else if (read_analog_sensor > 100)
    {
    turn_on_pump();
    delay(1000);
    i=i-1;
    }


  }
  
  
  
  
}




void setup()
{
  Serial.begin(115200);
  Serial.println(F("Simple Class based menu"));
  myStepper.setSpeed(75);

  Wire.begin();                        // start I2C library
  lcd.init();                          // initialize the LCD
  lcd.backlight();                     // turn on backlight
  pinMode(upButton, INPUT_PULLUP);
  pinMode(downButton, INPUT_PULLUP);
  pinMode(backButton, INPUT_PULLUP);
  pinMode(selectButton, INPUT_PULLUP);
  pinMode(encoderButton, INPUT_PULLUP);
  pinMode(23, OUTPUT);
  pinMode(22, OUTPUT);
  pinMode(25, OUTPUT);
  pinMode(27, OUTPUT);
  pinMode(29, OUTPUT);
  digitalWrite(22,LOW);
  digitalWrite(23,LOW);
  digitalWrite(25,LOW);
  digitalWrite(27,LOW);
  digitalWrite(29,LOW);
  digitalWrite(5, HIGH);
  pinMode(5, INPUT);
  pinMode(A7,INPUT);
  pinMode(13,OUTPUT);
  pinMode(A5,INPUT);
  analogWrite(A4, LOW);
  pinMode(13, OUTPUT);
  pinMode(sensor_pin, INPUT);
  digitalWrite(13,LOW);
  pinMode(ENCODER_CLK, INPUT);
  pinMode(ENCODER_DT, INPUT);
  attachInterrupt(digitalPinToInterrupt(ENCODER_CLK), readEncoder, FALLING);
  menuSystem.show();
  {
  pinMode(relay_pin, OUTPUT); // Configurar el pin del rele como salida
}

}


void loop()
{

  readButton();
}
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module