// Sketch from Arduino user retcon:
// https://forum.arduino.cc/t/can-someone-explain-this-code-trying-to-learn/1031873/18
//
// Left slide switch is water low (pin 8).
// Right slide switch is water high (pin 9).
//
// Formatted the sketch.
/*
The circuit uses two LEDs Connected to an Arduino UNO board in order to simulate the two water pumps,
A third LED is used in order to simulate an Alarm signal.
The Two different Water Level Sensors are simulated using two digital Slide Switches wired using the
Arduinos internal Pullup resistors.
*/
const int pump_1 = 3;
const int pump_2 = 4;
const int waterLow = 8;
const int waterHigh = 9;
const int alarm = 2;
const unsigned long pumpInterval = 30000; // Declare interval before second pump starts (30s)
const unsigned long alarmInterval = 30000; //Declare time before alarm state (30s)
unsigned long pumpOnTime;
int lowSensor = LOW; // declare initial state of low water sensor
int highSensor = LOW; // declare initial state of High level water sensor
unsigned int nextPumpFlag; // variable to indicate which pump will be primary and which is back-up
int nextState;
int currentState;
//possible states of the state-machine
typedef enum {
TankFilling,
FirstPumpOn,
SecondPumpOn,
AlarmOn,
TankWaiting
} states;
void setup() {
Serial.begin(9600);
nextState = TankFilling;
currentState = nextState;
//set pin modes for each pin:
pinMode(pump_1, OUTPUT);
pinMode(pump_2, OUTPUT);
pinMode(alarm, OUTPUT);
pinMode(waterLow, INPUT_PULLUP);
pinMode(waterHigh, INPUT_PULLUP);
}
//Set Alarm function
void TurnOnAlarm() {
digitalWrite (alarm, HIGH);
Serial.println ("Alarm On");
}
//set Empty tank Function (switch all pumps and alarm off)
void TankEmpty() {
digitalWrite(pump_1, LOW);
digitalWrite(pump_2, LOW);
digitalWrite(alarm, LOW);
Serial.println("Tank Empty");
}
//Set first pump function
void turnOnFirstPump() {
turnOnNextPump();
nextPumpFlag++;
}
//Set Second pump function
void turnOnSecondPump() {
turnOnNextPump();
}
//Set function for next pump. primary and backup pump to alternate
void turnOnNextPump() {
if (nextPumpFlag & 0x1) {
digitalWrite(pump_1, HIGH);
Serial.println("Pump 2 Running");
} else {
digitalWrite(pump_2, HIGH);
Serial.println("Pump 1 Running");
}
}
//main program loop using Switch..Case statements
void loop() {
const unsigned long currentTime = millis(); // set current time
int tankFull;
lowSensor = digitalRead(waterLow);
highSensor = digitalRead(waterHigh);
tankFull = lowSensor + highSensor;
switch (currentState) {
//Only Start first pump when both Sensors are HIGH,
case TankFilling:
if (tankFull == 2) {
Serial.println("Water High");
nextState = FirstPumpOn;
} else if (tankFull <= 1) {
Serial.println("Water Low");
}
break;
//Switch on first pump in sequence move to next state
case FirstPumpOn:
if (tankFull >= 1) {
turnOnFirstPump();
pumpOnTime = currentTime;
Serial.println("Pump 1 start time: ");
Serial.print(currentTime);
Serial.println(" ");
nextState = SecondPumpOn;
} else if (tankFull == 0) {
TankEmpty();
nextState = TankFilling;
}
break;
/*If both Sensors are not LOW switch second pump on after 30s
move to monitor for Alarm signal, If both Sensors Read LOW
go switch pump off and go back to starting state*/
case SecondPumpOn:
if (tankFull >= 1) {
if (currentTime - pumpOnTime >= pumpInterval) {
turnOnSecondPump();
pumpOnTime = currentTime;
nextState = AlarmOn;
}
} else if (tankFull == 0) {
TankEmpty();
nextState = TankFilling;
}
break;
/*If both sensors are not LOW with both pumps running after 30s
Switch Alarm signal on and move to monitor water level,
If both Sensors Read Low before 30s switch all pumps off
and go back to starting state in sequence*/
case AlarmOn:
if (tankFull >= 1) {
if (currentTime - pumpOnTime >= alarmInterval) {
TurnOnAlarm();
Serial.println("Alarm start time:");
Serial.print(currentTime);
Serial.println("");
nextState = TankWaiting;
}
} else if (tankFull == 0) {
TankEmpty();
nextState = TankFilling;
}
break;
/* monitor Tank Sensor Readings and only switch pumps and Alarm off
When Both Sensors read LOW, once LOW go to first state in sequence*/
case TankWaiting:
if (tankFull == 0) {
TankEmpty();
nextState = TankFilling;
}
break;
}
currentState = nextState; // declare how to move to next state
}//close Loop