// #include <EEPROM.h>

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

//LiquidCrystal_I2C lcd(34, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 16, 2);
// set the LCD address to 0x27 for a 16 chars and 2 line display

//Float Switches
int L3 = 7; //highest
int L2 = 9;
int L1 = 10;
int L0 = 12; // lowest
int percentage;

//OTHER
int led = 8; // to indicate pump is ON
int relay = 2;
int mode = 11; // spst switch
int startStop = 4;  //push-pull
int dryRun = 5; //float switch
//bool state;
bool pump, isDry;
//-------------------------------------------------

void setup()
{
  // Serial.begin(9600);
  lcd.init();         // initialize the lcd
  lcd.backlight();    // Turn on the LCD screen backlight

  //float switch
  pinMode(L3, INPUT_PULLUP);
  pinMode(L2, INPUT_PULLUP);
  pinMode(L1, INPUT_PULLUP);
  pinMode(L0, INPUT_PULLUP);

  pinMode(led, OUTPUT);
  pinMode(relay, OUTPUT);
  pinMode(mode, INPUT_PULLUP);
  pinMode(startStop, INPUT_PULLUP);
  pinMode(dryRun, INPUT_PULLUP);

  percentage = 101; //safety
}
void loop()
{

  //default print
  lcd.setCursor(0, 0);
  lcd.print("WATER LEVEL:");
  lcd.setCursor(0, 1);
  lcd.print("PUMP:");

  //level check
  if(!digitalRead(L3) & !digitalRead(L2) & !digitalRead(L1) & !digitalRead(L0)){
    percentage = 100;
  }
  else if(digitalRead(L3) & !digitalRead(L2) & !digitalRead(L1) & !digitalRead(L0)){
    percentage = 75;
  }
  else if(digitalRead(L3) & digitalRead(L2) & !digitalRead(L1) & !digitalRead(L0)){
    percentage = 50;
  }
  else if(digitalRead(L3) & digitalRead(L2) & digitalRead(L1) & !digitalRead(L0)){
    percentage = 25;
  }
  else if(digitalRead(L3) & digitalRead(L2) & digitalRead(L1) & digitalRead(L0)){ // "else" is not used for 10 percent, since if any of float switch mis-operates/damages IN SEQUENCE as above , by default percentage will go 10, and this makes Motor turn ON.
    percentage = 10;
  }else{
    percentage = 101; //safety
    pump = 0;
    lcd.setCursor(0, 0);
    lcd.print("Sensor ERROR!    ");
    delay(3000);
  }

  //Print
  if(!pump){
    lcd.setCursor(12, 0);
    lcd.print(percentage);
    lcd.print("%   ");
  }else{ // blinking percentage effect while pump is ON.
    lcd.setCursor(12, 0);
    lcd.print(percentage);
    lcd.print("%   ");
    delay(1000);
    lcd.setCursor(12, 0);
    lcd.print("    ");
  }
  

  //AUTO
  if (digitalRead(mode) & percentage == 10) {
    pump = 1;
  }
  if (percentage == 100) {
    pump = 0;
  }

  //MANUAL
  if (!digitalRead(mode) & !digitalRead(startStop)) {
    pump = !pump;
  }
  while (!digitalRead(startStop)) { // to make toggle perfect
    delay(50);
  }

  //(*)Dry Run protection
  if ((pump == 1) & digitalRead(dryRun)) {
    delay(5000);
    pump = 0;
    isDry = !isDry; // step 1 to run motor only once till next digitalRead(!dryRun) and avoid repeated ON/OFF;

    lcd.setCursor(0, 1);
    lcd.print("PUMP     DRY !!");
    delay(3000);
  } else {
    isDry = 0;
  }

  //(*)control point (isDry case)
  if (isDry) {
    digitalWrite(relay, 1);
    delay(5000);
    digitalWrite(relay, 0);
    digitalWrite(led, 1);
    delay(1000);
    digitalWrite(led, 0);
    isDry = 1; // step 2 to run motor only once till next digitalRead(!dryRun) and avoid repeated ON/OFF;
  } else {
    isDry = 1; // step 2 to run motor only once till next digitalRead(!dryRun) and avoid repeated ON/OFF;
  }

  //control point
  digitalWrite(relay, pump);
  digitalWrite(led, pump);
  delay(1000);
  digitalWrite(led, 0);

  //print
  lcd.setCursor(5, 1);
  if (pump) {
    lcd.print("ON ");
  } else {
    lcd.print("OFF");
  }
  lcd.setCursor(9, 1);
  if (!digitalRead(mode)) {
    lcd.print("Manual");
  } else {
    lcd.print("Auto  ");
  }

  delay(500);
}

//NOTE:: (*) do Dry-run the code for "dryRun" and "isDry" cases.
NOCOMNCVCCGNDINLED1PWRRelay Module