#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>
// Constants and Pin Definitions
#define NUM_SENSORS 4 // Number of potentiometers
#define BASE_SERVO_TIME 4000 // Mandatory time for each servo in ms (4 seconds)
#define TOTAL_SERVO_LOOP_TIME 24000 // Total loop time in ms (24 seconds)
#define EXTRA_TIME 8000 // Additional time to distribute among servos based on moisture
// Potentiometer pins
const int potPins[NUM_SENSORS] = {A0, A1, A2, A3}; // Analog pins for potentiometers
// LCD and Servo
LiquidCrystal_I2C lcd(0x27, 20, 4); // LCD with I2C address 0x27
Servo servos[NUM_SENSORS]; // Array to store each servo
const int servoPins[NUM_SENSORS] = {3, 5, 6, 9}; // Updated servo pins
void setup() {
Serial.begin(9600);
// Initialize the LCD with 20 columns and 4 rows
lcd.init();
lcd.backlight();
// Attach each servo motor to its pin and initialize at 0 position
for (int i = 0; i < NUM_SENSORS; i++) {
servos[i].attach(servoPins[i]);
servos[i].write(0);
}
// Display welcome message on LCD
lcd.print("Irrigation System");
delay(2000);
lcd.clear();
}
void loop() {
// Calculate total moisture to determine extra time distribution
float moistureLevels[NUM_SENSORS];
float totalMoisture = 0;
// Read moisture levels for each field
for (int i = 0; i < NUM_SENSORS; i++) {
int potValue = analogRead(potPins[i]);
moistureLevels[i] = map(potValue, 0, 1023, 0, 100); // Map to 0-100%
totalMoisture += (100 - moistureLevels[i]); // Dryness factor for time allocation
}
// Track moisture and corresponding watering time for each field
for (int i = 0; i < NUM_SENSORS; i++) {
// Calculate the proportion of extra time based on dryness
int additionalTime = (totalMoisture > 0) ? (int)(EXTRA_TIME * ((100 - moistureLevels[i]) / totalMoisture)) : 0;
int fieldTime = BASE_SERVO_TIME + additionalTime;
// Display moisture data and field time on LCD
displayData(i, moistureLevels[i], fieldTime);
// Move servo to 90 degrees, wait, and then return to 0
servos[i].write(90);
delay(fieldTime);
servos[i].write(0);
// Print to serial monitor for debugging
Serial.print("Field ");
Serial.print(i + 1);
Serial.print(" Moisture: ");
Serial.print(moistureLevels[i]);
Serial.print("%, Time: ");
Serial.print(fieldTime / 1000.0, 1);
Serial.println(" s");
// Delay to allow for LCD readability between fields
delay(500);
}
// Delay between full loop cycles
delay(1000);
}
// Function to display data on LCD
void displayData(int fieldIndex, float moisture, int time) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Field ");
lcd.print(fieldIndex + 1); // Field numbering starts at 1
lcd.print(" Moisture:");
lcd.setCursor(0, 1);
lcd.print(moisture, 1);
lcd.print("%");
lcd.setCursor(0, 2);
lcd.print("Time: ");
lcd.print(time / 1000.0, 1); // Display time in seconds
lcd.print(" s");
delay(2000); // Hold display for 2 seconds for readability
}