Water level indicator and pump controller

[code]
#include <EEPROM.h>

const unsigned long debounceDelay = 50;

const int waterLevelSensorLow = 0;
const int waterLevelSensorMedium = 1;
const int waterLevelSensorHigh = 2;

const int btnPause = 3;
int btnPauseState;
int lastBtnPauseState = LOW;
unsigned long lastBtnPauseDebounceTime = 0;

const int btnAutoManual = 4;
int btnAutoManualState;
int lastBtnAutoManualState = LOW;
unsigned long lastBtnAutoManualDebounceTime = 0;

const int btnSemiAuto =5;
int btnSemiAutoState;
int lastSemiAutoState = LOW;
unsigned long lastBtnSemiAutoDebounceTime = 0;

const int ledWaterLevelLow = 6;
const int ledWaterLevelMedium = 7;
const int ledWaterLevelHigh = 8;

const int ledAuto = 9;
const int ledManual = 10;
const int ledPause = 13;
const int ledSemiAuto = A0;

const int waterMotor = A2;
const int buzzer = A3;

const int sumpTankLowSensor = A4;
const int ledSumpTankLow = A5;

const int ledRunning = 12;
const int ledStandby = 11;
int standbyLedBrightness = 0;
int standbyLedFadeAmount = 2;

const int ledTimer = A1;

bool isPaused = false;
bool isAuto = true;
bool isSemiAuto = false;

bool isPauseLedOn = false;
bool isRunningLedOn = false;
bool isTimerLedOn = false;

const long ledBlinkingTimeInMilliSeconds = 200;
long lastPauseLedChangedTime = 0;
long lastRunningLedChangedTime = 0;
long lastTimerLedChangedTime = 0;

//Water Level 0 = Empty, 1 = LOW, 2 = MEDIUM, 3 = HIGH
int waterLevel = -1;
int lastWaterLevel = -1; 

bool runWaterMotor = false;
bool isWaterMotorRunning = false;

bool isSumpTankLow = false;

long motorStarTime = 0;
//5 minutes
const long motorMaxRunTimeInMilliseconds = 30000;

void setup() {
  
  Serial.begin(9600);
  
  pinMode(btnPause, INPUT);
  pinMode(btnAutoManual, INPUT);
  pinMode(btnSemiAuto, INPUT);
  
  pinMode(ledPause, OUTPUT);
  pinMode(ledAuto, OUTPUT);
  pinMode(ledManual, OUTPUT);
  pinMode(ledSemiAuto, OUTPUT);
  pinMode(ledWaterLevelLow, OUTPUT);
  pinMode(ledWaterLevelMedium, OUTPUT);
  pinMode(ledWaterLevelHigh, OUTPUT);
  
  pinMode(waterLevelSensorHigh, INPUT);
  pinMode(waterLevelSensorMedium, INPUT);
  pinMode(waterLevelSensorLow, INPUT);
  
  pinMode(waterMotor, OUTPUT);
  pinMode(buzzer, OUTPUT);
  
  pinMode(sumpTankLowSensor, INPUT);
  pinMode(ledSumpTankLow, OUTPUT);
  
  pinMode(ledRunning, OUTPUT);
  pinMode(ledStandby, OUTPUT);
  
  pinMode(ledTimer, OUTPUT);
  
  //readFromEEPROM();
  
  buzzerBeep();
  buzzerBeep();
}

void readFromEEPROM() {
  
  bool isEEPROMUpdated;
  EEPROM.get(EEPROM.length() - 1, isEEPROMUpdated);
  
  if (!isEEPROMUpdated){
    return;
  }
  
  int eeAddress = 0;
  
  EEPROM.get(eeAddress, isPaused);
  eeAddress += sizeof(bool);
    
  EEPROM.get(eeAddress, isAuto);
  eeAddress += sizeof(bool);
  
  EEPROM.get(eeAddress, isSemiAuto);
  eeAddress += sizeof(bool);
  
  EEPROM.get(eeAddress, lastWaterLevel);
  eeAddress += sizeof(int);
  
  EEPROM.get(eeAddress, runWaterMotor);
  eeAddress += sizeof(bool);
  
  EEPROM.get(eeAddress, isWaterMotorRunning);
  eeAddress += sizeof(bool);
  
  EEPROM.get(eeAddress, motorStarTime);
  eeAddress += sizeof(long);
}

void loop() {
  
  updateSumpTankWaterStatus();
  updateWaterLevel();
  updateButtonStatuses();
  handleWaterMotor();
  updateEEPROM();
}

void updateSumpTankWaterStatus() {
  int status = digitalRead(sumpTankLowSensor);
  
  isSumpTankLow = !status;
  digitalWrite(ledSumpTankLow, isSumpTankLow);
}

void updateWaterLevel() {
  setWaterLevel();
  handleWaterLevelLed();
}

void setWaterLevel() {
  
  int low = digitalRead(waterLevelSensorLow);
  int medium = digitalRead(waterLevelSensorMedium);
  int high = digitalRead(waterLevelSensorHigh);
  
  int calculatedWaterLevel;
  
  if (low == LOW && medium == LOW && high == LOW) {
  	calculatedWaterLevel = 3;
  } else if (low == LOW && medium == LOW && high == HIGH) {
  	calculatedWaterLevel = 2;
  } else if (low == LOW && medium == HIGH && high == HIGH) {
  	calculatedWaterLevel = 1;
  } else if (low == HIGH && medium == HIGH && high == HIGH) {
  	calculatedWaterLevel = 0;
  } else {
  	calculatedWaterLevel = -1;
  }
  
  if(waterLevel != calculatedWaterLevel) {
    
    if(lastWaterLevel == -1) {
      lastWaterLevel = calculatedWaterLevel;
    } else {
      lastWaterLevel = waterLevel;
    }
    
    waterLevel = calculatedWaterLevel;
  }
}

void handleWaterLevelLed() {
    
  if (waterLevel == 1) {
    
    digitalWrite(ledWaterLevelHigh, LOW);
    digitalWrite(ledWaterLevelMedium, LOW);
    digitalWrite(ledWaterLevelLow, HIGH);
    
  } else if (waterLevel == 2) {
    
    digitalWrite(ledWaterLevelHigh, LOW);
    digitalWrite(ledWaterLevelMedium, HIGH);
    digitalWrite(ledWaterLevelLow, HIGH);
    
  } else if (waterLevel == 3) {
    
    digitalWrite(ledWaterLevelHigh, HIGH);
    digitalWrite(ledWaterLevelMedium, HIGH);
    digitalWrite(ledWaterLevelLow, HIGH);
  
  } else {
  
    digitalWrite(ledWaterLevelHigh, LOW);
    digitalWrite(ledWaterLevelMedium, LOW);
    digitalWrite(ledWaterLevelLow, LOW);
  }
}

void updateButtonStatuses() {
  setAutoStatus();
  setPauseStatus();
  setSemiAutoStatus();
  
  handleAutoManualLeds();
  handlePauseLed();
  handleSemiAutoLed();
}

void setAutoStatus() {
  
  int reading = digitalRead(btnAutoManual);
  
  if (reading != lastBtnAutoManualState) {
    lastBtnAutoManualDebounceTime = millis();
  }
  
  if ((millis() - lastBtnAutoManualDebounceTime) > debounceDelay) {
    if (reading != btnAutoManualState) {
      btnAutoManualState = reading;

      if (btnAutoManualState == HIGH) {
        isAuto = !isAuto;
        buzzerBeep();
      }
    }
  }
  lastBtnAutoManualState = reading;
}

void handleAutoManualLeds() {
  
  bool isAutoLedOn = isAuto && !isPaused;
  digitalWrite(ledAuto, isAutoLedOn);
  
  bool isManualLedOn = !isAuto && !isPaused;
  digitalWrite(ledManual, isManualLedOn);
}

void setPauseStatus() {
  
  int reading = digitalRead(btnPause);
  
  if (reading != lastBtnPauseState) {
    lastBtnPauseDebounceTime = millis();
  }
  
  if ((millis() - lastBtnPauseDebounceTime) > debounceDelay) {
    if (reading != btnPauseState) {
      btnPauseState = reading;

      if (btnPauseState == HIGH) {
        isPaused = !isPaused;
      }
    }
  }
  lastBtnPauseState = reading;
}

void handlePauseLed() {
    
  if(isPaused) {
    
    long timeElapsedAfterLastChange = millis() - lastPauseLedChangedTime;
    
    if(timeElapsedAfterLastChange > ledBlinkingTimeInMilliSeconds) {
      
      isPauseLedOn = !isPauseLedOn;
      digitalWrite(ledPause, isPauseLedOn);
      lastPauseLedChangedTime = millis();
    }
  } else {
  
    digitalWrite(ledPause, LOW);
    isPauseLedOn = false;
  } 

  if(isPauseLedOn) {
    buzzerBeep();
  }
}

void setSemiAutoStatus() {
  
  int reading = digitalRead(btnSemiAuto);
  
  if (reading != lastSemiAutoState) {
    lastBtnSemiAutoDebounceTime = millis();
  }
  
  if ((millis() - lastBtnSemiAutoDebounceTime) > debounceDelay) {
    if (reading != btnSemiAutoState) {
      btnSemiAutoState = reading;

      if (btnSemiAutoState == HIGH) {
        isSemiAuto = !isSemiAuto && (waterLevel < 3 && waterLevel > 0);
        buzzerBeep();
      }
    }
  }
  lastSemiAutoState = reading;
  
  if (waterLevel == 3) {
    isSemiAuto = false;
  }
}

void handleSemiAutoLed() {
  digitalWrite(ledSemiAuto, isSemiAuto && isAuto && !isPaused);
}

void handleWaterMotor() {
  setWaterMotorRunStatus();
  
  if(isWaterMotorRunning != runWaterMotor) {
    
    if(runWaterMotor) {
      buzzerBeep();
      buzzerBeep();
      buzzerBeep();
      
      motorStarTime = millis();
    }
    
    digitalWrite(waterMotor, runWaterMotor);
    isWaterMotorRunning = runWaterMotor;
    
    if(!runWaterMotor) {
      buzzerBeep();
      buzzerBeep();
      buzzerBeep();
      
      motorStarTime = 0;
    }
  }
  
  handleRunningLed();
  handleSandbyLed();
  handleTimerLed();
}

void setWaterMotorRunStatus() {
  
  bool isWaterLevelLow = waterLevel == 0;
  bool isWaterLevelLowToHigh = waterLevel < 3 && waterLevel > 0;
  bool isTankFillingUp = isWaterLevelLowToHigh && waterLevel > lastWaterLevel;
  bool runMotorAutoMode = isAuto && (isWaterLevelLow || isTankFillingUp);
  bool runMotorSemiAutoMode = isSemiAuto && (isWaterLevelLowToHigh || isTankFillingUp);
  bool isTimerUp = isAuto && (millis() - motorStarTime) >= motorMaxRunTimeInMilliseconds;
  
  
  runWaterMotor = (runMotorAutoMode || runMotorSemiAutoMode || !isAuto) && !isPaused && !isSumpTankLow && !isTimerUp;
}

void handleRunningLed() {
    
  if(isWaterMotorRunning) {
    
    long timeElapsedAfterLastChange = millis() - lastRunningLedChangedTime;
    
    if(timeElapsedAfterLastChange > ledBlinkingTimeInMilliSeconds) {
      
      isRunningLedOn = !isRunningLedOn;
      digitalWrite(ledRunning, isRunningLedOn);
      lastRunningLedChangedTime = millis();
    }
  } else {
  
    digitalWrite(ledRunning, LOW);
    isRunningLedOn = false;
  } 

  if(isRunningLedOn) {
    buzzerBeep();
  }
}

void handleSandbyLed() {
  
  if(!isWaterMotorRunning && (isAuto || isSemiAuto) && !isPaused) {      
  	
    analogWrite(ledStandby, standbyLedBrightness);
  	standbyLedBrightness = standbyLedBrightness + standbyLedFadeAmount;

  	if (standbyLedBrightness <= 0 || standbyLedBrightness >= 255) {
    	standbyLedFadeAmount = -standbyLedFadeAmount;
  	}
    
  	delay(30);
    
  } else {
    digitalWrite(ledStandby, LOW);
  }
}

void handleTimerLed() {
  
  if(isWaterMotorRunning && motorStarTime > 0 && isAuto){
    
    long timeElapsedAfterLastChange = millis() - lastTimerLedChangedTime;
    
    if(timeElapsedAfterLastChange > ledBlinkingTimeInMilliSeconds) {
      
      isTimerLedOn = !isTimerLedOn;
      digitalWrite(ledTimer, isTimerLedOn);
      lastTimerLedChangedTime = millis();
    }
  } else {
     digitalWrite(ledTimer, LOW);
     isTimerLedOn = false;
  }
}

void buzzerBeep() {
  const int buzzerTime = 250;
  
  digitalWrite(buzzer, HIGH);
  delay(buzzerTime);
  digitalWrite(buzzer, LOW);
  delay(buzzerTime);
}

void updateEEPROM() {
  
  int eeAddress = 0;
  
  EEPROM.update(eeAddress, isPaused);
  eeAddress += sizeof(bool);
    
  EEPROM.update(eeAddress, isAuto);
  eeAddress += sizeof(bool);
  
  EEPROM.update(eeAddress, isSemiAuto);
  eeAddress += sizeof(bool);
  
  EEPROM.update(eeAddress, lastWaterLevel);
  eeAddress += sizeof(int);
  
  EEPROM.update(eeAddress, runWaterMotor);
  eeAddress += sizeof(bool);
  
  EEPROM.update(eeAddress, isWaterMotorRunning);
  eeAddress += sizeof(bool);
  
  EEPROM.update(eeAddress, motorStarTime);
  eeAddress += sizeof(long);
  
  EEPROM.update(EEPROM.length() - 1, true);
}
[/code]