#include <Servo.h>
#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal_I2C.h>
// Pin definitions
const int trigPin = 9;
const int echoPin = 10;
const int servoPin1 = 12;
const int servoPin2 = 5;
const int servoPin3 = 13;
//const int rs = 7, en = 8, d4 = 4, d5 = 2, d6 = 6, d7 = 3; // LCD pins
RTC_DS3231 rtc; // Using DS3231
//LiquidCrystal lcd(rs, en, d4, d5, d6, d7);//
LiquidCrystal_I2C lcd(0x27, 16, 2);
Servo servo1, servo2, servo3;
// Start date and time for water supply
const int startYear = 2025;
const int startMonth = 02;
const int startDay = 03;
const int startHour = 12;
const int startMinute = 0;
// Timing control
unsigned long lastSensedTime = 0; // For continuous sensor reading (non-blocking)
const unsigned long sensingInterval = 1000; // 1 second interval for ultrasonic sensor
// Water supply timing
unsigned long lastSupplyTime = 0;
unsigned long supplyTime = 0; // Total time for supply
bool supplyInProgress = false;
int currentWaterLevel = 0; // To store the last sensed water level
void setup() {
Serial.begin(9600);
//lcd.begin(16, 2);//
lcd.init(); // Initialize the LCD with I2C
lcd.backlight(); // Turn on the backlight
servo1.attach(servoPin1);
servo2.attach(servoPin2);
servo3.attach(servoPin3);
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
if (rtc.lostPower()) {
rtc.adjust(DateTime(2025,02 , 03, 12, 0, 0)); // Set this to the current date and time
}
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
turnOffAllServos(); // Set all servos to off (closed)
}
void loop() {
DateTime now = rtc.now();
// Display current date and time on the LCD
lcd.setCursor(0, 0);
lcd.print("Time:");
lcd.print(now.hour());
lcd.print(":");
if (now.minute() < 10) lcd.print("0"); // Add leading zero if needed
lcd.print(now.minute());
// Check if the current date and time match or exceed the start date and time
bool supplyAllowed = isStartTimeReached(now);
// Continuously sense the water level, no delay here
if (millis() - lastSensedTime >= sensingInterval) {
lastSensedTime = millis();
currentWaterLevel = senseWaterLevel();
Serial.print("Water Level: ");
Serial.print(currentWaterLevel);
Serial.println(" cm");
// Display water level on LCD
lcd.setCursor(0, 1);
lcd.print("Level: ");
lcd.print(currentWaterLevel);
lcd.print(" cm "); // Clear any leftover characters
// Supply water based on the current water level
if (supplyAllowed && !supplyInProgress) {
// Start the water supply based on water level
if (currentWaterLevel >= 50) {
// No water supply if the level is >= 50 cm
Serial.println("Water level >= 50 cm, supply stopped.");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Water level 50 cm");
return; // Exit if the water level is 50 cm or more
} else if (currentWaterLevel >= 20) {
// Supply for 1 minute per area (total 3 minutes)
supplyInProgress = true;
supplyWater(30 * 1000); // 1 minute per area
} else if (currentWaterLevel >= 15) {
// Supply for 2 minutes per area (total 6 minutes)
supplyInProgress = true;
supplyWater(1 * 60000); // 2 minutes per area
} else if (currentWaterLevel >= 5) {
// Supply for 2 minutes per area (total 6 minutes)
supplyInProgress = true;
supplyWater(2 * 60000); // 2 minutes per area
}
}
}
// If supply is in progress, continue supplying until the total supply time is met
if (supplyInProgress && millis() - lastSupplyTime >= supplyTime) {
turnOffAllServos(); // Stop supplying water to all areas
supplyInProgress = false;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Supply Stopped");
}
}
int senseWaterLevel() {
// Continuously sense the water level by using the ultrasonic sensor
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
int duration = pulseIn(echoPin, HIGH);
int distance = duration * 0.034 / 2; // Distance in cm
return distance;
}
void openGate(Servo& servo, const char* areaMessage) {
turnOffAllServos(); // Ensure other servos are off
servo.write(180); // Open specified servo
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(areaMessage);
Serial.println(areaMessage);
}
void turnOffAllServos() {
servo1.write(0);
servo2.write(0);
servo3.write(0);
}
bool isStartTimeReached(DateTime now) {
// Check if the current date and time matches or exceeds the start date and time
if (now.year() > startYear) return true;
if (now.year() == startYear) {
if (now.month() > startMonth) return true;
if (now.month() == startMonth) {
if (now.day() > startDay) return true;
if (now.day() == startDay) {
if (now.hour() > startHour) return true;
if (now.hour() == startHour && now.minute() >= startMinute) return true;
}
}
}
return false;
}
void supplyWater(unsigned long supplyDuration) {
// Total supply time for each area
unsigned long areaSupplyTime = supplyDuration;
// Start supplying water to Area 1
openGate(servo1, "Area 1 Supplying");
lastSupplyTime = millis();
while (millis() - lastSupplyTime < areaSupplyTime) {
// Wait until supply duration is complete for Area 1
}
turnOffAllServos(); // Ensure servo1 is off before moving to the next area
// Start supplying water to Area 2
openGate(servo2, "Area 2 Supplying");
lastSupplyTime = millis();
while (millis() - lastSupplyTime < areaSupplyTime) {
// Wait until supply duration is complete for Area 2
}
turnOffAllServos(); // Ensure servo2 is off before moving to the next area
// Start supplying water to Area 3
openGate(servo3, "Area 3 Supplying");
lastSupplyTime = millis();
while (millis() - lastSupplyTime < areaSupplyTime) {
// Wait until supply duration is complete for Area 3
}
turnOffAllServos(); // Ensure servo3 is off after final supply
}