/*This code is to work with manual switching done via the CADIO app and Wemos D1 R1 board,
but without adding any buttons in the Arduino code itself. The control logic for the pumps
will still be managed by the Arduino, ensuring the pumps turn OFF automatically when they
reach the specified water levels, but manual activation will be done through external
signals connected parallelly with Contactor.*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Initialize the LCD (I2C address: 0x27, columns: 16, rows: 2)
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Constants for the ultrasonic sensor
const int trigPin = 9;
const int echoPin = 10;
// Pump relays pins
const int fillPumpPin = 7; // Relay controlling fill pump
const int drainPumpPin = 8; // Relay controlling drain pump
// Current sensor pins (to detect external pump activity)
const int fillPumpCurrentSensor = A0; // Current sensor for fill pump
const int drainPumpCurrentSensor = A1; // Current sensor for drain pump
// Measurement constants
const float poolDepth = 72.0; // 6 feet in inches
const float minFillHeight = 2.0; // 2 inches for filling pump OFF
const float maxDrainHeight = 66.0; // 5.5 feet in inches (66 inches)
// Variables
float distance = 0.0; // Distance measured by ultrasonic sensor
bool fillPumpOn = false; // Track if the fill pump is ON
bool drainPumpOn = false; // Track if the drain pump is ON
void setup() {
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(fillPumpPin, OUTPUT);
pinMode(drainPumpPin, OUTPUT);
digitalWrite(fillPumpPin, LOW); // Keep both pumps OFF initially
digitalWrite(drainPumpPin, LOW);
// Current sensor pins
pinMode(fillPumpCurrentSensor, INPUT);
pinMode(drainPumpCurrentSensor, INPUT);
Serial.begin(9600);
// Initialize the LCD
lcd.begin(16, 2);
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("PoolLevel:");
}
void loop() {
// Measure water level
distance = getWaterLevel();
float percentage = (distance / poolDepth) * 100;
// Display water percentage on LCD
lcd.setCursor(10, 0);
lcd.print(percentage);
lcd.print("% "); // Clear remaining characters
Serial.print("Water Level (inches): ");
Serial.println(distance);
// Read the current sensor values
int fillPumpCurrent = analogRead(fillPumpCurrentSensor);
int drainPumpCurrent = analogRead(drainPumpCurrentSensor);
// Determine whether the external pumps are running
bool externalFillPumpOn = (fillPumpCurrent > 100); // Adjust the threshold based on your sensor
bool externalDrainPumpOn = (drainPumpCurrent > 100);
// Sync Arduino relays with external pump state
if (externalFillPumpOn) {
fillPumpOn = true;
digitalWrite(fillPumpPin, HIGH); // Turn ON the Arduino-controlled fill pump relay
} else {
fillPumpOn = false;
digitalWrite(fillPumpPin, LOW); // Turn OFF the Arduino-controlled fill pump relay
}
if (externalDrainPumpOn) {
drainPumpOn = true;
digitalWrite(drainPumpPin, HIGH); // Turn ON the Arduino-controlled drain pump relay
} else {
drainPumpOn = false;
digitalWrite(drainPumpPin, LOW); // Turn OFF the Arduino-controlled drain pump relay
}
// Handle the draining pump based on water level
if (drainPumpOn && distance >= maxDrainHeight) {
// Automatically stop the drain pump when the max level is reached
drainPumpOn = true;
digitalWrite(drainPumpPin, LOW); // Turn OFF draining pump
Serial.println("Draining Pump OFF (Max Level Reached)");
delay(200);
}
// Handle the filling pump based on water level
if (fillPumpOn && distance <= minFillHeight) {
// Automatically stop the fill pump when the min level is reached
fillPumpOn = true;
digitalWrite(fillPumpPin, LOW); // Turn OFF filling pump
Serial.println("Filling Pump OFF (Min Level Reached)");
delay(200);
}
// Update the pump status on the LCD
lcd.setCursor(0, 1);
lcd.print("In: ");
lcd.print(fillPumpOn ? "ON " : "OFF");
lcd.print(" Out: ");
lcd.print(drainPumpOn ? "ON" : "OFF");
delay(500); // Wait for half a second before the next measurement
}
// Function to calculate the water level using the ultrasonic sensor
float getWaterLevel() {
long duration;
float distance;
// Send the trigger signal
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Measure the duration of the echo signal
duration = pulseIn(echoPin, HIGH);
// Calculate distance in inches (duration / 2 to account for travel time to and from the object)
distance = (duration / 2) / 74; // Convert to inches (sound speed 0.0343 cm/us)
// Calculate water depth based on pool depth
float waterLevel = poolDepth - distance;
return waterLevel;
}