#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // Address 0x27 for a 16x2 LCD
const int trigPin = 7; // Ultrasonic sensor trigger pin
const int echoPin = 6; // Ultrasonic sensor echo pin
const int switchPin = 2; // Slide switch pin
const int potPin = A1; // Slide potentiometer pin
const int relayPin = 12; // Relay control pin
const int buzzerPin = 11; // Buzzer pin
const int numReadings = 10; // Number of readings for moving average filter
const int lowWaterLevel = 10; // Threshold for low water level
const int priorityThreshold = 30; // Threshold for priority level (percentage)
int waterLevel = 0; // Current water level (percentage)
int priorityLevel = 0; // Priority level based on water level
bool isManualMode = false; // Flag for manual mode
int readings[numReadings]; // Array to store ultrasonic sensor readings
int readIndex = 0; // Index for reading array
int total = 0; // Total of readings
void setup() {
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(switchPin, INPUT_PULLUP);
pinMode(relayPin, OUTPUT);
pinMode(buzzerPin, OUTPUT);
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print("WATER LEVEL:");
lcd.setCursor(0, 1);
lcd.print("PUMP:OFF MANUAL");
// Initialize LCD backlight
lcd.setBacklight(HIGH);
// Initialize array to 0
for (int i = 0; i < numReadings; ++i) {
readings[i] = 0;
}
}
void loop() {
// Read water level using moving average filter
total -= readings[readIndex]; // Subtract the oldest reading
readings[readIndex] = measureDistance(); // Read from the sensor
total += readings[readIndex]; // Add the new reading
readIndex = (readIndex + 1) % numReadings; // Advance to the next position
// Calculate the average distance
int distance = total / numReadings;
// Calculate water level percentage
int tankCapacity = calculateTankCapacity(distance); // Calculate tank capacity based on distance
waterLevel = map(distance, 0, tankCapacity, 0, 100); // Map distance to a percentage value based on tank capacity
// Ensure water level is within 0 to 100 range
waterLevel = constrain(waterLevel, 0, 100);
// Read switch state
isManualMode = digitalRead(switchPin) == LOW;
// Calculate priority level based on water level
priorityLevel = calculatePriorityLevel(waterLevel);
// Update LCD with water level
lcd.setCursor(12, 0);
lcd.print(waterLevel);
lcd.print("% ");
lcd.setCursor(5, 1);
if (digitalRead(relayPin) == HIGH) {
lcd.print("ON ");
} else {
lcd.print("OFF");
}
lcd.setCursor(9, 1);
if (isManualMode) {
lcd.print("MANUAL");
} else {
lcd.print("AUTO ");
}
// Control pump based on priority and manual mode
if (!isManualMode) {
if (priorityLevel >= priorityThreshold && digitalRead(relayPin) == LOW) {
activatePump();
} else if (priorityLevel < priorityThreshold && digitalRead(relayPin) == HIGH) {
deactivatePump();
}
}
// Check for low water level
if (waterLevel <= lowWaterLevel) {
activateBuzzer();
} else {
deactivateBuzzer();
}
delay(500);
}
int measureDistance() {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
long duration = pulseIn(echoPin, HIGH);
int distance = duration * 0.034 / 2;
return distance;
}
int calculateTankCapacity(int distance) {
// Define the formula to calculate tank capacity based on distance
// For example, you can use a linear formula or any other appropriate method
// This is just an example, adjust it according to your specific setup
return map(distance, 0, 150, 50, 150); // Adjust this mapping to match your tank capacity
}
int calculatePriorityLevel(int waterLevel) {
// Implement area priority logic here
// For example, prioritize bathroom > kitchen > bedroom
if (waterLevel >= 90) {
return 100; // High priority
} else if (waterLevel >= 60) {
return 75; // Medium priority
} else {
return 50; // Low priority
}
}
void activatePump() {
digitalWrite(relayPin, HIGH);
}
void deactivatePump() {
digitalWrite(relayPin, LOW);
}
void activateBuzzer() {
tone(buzzerPin, 1000); // Activate buzzer at 1kHz frequency
}
void deactivateBuzzer() {
noTone(buzzerPin); // Turn off buzzer
}