#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
// LCD display settings
#define I2C_ADDR 0x27
#define LCD_COLS 16
#define LCD_ROWS 2
// Keypad settings
const byte ROWS = 4; // Four rows
const byte COLS = 4; // Four columns
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {9, 8, 7, 6}; // Connect to the row pinouts of the keypad
byte colPins[COLS] = {5, 4, 3, 2}; // Connect to the column pinouts of the keypad
// Initialize the Keypad and LCD
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLS, LCD_ROWS);
int threshold = 0; // Threshold for soil moisture
bool thresholdEntered = false; // Flag to check if threshold is entered
// Pins for relay and moisture sensor
int relayPin = 10;
int moistureSensorPin = A0;
// State definitions for the state machine
enum State {
WELCOME, // Initial welcome state
MAIN_MENU, // Main menu state
ENTER_THRESHOLD, // State for entering threshold
VIEW_STATUS, // State for viewing status
RESET_SYSTEM // State for resetting the system
};
State currentState = WELCOME; // Start with the welcome state
void setup() {
lcd.init(); // Initialize the LCD
lcd.backlight(); // Turn on the backlight
pinMode(relayPin, OUTPUT); // Set relay pin as output
displayWelcomeMessage(); // Display the welcome message
}
void loop() {
char key = keypad.getKey(); // Read the key pressed on the keypad
switch (currentState) {
case WELCOME:
if (millis() > 4000) { // Display welcome message for 4 seconds
lcd.clear();
currentState = MAIN_MENU;
displayMainMenu(); // Show main menu after welcome message
}
break;
case MAIN_MENU:
if (key) handleMainMenuInput(key); // Handle input in main menu
break;
case ENTER_THRESHOLD:
if (key) handleThresholdInput(key); // Handle threshold input
break;
case VIEW_STATUS:
displayStatus(); // Display the current status
if (key == 'C') { // Go back to main menu if 'C' is pressed
currentState = MAIN_MENU;
lcd.clear();
displayMainMenu();
}
break;
case RESET_SYSTEM:
resetSystem(); // Reset the system
currentState = MAIN_MENU;
displayMainMenu(); // Go back to main menu after resetting
break;
}
}
void displayWelcomeMessage() {
lcd.setCursor(0, 0);
lcd.print("Welcome to Smart");
lcd.setCursor(3, 1);
lcd.print("Irrigation");
}
void displayMainMenu() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("1:Set Threshold");
lcd.setCursor(0, 1);
lcd.print("2:View Status");
}
void handleMainMenuInput(char key) {
if (key == '1') { // If '1' is pressed, enter threshold input state
currentState = ENTER_THRESHOLD;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter threshold:");
lcd.setCursor(7, 1);
lcd.print("__%");
} else if (key == '2') { // If '2' is pressed, enter view status state
currentState = VIEW_STATUS;
lcd.clear();
}
}
void handleThresholdInput(char key) {
if (key >= '0' && key <= '9') { // If a number key is pressed
if (threshold < 10) {
threshold = threshold * 10 + (key - '0');
} else {
threshold = (threshold % 10) * 10 + (key - '0');
}
lcd.setCursor(7, 1);
lcd.print("__% "); // Clear previous threshold
lcd.setCursor(7, 1);
lcd.print(threshold); // Display currently entered threshold
} else if (key == 'C') { // Clear the threshold if 'C' is pressed
threshold = 0;
lcd.setCursor(7, 1);
lcd.print("__%");
} else if (key == 'D') { // Confirm the threshold if 'D' is pressed
thresholdEntered = true;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Threshold set:");
lcd.setCursor(6, 1);
lcd.print(threshold);
lcd.print("%");
delay(2000);
currentState = MAIN_MENU;
lcd.clear();
displayMainMenu(); // Go back to main menu after setting threshold
}
}
void displayStatus() {
if (thresholdEntered) {
int moisture = analogRead(moistureSensorPin); // Read moisture level
int moisturePercentage = map(moisture, 0, 1023, 0, 100); // Convert to percentage
lcd.setCursor(0, 0);
lcd.print("Moisture:");
lcd.print(moisturePercentage);
lcd.print("% ");
lcd.setCursor(0, 1);
lcd.print("Th:");
lcd.print(threshold);
lcd.print("% ");
if (moisturePercentage < threshold) {
digitalWrite(relayPin, HIGH); // Turn on the pump if moisture is below threshold
lcd.print("Pump: ON ");
} else {
digitalWrite(relayPin, LOW); // Turn off the pump if moisture is above threshold
lcd.print("Pump: OFF");
}
} else {
lcd.setCursor(0, 0);
lcd.print("Threshold not set");
lcd.setCursor(0, 1);
lcd.print("Press 'C' to go back");
}
}
void resetSystem() {
threshold = 0;
thresholdEntered = false;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("System reset");
delay(2000);
lcd.clear();
}