#include <DHTesp.h>
#include <LiquidCrystal.h>
#include <Keypad.h>
// DHT Sensor configuration
#define DHTPIN 15 // DHT22 data pin
DHTesp dht; // Create an instance of DHTesp
// Relay Pins
#define RELAY1_PIN 2 // Pin for heater control
#define RELAY2_PIN 4 // Pin for fan control
// Define rows and columns for Keypad
const byte ROWS = 4;
const byte COLS = 4;
byte rowPins[ROWS] = {13, 12, 14, 27}; // Keypad rows
byte colPins[COLS] = {26, 25, 33, 32}; // Keypad columns
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// LCD settings
LiquidCrystal lcd(22, 23, 5, 18, 19, 21); // LCD pin configuration
// Temperature, humidity, and hysteresis settings
float setTemp = 25.0; // Default set temperature
float setHum = 50.0; // Default set humidity
float hystTemp = 1.0; // Temperature hysteresis
float hystHum = 5.0; // Humidity hysteresis
int menuPos = 0;
int hystMenuPos = 0;
bool inSettings = false;
bool displayMainMenu = false; // Flag to toggle between live display and main menu
String menuLines[4] = {
"Temp Settings",
"Hum Settings",
"Hyst Settings",
"Return"
};
// Hysteresis menu options
String hystMenuLines[3] = {
"Temp Hyst:",
"Hum Hyst:",
"Return"
};
void setup() {
lcd.begin(16, 2); // Initialize LCD
dht.setup(DHTPIN, DHTesp::DHT22); // Initialize DHT22 sensor using DHTesp
// Set relay pins as output
pinMode(RELAY1_PIN, OUTPUT);
pinMode(RELAY2_PIN, OUTPUT);
// Initial state: both heater and fan are off
digitalWrite(RELAY1_PIN, LOW);
digitalWrite(RELAY2_PIN, LOW);
}
void loop() {
// Read temperature and humidity from DHT22
TempAndHumidity data = dht.getTempAndHumidity(); // DHTesp method to get temperature and humidity
float currentTemp = data.temperature;
float currentHum = data.humidity;
if (inSettings) {
settingsMenu(); // Go to settings menu
} else if (displayMainMenu) {
displayMainMenuScreen();
char key = keypad.getKey();
if (key == '*') {
displayMainMenu = false; // Go back to live readings
} else if (key == 'A') {
inSettings = true; // Enter settings when 'A' is pressed
// menuPos = 0; // Reset menu position to the first setting
} else if (key == 'B') {
menuPos = (menuPos + 1) % 4; // Move down in menu
} else if (key == 'C') {
menuPos = (menuPos - 1 ) % 4; // Move up in menu
}
delay(200);
} else {
// Display live temperature and humidity values by default
displayLiveValues(currentTemp, currentHum);
char key = keypad.getKey();
if (key == '*') {
displayMainMenu = true; // Show main menu when * is pressed
}
}
// Control the heater based on temperature
if (currentTemp < setTemp - hystTemp) {
digitalWrite(RELAY1_PIN, HIGH); // Turn on heater
} else if (currentTemp > setTemp + hystTemp) {
digitalWrite(RELAY1_PIN, LOW); // Turn off heater
}
// Control the fan based on humidity
if (currentHum > setHum + hystHum) {
digitalWrite(RELAY2_PIN, HIGH); // Turn on fan
} else if (currentHum < setHum - hystHum) {
digitalWrite(RELAY2_PIN, LOW); // Turn off fan
}
}
// Function to display live temperature and humidity values
void displayLiveValues(float currentTemp, float currentHum) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Temp: ");
lcd.print(currentTemp);
lcd.print("C");
lcd.setCursor(0, 1);
lcd.print("Hum: ");
lcd.print(currentHum);
lcd.print("%");
}
// Function to display the main menu
void displayMainMenuScreen() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(">");
lcd.print(menuLines[menuPos]);
lcd.setCursor(0, 1);
lcd.print(menuLines[(menuPos + 1) % 4]);
}
// Menu to adjust temperature, humidity, and hysteresis settings
void settingsMenu() {
lcd.clear();
lcd.setCursor(0, 0);
if (menuPos == 0) { // Temperature Settings
lcd.print("Set Temp:");
lcd.setCursor(0, 1);
lcd.print(setTemp);
} else if (menuPos == 1) { // Humidity Settings
lcd.print("Set Hum:");
lcd.setCursor(0, 1);
lcd.print(setHum);
} else if (menuPos == 2) { // Hysteresis Settings
hysteresisMenu(); // Go to hysteresis settings menu
return; // Exit to prevent further execution
} else {
inSettings = false; // Exit the settings menu
lcd.clear(); // Clear the display when returning to the main menu
return;
}
char key = keypad.getKey();
if (key == '1') increaseSetting(); // Increase the setting
if (key == '2') decreaseSetting(); // Decrease the setting
if (key == '#') {
inSettings = false; // Exit settings and go back to the previous display
lcd.clear();
}
delay(200);
}
void hysteresisMenu() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(">"); // Display current hysteresis menu line
lcd.print(hystMenuLines[menuPos - 2]);
lcd.setCursor(0, 1);
lcd.print(hystMenuLines[(menuPos - 2 + 1) % 3]); // Display next hysteresis menu line
char key = keypad.getKey();
if (key == '1') increaseHystSetting(); // Increase the hysteresis setting
if (key == '2') decreaseHystSetting(); // Decrease the hysteresis setting
if (key == '#') {
inSettings = false; // Exit hysteresis settings and go back to previous display
lcd.clear();
}
if (key == 'B') {
menuPos = (menuPos + 1) % 3; // Move to next hysteresis menu option
}
if (key == 'C') {
menuPos = (menuPos - 1 + 3) % 3; // Move to previous hysteresis menu option
}
delay(200);
}
// Functions to increase and decrease temperature, humidity, and hysteresis settings
void increaseSetting() {
if (menuPos == 0) {
setTemp = min(setTemp + 1.0, 50.0); // Max temperature limit
displayFeedback("Temp set to:", setTemp);
} else if (menuPos == 1) {
setHum = min(setHum + 5.0, 100.0); // Max humidity limit
displayFeedback("Humidity set to:", setHum);
}
}
void decreaseSetting() {
if (menuPos == 0) {
setTemp = max(setTemp - 1.0, 0.0); // Min temperature limit
displayFeedback("Temp set to:", setTemp);
} else if (menuPos == 1) {
setHum = max(setHum - 5.0, 0.0); // Min humidity limit
displayFeedback("Humidity set to:", setHum);
}
}
// Functions to increase and decrease hysteresis settings
void increaseHystSetting() {
if (menuPos == 2) {
hystTemp = min(hystTemp + 0.5, 5.0); // Max temperature hysteresis limit
displayFeedback("Temp Hyst set to:", hystTemp);
} else if (menuPos == 3) {
hystHum = min(hystHum + 1.0, 10.0); // Max humidity hysteresis limit
displayFeedback("Hum Hyst set to:", hystHum);
}
}
void decreaseHystSetting() {
if (menuPos == 2) {
hystTemp = max(hystTemp - 0.5, 0.0); // Min temperature hysteresis limit
displayFeedback("Temp Hyst set to:", hystTemp);
} else if (menuPos == 3) {
hystHum = max(hystHum - 1.0, 0.0); // Min humidity hysteresis limit
displayFeedback("Hum Hyst set to:", hystHum);
}
}
// Function to display feedback on the LCD
void displayFeedback(String message, float value) {
lcd.clear();
lcd.print(message);
lcd.setCursor(0, 1);
lcd.print(value);
delay(100); // Display feedback for a short duration
}