#include <EEPROM.h>
#include <Servo.h>
#include <LiquidCrystal.h>
#include <DHT.h>
#include <Keypad.h>
// Definitions for LCD pin connections
#define LCD_RS 2
#define LCD_EN 3
#define LCD_D4 4
#define LCD_D5 5
#define LCD_D6 6
#define LCD_D7 7
// Pin number for the DHT sensor
#define DHT_PIN 10
// Dimensions of the keypad
#define ROWS 4
#define COLS 4
// Keypad button layout
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
// Pins connected to keypad rows and columns
byte rowPins[ROWS] = {1, 0, 14, 15};
byte colPins[COLS] = {A2, A3, A4, A5};
// Creating LCD object
LiquidCrystal lcd(LCD_RS, LCD_EN, LCD_D4, LCD_D5, LCD_D6, LCD_D7);
// Creating Keypad object
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// Type and pin of the DHT sensor
#define DHT_TYPE DHT22
DHT dht(DHT_PIN, DHT_TYPE);
// Constants
const int MIN_WATER_LEVEL = 0;
const int MAX_WATER_LEVEL = 150;
const int PUMP_THRESHOLD = 30;
const int PUMP_OFF_THRESHOLD = 99;
const float TEMP_THRESHOLD = 30.0;
// Variables
long duration, inches;
int set_val,percentage;
bool state,pump;
Servo x;
int position=0;
void setup() {
// Attaching servo motor pin
x.attach(6);
// Starting serial communication
Serial.begin(9600);
// Initializing the LCD
lcd.begin(20, 4);
// Starting the DHT sensor
dht.begin();
// Printing initial messages on the LCD
lcd.print("WATER LEVEL:");
lcd.setCursor(0, 1);
lcd.print("Temp:");
lcd.setCursor(0, 2);
lcd.print("PUMP:OFF");
lcd.setCursor(0, 3);
lcd.print("Humidity:");
// Setting pin modes
pinMode(8, OUTPUT);
pinMode(9, INPUT);
pinMode(13, OUTPUT);
pinMode(11, INPUT_PULLUP);
pinMode(12, OUTPUT);
// Reading water level setting from EEPROM
set_val = EEPROM.read(0);
// Checking water level setting limits
if(set_val > MAX_WATER_LEVEL )
set_val = MAX_WATER_LEVEL;
}
void loop() {
// Reading keypad inputs
char key = keypad.getKey();
// Performing actions based on the pressed key
if (key != NO_KEY) {
Serial.print("Pressed Key: ");
Serial.println(key);
// Changing mode with the # key
if (key == '#') {
state = !state;
// Writing mode to EEPROM
EEPROM.write(0, state);
updateModeDisplay();
}
// Toggling pump state with the * key
if (key == '*') {
pump = !pump;
// Updating pump pin
digitalWrite(12, pump);
updatePumpDisplay();
}
}
// Moving the servo motor
if (state) { // Automatic mode
float temperature = dht.readTemperature();
if (temperature > TEMP_THRESHOLD) {
// Rotate the sprinkler head to cover a wider area
for (position = 0; position <= 180; position += 1) {
x.write(position);
delay(8);
}
for (position = 180; position >= 0; position -= 1) {
x.write(position);
delay(8);
}
} else {
for (position = 0; position <= 40; position += 1) {
x.write(position);
delay(8);
}
for (position = 40; position >= 0; position -= 1) {
x.write(position);
delay(8);
}// Adjust position as needed
}
}
// Reading water level with ultrasonic sensor
digitalWrite(3, LOW);
delayMicroseconds(2);
digitalWrite(8, HIGH);
delayMicroseconds(10);
digitalWrite(8, LOW);
duration = pulseIn(9, HIGH);
inches = microsecondsToInches(duration);
// Calculating water level percentage
percentage = (set_val - inches) * 100 / set_val;
// Printing water level on LCD
lcd.setCursor(12, 0);
if (percentage < MIN_WATER_LEVEL) percentage = MIN_WATER_LEVEL;
lcd.print(percentage);
lcd.print("% ");
// Controlling the pump
if (percentage < PUMP_THRESHOLD && digitalRead(11)) pump = true;
if (percentage > PUMP_OFF_THRESHOLD) pump = false;
digitalWrite(12, !pump);
// Printing pump status on LCD
lcd.setCursor(0, 2);
if (pump) lcd.print("PUMP:ON ");
else lcd.print("PUMP:OFF");
// Printing mode on LCD
lcd.setCursor(9, 2);
if (!digitalRead(11)) lcd.print("MANUAL");
else lcd.print("AUTO ");
// Writing water level to EEPROM or toggling pump state
if (!state && digitalRead(11)) {
state = true;
set_val = inches;
EEPROM.write(0, set_val);
}
if (!state && !digitalRead(11)) {
state = true;
pump = !pump;
}
// Reading temperature and humidity
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
// Printing temperature and humidity on LCD
lcd.setCursor(6, 1);
lcd.print(temperature, 1);
lcd.print("C");
lcd.setCursor(9, 3);
lcd.print(humidity, 1);
lcd.print("%");
// Controlling the temperature
// Controlling the temperature and buzzer
if (temperature > TEMP_THRESHOLD) {
tone(13, 262); // Play a tone at 262 Hz (Middle C)
} else {
noTone(13); // Stop playing tone
}
delay(500);
}
// Function to update mode display
void updateModeDisplay() {
lcd.setCursor(9, 2);
if (!state) {
lcd.print("MANUAL");
} else {
lcd.print("AUTO ");
}
}
// Function to update pump display
void updatePumpDisplay() {
lcd.setCursor(0, 2);
if (pump) {
lcd.print("PUMP:ON ");
} else {
lcd.print("PUMP:OFF");
}
}
// Function to convert microseconds to inches
long microsecondsToInches(long microseconds) {
return microseconds / 74 / 2;
}