#include <LiquidCrystal.h>
#include <Servo.h>
#include <DHT.h>
#define DHT_PIN 2
#define DHT_TYPE DHT11
#define SERVO_PIN 3
#define RED_LED_PIN 11
#define YELLOW_LED_PIN 12
#define GREEN_LED_PIN 13
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
DHT dht(DHT_PIN, DHT_TYPE);
Servo servo;
enum Button {
BUTTON_NONE,
BUTTON_RIGHT,
BUTTON_UP,
BUTTON_DOWN,
BUTTON_LEFT,
BUTTON_SELECT
};
enum State {
MAIN_MENU,
SENSOR_MENU,
TEMPERATURE_VIEW,
HUMIDITY_VIEW,
SERVO_CONTROL,
LED_MENU,
RED_LED_CONTROL,
YELLOW_LED_CONTROL,
GREEN_LED_CONTROL,
AUTO_MODE
};
State currentState = MAIN_MENU;
const char* mainMenu[] = {
"SENSOR",
"SERVO",
"LED",
"AUTO MODE"
};
const char* sensorMenu[] = {
"TEMPERATURE",
"HUMIDITY"
};
const char* ledMenu[] = {
"RED",
"YELLOW",
"GREEN"
};
int mainMenuIndex = 0;
int sensorMenuIndex = 0;
int ledMenuIndex = 0;
int servoAngle = 90;
bool redLEDState = false;
bool yellowLEDState = false;
bool greenLEDState = false;
float temperature = 0.0;
float humidity = 0.0;
unsigned long lastSensorRead = 0;
unsigned long lastAutoDisplay = 0;
const unsigned long sensorInterval = 2000;
const unsigned long autoDisplayInterval = 2000;
bool autoDisplayPage = false;
Button readButton() {
int value = analogRead(A0);
if (value < 50)
return BUTTON_RIGHT;
if (value < 200)
return BUTTON_UP;
if (value < 400)
return BUTTON_DOWN;
if (value < 600)
return BUTTON_LEFT;
if (value < 800)
return BUTTON_SELECT;
return BUTTON_NONE;
}
void waitButtonRelease() {
while (readButton() != BUTTON_NONE) {
delay(10);
}
delay(100);
}
void displayMainMenu() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("MAIN MENU");
lcd.setCursor(0, 1);
lcd.print("> ");
lcd.print(mainMenu[mainMenuIndex]);
}
void displaySensorMenu() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("SENSOR");
lcd.setCursor(0, 1);
lcd.print("> ");
lcd.print(sensorMenu[sensorMenuIndex]);
}
void displayLEDMenu() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("LED CONTROL");
lcd.setCursor(0, 1);
lcd.print("> ");
lcd.print(ledMenu[ledMenuIndex]);
}
void readSensor() {
float newTemperature = dht.readTemperature();
float newHumidity = dht.readHumidity();
if (!isnan(newTemperature)) {
temperature = newTemperature;
}
if (!isnan(newHumidity)) {
humidity = newHumidity;
}
}
void showTemperature() {
readSensor();
lcd.setCursor(0, 0);
lcd.print("TEMPERATURE ");
lcd.setCursor(0, 1);
lcd.print(temperature, 1);
lcd.print((char)223);
lcd.print("C ");
}
void showHumidity() {
readSensor();
lcd.setCursor(0, 0);
lcd.print("HUMIDITY ");
lcd.setCursor(0, 1);
lcd.print(humidity, 1);
lcd.print("% ");
}
void displayServoControl() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("SERVO CONTROL");
lcd.setCursor(0, 1);
lcd.print("ANGLE: ");
lcd.print(servoAngle);
lcd.print((char)223);
}
void displayLEDControl(const char* ledName, bool state) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(ledName);
lcd.setCursor(0, 1);
if (state) {
lcd.print("STATUS: ON");
} else {
lcd.print("STATUS: OFF");
}
}
void displayAutoPage1() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("HUM:");
lcd.print(humidity, 0);
lcd.print("%");
lcd.setCursor(0, 1);
lcd.print("TEMP:");
lcd.print(temperature, 1);
lcd.print(" C");
}
void displayAutoPage2() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("LED: ");
if (temperature < 25.0) {
lcd.print("GREEN");
}
else if (temperature < 30.0) {
lcd.print("YELLOW");
}
else {
lcd.print("RED");
}
lcd.setCursor(0, 1);
lcd.print("SERVO: ");
lcd.print(servoAngle);
lcd.print(" DEG");
}
void runAutoMode() {
readSensor();
if (temperature < 31.3) {
digitalWrite(GREEN_LED_PIN, HIGH);
digitalWrite(YELLOW_LED_PIN, LOW);
digitalWrite(RED_LED_PIN, LOW);
servoAngle = 0;
servo.write(servoAngle);
}
else if (temperature < 31.5) {
digitalWrite(GREEN_LED_PIN, LOW);
digitalWrite(YELLOW_LED_PIN, HIGH);
digitalWrite(RED_LED_PIN, LOW);
servoAngle = 90;
servo.write(servoAngle);
}
else {
digitalWrite(GREEN_LED_PIN, LOW);
digitalWrite(YELLOW_LED_PIN, LOW);
digitalWrite(RED_LED_PIN, HIGH);
servoAngle = 180;
servo.write(servoAngle);
}
}
void handleMainMenu(Button button) {
if (button == BUTTON_UP) {
mainMenuIndex--;
if (mainMenuIndex < 0) {
mainMenuIndex = 3;
}
displayMainMenu();
}
else if (button == BUTTON_DOWN) {
mainMenuIndex++;
if (mainMenuIndex > 3) {
mainMenuIndex = 0;
}
displayMainMenu();
}
else if (button == BUTTON_SELECT) {
switch (mainMenuIndex) {
case 0:
currentState = SENSOR_MENU;
sensorMenuIndex = 0;
displaySensorMenu();
break;
case 1:
currentState = SERVO_CONTROL;
displayServoControl();
break;
case 2:
currentState = LED_MENU;
ledMenuIndex = 0;
displayLEDMenu();
break;
case 3:
currentState = AUTO_MODE;
autoDisplayPage = false;
lastSensorRead = millis();
lastAutoDisplay = millis();
runAutoMode();
displayAutoPage1();
break;
}
}
}
void handleSensorMenu(Button button) {
if (button == BUTTON_UP) {
sensorMenuIndex--;
if (sensorMenuIndex < 0) {
sensorMenuIndex = 1;
}
displaySensorMenu();
}
else if (button == BUTTON_DOWN) {
sensorMenuIndex++;
if (sensorMenuIndex > 1) {
sensorMenuIndex = 0;
}
displaySensorMenu();
}
else if (button == BUTTON_SELECT) {
if (sensorMenuIndex == 0) {
lcd.clear();
currentState = TEMPERATURE_VIEW;
lastSensorRead = millis();
showTemperature();
}
else {
lcd.clear();
currentState = HUMIDITY_VIEW;
lastSensorRead = millis();
showHumidity();
}
}
else if (button == BUTTON_LEFT) {
currentState = MAIN_MENU;
displayMainMenu();
}
}
void handleTemperatureView(Button button) {
if (button == BUTTON_LEFT || button == BUTTON_SELECT) {
currentState = SENSOR_MENU;
displaySensorMenu();
}
}
void handleHumidityView(Button button) {
if (button == BUTTON_LEFT || button == BUTTON_SELECT) {
currentState = SENSOR_MENU;
displaySensorMenu();
}
}
void handleServoControl(Button button) {
if (button == BUTTON_UP) {
servoAngle++;
if (servoAngle > 180) {
servoAngle = 180;
}
servo.write(servoAngle);
displayServoControl();
}
else if (button == BUTTON_DOWN) {
servoAngle--;
if (servoAngle < 0) {
servoAngle = 0;
}
servo.write(servoAngle);
displayServoControl();
}
else if (button == BUTTON_RIGHT) {
servoAngle += 10;
if (servoAngle > 180) {
servoAngle = 180;
}
servo.write(servoAngle);
displayServoControl();
}
else if (button == BUTTON_LEFT) {
servoAngle -= 10;
if (servoAngle < 0) {
servoAngle = 0;
}
servo.write(servoAngle);
displayServoControl();
}
else if (button == BUTTON_SELECT) {
currentState = MAIN_MENU;
displayMainMenu();
}
}
void handleLEDMenu(Button button) {
if (button == BUTTON_UP) {
ledMenuIndex--;
if (ledMenuIndex < 0) {
ledMenuIndex = 2;
}
displayLEDMenu();
}
else if (button == BUTTON_DOWN) {
ledMenuIndex++;
if (ledMenuIndex > 2) {
ledMenuIndex = 0;
}
displayLEDMenu();
}
else if (button == BUTTON_SELECT) {
switch (ledMenuIndex) {
case 0:
currentState = RED_LED_CONTROL;
displayLEDControl("RED LED", redLEDState);
break;
case 1:
currentState = YELLOW_LED_CONTROL;
displayLEDControl("YELLOW LED", yellowLEDState);
break;
case 2:
currentState = GREEN_LED_CONTROL;
displayLEDControl("GREEN LED", greenLEDState);
break;
}
}
else if (button == BUTTON_LEFT) {
currentState = MAIN_MENU;
displayMainMenu();
}
}
void handleRedLED(Button button) {
if (button == BUTTON_RIGHT) {
redLEDState = !redLEDState;
digitalWrite(RED_LED_PIN, redLEDState ? HIGH : LOW);
displayLEDControl("RED LED", redLEDState);
}
else if (button == BUTTON_LEFT) {
currentState = LED_MENU;
displayLEDMenu();
}
}
void handleYellowLED(Button button) {
if (button == BUTTON_RIGHT) {
yellowLEDState = !yellowLEDState;
digitalWrite(YELLOW_LED_PIN, yellowLEDState ? HIGH : LOW);
displayLEDControl("YELLOW LED", yellowLEDState);
}
else if (button == BUTTON_LEFT) {
currentState = LED_MENU;
displayLEDMenu();
}
}
void handleGreenLED(Button button) {
if (button == BUTTON_RIGHT) {
greenLEDState = !greenLEDState;
digitalWrite(GREEN_LED_PIN, greenLEDState ? HIGH : LOW);
displayLEDControl("GREEN LED", greenLEDState);
}
else if (button == BUTTON_LEFT) {
currentState = LED_MENU;
displayLEDMenu();
}
}
void handleAutoMode(Button button) {
if (button == BUTTON_LEFT || button == BUTTON_SELECT) {
digitalWrite(RED_LED_PIN, LOW);
digitalWrite(YELLOW_LED_PIN, LOW);
digitalWrite(GREEN_LED_PIN, LOW);
redLEDState = false;
yellowLEDState = false;
greenLEDState = false;
servoAngle = 90;
servo.write(servoAngle);
currentState = MAIN_MENU;
displayMainMenu();
}
}
void setup() {
lcd.begin(16, 2);
dht.begin();
servo.attach(SERVO_PIN);
servo.write(servoAngle);
pinMode(RED_LED_PIN, OUTPUT);
pinMode(YELLOW_LED_PIN, OUTPUT);
pinMode(GREEN_LED_PIN, OUTPUT);
digitalWrite(RED_LED_PIN, LOW);
digitalWrite(YELLOW_LED_PIN, LOW);
digitalWrite(GREEN_LED_PIN, LOW);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("SMART CONTROL");
lcd.setCursor(0, 1);
lcd.print("STATION");
delay(2000);
displayMainMenu();
}
void loop() {
Button button = readButton();
if (button != BUTTON_NONE) {
switch (currentState) {
case MAIN_MENU: handleMainMenu(button); break;
case SENSOR_MENU: handleSensorMenu(button); break;
case TEMPERATURE_VIEW: handleTemperatureView(button); break;
case HUMIDITY_VIEW: handleHumidityView(button); break;
case SERVO_CONTROL: handleServoControl(button); break;
case LED_MENU: handleLEDMenu(button); break;
case RED_LED_CONTROL: handleRedLED(button); break;
case YELLOW_LED_CONTROL: handleYellowLED(button); break;
case GREEN_LED_CONTROL: handleGreenLED(button); break;
case AUTO_MODE: handleAutoMode(button); break;
}
waitButtonRelease();
}
if (currentState == AUTO_MODE) {
if (millis() - lastSensorRead >= sensorInterval) {
lastSensorRead = millis();
runAutoMode();
}
if (millis() - lastAutoDisplay >= autoDisplayInterval) {
lastAutoDisplay = millis();
autoDisplayPage = !autoDisplayPage;
if (autoDisplayPage) {
displayAutoPage2();
} else {
displayAutoPage1();
}
}
}
if (currentState == TEMPERATURE_VIEW || currentState == HUMIDITY_VIEW) {
if (millis() - lastSensorRead >= sensorInterval) {
lastSensorRead = millis();
if (currentState == TEMPERATURE_VIEW) {
showTemperature();
} else if (currentState == HUMIDITY_VIEW) {
showHumidity();
}
}
}
}