/*
Forum: https://forum.arduino.cc/t/code-check-please/1240893/2
(first Version Wokwi: https://wokwi.com/projects/393602101966308353)
Wokwi: https://wokwi.com/projects/395791344414641153
Sketch from TO at 2024/03/28
Modified by ec2021 at 2024/03/28 and again at 2024/04/21
*/
// C++ code
enum States {UNKNOWN, LEVELLOW, LEVELNORMAL, LEVELHIGH};
States state = LEVELNORMAL;
States lastState = UNKNOWN;
const unsigned long waitBeforePumpTwo = 4000; //30000;
const byte PUMP1_PIN = 9;
const byte PUMP2_PIN = 8;
const byte LOW_LEVEL_PIN = 5;
const byte HIGH_LEVEL_PIN = 4;
int PrimaryPump = 0; // Assuming 0 for Pump 1, 1 for Pump 2 (can be modified in loop)
const byte HIGH_LED_PIN = 7;
const byte LOW_LED_PIN = 6;
const byte ALARM_PIN = 12;
int primaryPumpPin;
int secondaryPumpPin;
boolean flashRed = false;
boolean secondPumpOn = false;
unsigned long levelHighStartTime;
void setup() {
Serial.begin(115200);
pinMode(PUMP1_PIN, OUTPUT); // Pump 1 Output;
pinMode(PUMP2_PIN, OUTPUT); // Pump 2 Output;
pinMode(HIGH_LED_PIN, OUTPUT); // Red LED to indicate high water level;
pinMode(LOW_LED_PIN, OUTPUT); // Green LED to indicate Low water level;
pinMode(ALARM_PIN, OUTPUT); // Alarm buzzer
pinMode(LOW_LEVEL_PIN, INPUT_PULLUP); // Low level switch pin goes here
pinMode(HIGH_LEVEL_PIN, INPUT_PULLUP); // High level switch pin goes here
// Set pump pins based on PrimaryPump (can be adjusted in loop if needed)
primaryPumpPin = PrimaryPump == 0 ? PUMP1_PIN : PUMP2_PIN;
secondaryPumpPin = PrimaryPump == 0 ? PUMP2_PIN : PUMP1_PIN;
}
void loop() {
checkLevel();
stateMachine();
flashRedLed();
}
void checkLevel() {
boolean lowLevel = !digitalRead(LOW_LEVEL_PIN);
boolean highLevel = !digitalRead(HIGH_LEVEL_PIN);
delay(30);// Simple debouncing ...
if (lowLevel) {
state = LEVELLOW;
}
if (highLevel) {
state = LEVELHIGH;
}
// The next states are not simulated in Wokwi but
// could be possible with a real limit switch
if (!lowLevel && !highLevel) {
state = LEVELNORMAL;
}
if (lowLevel && highLevel) {
Serial.println("Sensor defect -> Error!!");
}
}
void stateMachine() {
switch (state) {
case LEVELLOW:
lowLevel();
break;
case LEVELNORMAL:
normalLevel();
break;
case LEVELHIGH:
highLevel();
break;
}
}
void lowLevel() {
if (lastState != LEVELLOW) {
Serial.println("LOW");
flashRed = false;
digitalWrite(ALARM_PIN, LOW); // Alarm Off
digitalWrite(LOW_LED_PIN, HIGH); // Green LED ON
digitalWrite(HIGH_LED_PIN, LOW); // Red LED Off
digitalWrite(primaryPumpPin, LOW); // Stop Pump (assuming any pump was running)
digitalWrite(secondaryPumpPin, LOW);
// Now we exchange the pumpPins for the next cycle
byte tempPin = primaryPumpPin;
primaryPumpPin = secondaryPumpPin;
secondaryPumpPin = tempPin;
secondPumpOn = false;
lastState = state;
}
}
void normalLevel() {
// Normal Level - Turn off LEDs and Alarm
if (lastState != LEVELNORMAL) {
Serial.println("NORMAL");
flashRed = false;
digitalWrite(ALARM_PIN, LOW); // Alarm Off
digitalWrite(LOW_LED_PIN, LOW); // Green LED Off
digitalWrite(HIGH_LED_PIN, LOW); // Red LED Off
lastState = state;
}
}
void highLevel() {
// High Level Detected - Red LED ON and activate Pump sequence
if (lastState != LEVELHIGH) {
Serial.println("HIGH");
flashRed = false;
digitalWrite(ALARM_PIN, HIGH); // Alarm On
digitalWrite(LOW_LED_PIN, LOW); // Green LED Off
digitalWrite(HIGH_LED_PIN, HIGH); // Red LED On
digitalWrite(primaryPumpPin, HIGH); // Start Pump 1
levelHighStartTime = millis(); // Store the start time of LEVELHIGH here
lastState = state;
}
// Check if waitBeforePumpTwo has expired after start of the first pump
// If it has expired and pump 2 is off switch it on
if (millis() - levelHighStartTime >= waitBeforePumpTwo && !secondPumpOn) {
startSecondPump();
}
// The following part is not required but nice for this demo ...
static unsigned long lastPrint = 0;
if (millis() - lastPrint >= 1000 && !secondPumpOn) {
lastPrint = millis();
Serial.print(".");
}
}
void startSecondPump() {
// and flash Red Led
Serial.println("Start Second Pump");
flashRed = true;
secondPumpOn = true;
digitalWrite(ALARM_PIN, HIGH);
digitalWrite(secondaryPumpPin, HIGH); // Start Pump 2
}
void flashRedLed() {
static unsigned long lastChange = 0;
static byte ledState = HIGH;
if (!flashRed) {
return;
}
if (millis() - lastChange > 300) {
lastChange = millis();
digitalWrite(HIGH_LED_PIN, ledState);
ledState = !ledState;
}
}
Pump 1
Pump 2
Alarm
High Level
Low Level
Level Sim