#include <DHT.h>
#include <LiquidCrystal.h>
#include <DS3232RTC.h>
#include <Wire.h>
// #include <Time.h>
DS3232RTC myRTC;
#define SLAVE_ADDR 8
// Define Slave answer size
#define ANSWER_SIZE 16
#define DHT_PIN 2
#define DHT_TYPE DHT11
#define LCD_RS 2
#define LCD_EN 3
#define LCD_D4 4
#define LCD_D5 5
#define LCD_D6 6
#define LCD_D7 7
// Define the pins used for the push buttons
#define BUTTON_UP 9
#define BUTTON_DOWN 10
#define BUTTON_LEFT 11
#define BUTTON_RIGHT 12
#define BUTTON_SELECT 13
#define PHOTOSENSOR A0
#define SCREEN_MAIN 1
#define SCREEN_MENU 2
#define SCREEN_TEMP_MENU 3
#define SCREEN_DAY_TEMP_MENU 4
#define SCREEN_NIGHT_TEMP_MENU 5
#define SCREEN_FAN_MENU 6
#define SCREEN_LIGHT_MENU 7
#define SCREEN_HUMIDITY_MENU 8
#define MIN_DAY_TEMP 10
#define MAX_DAY_TEMP 50
#define MIN_NIGHT_TEMP 10
#define MAX_NIGHT_TEMP 50
#define MIN_FAN_CYCLES 0
#define MAX_FAN_CYCLES 12
#define MIN_FAN_CYCLE_DURATION 0
#define MAX_FAN_CYCLE_DURATION 120
LiquidCrystal lcd(LCD_RS, LCD_EN, LCD_D4, LCD_D5, LCD_D6, LCD_D7);
DHT dht(DHT_PIN, DHT_TYPE);
byte c1[8] = {
B00100,
B01110,
B11111,
B00100,
B00100,
B00100,
B00100,
B00100,
}; //Up-Arrow
byte c2[8] = {
B00100,
B00100,
B00100,
B00100,
B00100,
B11111,
B01110,
B00100,
}; //Down-Arrow
// Define the pins used for the push buttons
int buttons[] = { BUTTON_UP, BUTTON_DOWN, BUTTON_LEFT, BUTTON_RIGHT, BUTTON_SELECT };
int buttonStates[sizeof(buttons) / sizeof(buttons[0])];
int button_UP;
int button_DOWN;
int button_LEFT;
int button_RIGHT;
int button_SELECT;
int menuItem = 1;
int screen = 1;
bool dayTime = true;
int humidity;
int tempC;
int minHumidity = 50;
int maxHumidity = 80;
int dayMaxTemp = 26;
int dayMinTemp = 24;
int nightMaxTemp = 22;
int nightMinTemp = 20;
int fanCycles = 4;
int fanCycleDuration = 5;
int dt = 500;
void setup() {
Wire.begin();
Serial.begin(9600);
lcd.createChar(0, c1); //Creating custom characters in CG-RAM
lcd.createChar(1, c2);
pinMode(PHOTOSENSOR, INPUT);
dht.begin();
delay(dt);
lcd.begin(16, 2);
myRTC.begin();
// setTime(20, 1, 0, 25, 7, 2023); // set the system time to 23h31m30s on 13Feb2009
// myRTC.set(now());
// Serial.println("RTC has set the system time");
// Set button pin modes and initial states
for (int i = 0; i < sizeof(buttons) / sizeof(buttons[0]); i++) {
pinMode(buttons[i], INPUT);
buttonStates[i] = 1; // Assuming active LOW buttons
}
}
void loop() {
digitalClockDisplay();
// delay(1000);
// Request data from the slave device
Wire.requestFrom(SLAVE_ADDR, ANSWER_SIZE);
// Wait until all the data is received
while (Wire.available() < ANSWER_SIZE) {
delay(1);
}
// Read the received data from the slave
byte data[16];
for (int i = 0; i < 16; i++) {
data[i] = Wire.read();
}
// Read the received data from the slave
// Convert the received bytes back to float values
float temperatureDS18B20;
float humidityDHT11;
float temperatureDHT11;
int lightIntensity;
byte* tempBytes = (byte*)&temperatureDS18B20;
byte* humBytes = (byte*)&humidityDHT11;
byte* dhtTempBytes = (byte*)&temperatureDHT11;
byte* lightBytes = (byte*)&lightIntensity;
for (int i = 0; i < 4; i++) {
tempBytes[i] = data[i];
humBytes[i] = data[i + 4];
dhtTempBytes[i] = data[i + 8];
lightBytes[i] = data[i + 12];
}
tempC = temperatureDS18B20;
humidity = humidityDHT11;
if (lightIntensity >= 300 & !dayTime | lightIntensity < 300 & dayTime) {
lcd.clear();
dayTime = !dayTime;
}
// Sensor check
// if ((temperatureDS18B20 - temperatureDHT11) * 2 > 5) {
// Serial.println("Check sensor");
// }
// Read button states
for (int i = 0; i < sizeof(buttons) / sizeof(buttons[0]); i++) {
int buttonState = digitalRead(buttons[i]);
// Check if the button state has changed
if (buttonState != buttonStates[i]) {
buttonStates[i] = buttonState;
// Handle button press
if (buttonState == 1) {
handleButtonPress(i);
}
}
}
updateLCD();
}
void digitalClockDisplay() {
// digital clock display of the time
if (screen == SCREEN_MAIN & menuItem == 2) {
lcd.setCursor(0, 1);
lcd.print(hour());
lcd.setCursor(2, 1);
lcd.print(":");
lcd.setCursor(3, 1);
printDigits(minute());
lcd.setCursor(5, 1);
lcd.print(":");
lcd.setCursor(6, 1);
printDigits(second());
}
}
void printDigits(int digits) {
// utility function for digital clock display: prints preceding colon and leading 0
if (digits < 10) {
lcd.print(String(0) + String(digits));
} else {
lcd.print(digits);
}
}
void handleButtonPress(int i) {
switch (i) {
case 0:
switch (screen) {
case SCREEN_MAIN:
if (menuItem != 1) {
menuItem--;
} else {
menuItem = 2;
}
break;
case SCREEN_MENU:
if (menuItem != 1) {
menuItem--;
} else {
menuItem = 5;
}
break;
case SCREEN_TEMP_MENU:
if (menuItem != 1) {
menuItem--;
} else {
menuItem = 3;
}
break;
case SCREEN_DAY_TEMP_MENU:
if (menuItem != 1) {
menuItem--;
} else {
menuItem = 3;
}
break;
case SCREEN_NIGHT_TEMP_MENU:
if (menuItem != 1) {
menuItem--;
} else {
menuItem = 3;
}
break;
case SCREEN_FAN_MENU:
if (menuItem != 1) {
menuItem--;
} else {
menuItem = 3;
}
break;
case SCREEN_HUMIDITY_MENU:
if (menuItem != 1) {
menuItem--;
} else {
menuItem = 3;
}
break;
}
lcd.clear();
break;
case 1:
switch (screen) {
case SCREEN_MAIN:
if (menuItem != 1) {
menuItem = 1;
} else {
menuItem++;
}
break;
case SCREEN_MENU:
if (menuItem != 5) {
menuItem++;
} else {
menuItem = 1;
}
break;
case SCREEN_TEMP_MENU:
if (menuItem != 3) {
menuItem++;
} else {
menuItem = 1;
}
break;
case SCREEN_DAY_TEMP_MENU:
if (menuItem != 3) {
menuItem++;
} else {
menuItem = 1;
}
break;
case SCREEN_NIGHT_TEMP_MENU:
if (menuItem != 3) {
menuItem++;
} else {
menuItem = 1;
}
break;
case SCREEN_FAN_MENU:
if (menuItem != 3) {
menuItem++;
} else {
menuItem = 1;
}
break;
case SCREEN_HUMIDITY_MENU:
if (menuItem != 3) {
menuItem++;
} else {
menuItem = 1;
}
break;
}
lcd.clear();
break;
case 2:
lcd.clear();
if (screen == SCREEN_DAY_TEMP_MENU & menuItem == 1 & dayMaxTemp > dayMinTemp + 2) {
dayMaxTemp--;
} else if (screen == SCREEN_DAY_TEMP_MENU & menuItem == 2 & dayMinTemp > MIN_DAY_TEMP) {
dayMinTemp--;
} else if (screen == SCREEN_NIGHT_TEMP_MENU & menuItem == 1 & nightMaxTemp > nightMinTemp + 2) {
nightMaxTemp--;
} else if (screen == SCREEN_NIGHT_TEMP_MENU & menuItem == 2 & nightMinTemp > MIN_NIGHT_TEMP) {
nightMinTemp--;
} else if (screen == SCREEN_FAN_MENU & menuItem == 1) {
if (fanCycles != 0) {
fanCycles = fanCycles - 2;
} else {
fanCycles = 12;
}
} else if (screen == SCREEN_FAN_MENU & menuItem == 2) {
if (fanCycleDuration != 0) {
fanCycleDuration--;
} else {
fanCycleDuration = 60;
}
} else if (screen == SCREEN_HUMIDITY_MENU & menuItem == 1 & maxHumidity > 1 && maxHumidity > minHumidity + 2) {
maxHumidity--;
} else if (screen == SCREEN_HUMIDITY_MENU & menuItem == 2 & minHumidity > 1) {
minHumidity--;
}
break;
case 3:
lcd.clear();
if (screen == SCREEN_DAY_TEMP_MENU & menuItem == 1 & dayMaxTemp < MAX_DAY_TEMP) {
dayMaxTemp++;
} else if (screen == SCREEN_DAY_TEMP_MENU & menuItem == 2 & dayMinTemp < dayMaxTemp - 2) {
dayMinTemp++;
} else if (screen == SCREEN_NIGHT_TEMP_MENU & menuItem == 1 & nightMaxTemp < MAX_NIGHT_TEMP) {
nightMaxTemp++;
} else if (screen == SCREEN_NIGHT_TEMP_MENU & menuItem == 2 & nightMinTemp < nightMaxTemp - 2) {
nightMinTemp++;
} else if (screen == SCREEN_FAN_MENU & menuItem == 1) {
if (fanCycles != 12) {
fanCycles = fanCycles + 2;
} else {
fanCycles = 0;
}
} else if (screen == SCREEN_FAN_MENU & menuItem == 2 & fanCycleDuration != MAX_FAN_CYCLE_DURATION) {
if (fanCycleDuration != 60) {
fanCycleDuration++;
} else {
fanCycleDuration = 0;
}
} else if (screen == SCREEN_HUMIDITY_MENU & menuItem == 1 & maxHumidity < 100) {
maxHumidity++;
} else if (screen == SCREEN_HUMIDITY_MENU & menuItem == 2 & minHumidity < 100 && minHumidity < maxHumidity - 2) {
minHumidity++;
}
break;
case 4:
lcd.clear();
if (screen == SCREEN_MAIN & menuItem == 2) {
menuItem = 1;
screen++;
} else if (screen == SCREEN_MENU & menuItem == 1) {
menuItem = 1;
screen = 3;
} else if (screen == SCREEN_TEMP_MENU & menuItem == 1) {
menuItem = 1;
screen = 4;
} else if (screen == SCREEN_MENU & menuItem == 5 | screen == SCREEN_TEMP_MENU & menuItem == 3 | screen == SCREEN_DAY_TEMP_MENU & menuItem == 3) {
menuItem = 1;
screen--;
} else if (screen == SCREEN_TEMP_MENU & menuItem == 2) {
menuItem = 1;
screen = 5;
} else if (screen == SCREEN_MENU & menuItem == 3) {
menuItem = 1;
screen = 6;
} else if (screen == SCREEN_NIGHT_TEMP_MENU & menuItem == 3) {
menuItem = 2;
screen = 3;
} else if (screen == SCREEN_FAN_MENU & menuItem == 3) {
menuItem = 3;
screen = 2;
} else if (screen == SCREEN_HUMIDITY_MENU & menuItem == 3) {
menuItem = 2;
screen = 2;
} else if (screen == SCREEN_MENU & menuItem == 4) {
screen = 7;
} else if (screen == SCREEN_MENU & menuItem == 2) {
menuItem = 1;
screen = 8;
} else if (screen == SCREEN_LIGHT_MENU) {
menuItem = 4;
screen = 2;
}
break;
}
}
void updateLCD() {
lcd.setCursor(0, 0);
switch (screen) {
case SCREEN_MAIN:
switch (menuItem) {
case 1:
lcd.print("Temp=");
lcd.print(tempC);
lcd.print((char)223);
lcd.print("C");
lcd.setCursor(15, 0);
lcd.print((char)0);
lcd.setCursor(0, 1);
lcd.print("Humidity=");
lcd.print(humidity);
lcd.print("%");
lcd.setCursor(15, 1);
lcd.print((char)1);
break;
case 2:
lcd.print("Menu");
lcd.setCursor(13, 0);
lcd.print("*");
lcd.setCursor(15, 0);
lcd.print((char)0);
lcd.setCursor(15, 1);
lcd.print((char)1);
break;
}
break;
case SCREEN_MENU:
switch (menuItem) {
case 1:
lcd.print("Temperature");
lcd.setCursor(13, 0);
lcd.print("*");
lcd.setCursor(15, 0);
lcd.print((char)0);
lcd.setCursor(0, 1);
lcd.print("Humidity");
lcd.setCursor(15, 1);
lcd.print((char)1);
break;
case 2:
lcd.print("Temperature");
lcd.setCursor(15, 0);
lcd.print((char)0);
lcd.setCursor(0, 1);
lcd.print("Humidity");
lcd.setCursor(13, 1);
lcd.print("*");
lcd.setCursor(15, 1);
lcd.print((char)1);
break;
case 3:
lcd.print("Fans");
lcd.setCursor(13, 0);
lcd.print("*");
lcd.setCursor(15, 0);
lcd.print((char)0);
lcd.setCursor(0, 1);
lcd.print("Lights");
lcd.setCursor(15, 1);
lcd.print((char)1);
break;
case 4:
lcd.print("Fans");
lcd.setCursor(15, 0);
lcd.print((char)0);
lcd.setCursor(0, 1);
lcd.print("Lights");
lcd.setCursor(13, 1);
lcd.print("*");
lcd.setCursor(15, 1);
lcd.print((char)1);
break;
case 5:
lcd.print("Close");
lcd.setCursor(13, 0);
lcd.print("*");
lcd.setCursor(15, 0);
lcd.print((char)0);
lcd.setCursor(15, 1);
lcd.print((char)1);
break;
}
break;
case SCREEN_TEMP_MENU:
switch (menuItem) {
case 1:
lcd.print("Day");
lcd.setCursor(13, 0);
lcd.print("*");
lcd.setCursor(15, 0);
lcd.print((char)0);
lcd.setCursor(0, 1);
lcd.print("Night");
lcd.setCursor(15, 1);
lcd.print((char)1);
break;
case 2:
lcd.print("Day");
lcd.setCursor(15, 0);
lcd.print((char)0);
lcd.setCursor(0, 1);
lcd.print("Night");
lcd.setCursor(13, 1);
lcd.print("*");
lcd.setCursor(15, 1);
lcd.print((char)1);
break;
case 3:
lcd.print("Close");
lcd.setCursor(13, 0);
lcd.print("*");
lcd.setCursor(15, 0);
lcd.print((char)0);
lcd.setCursor(15, 1);
lcd.print((char)1);
break;
}
break;
case SCREEN_DAY_TEMP_MENU:
switch (menuItem) {
case 1:
lcd.print("MAX");
lcd.setCursor(9, 0);
lcd.print("<");
lcd.print(dayMaxTemp);
lcd.print(">");
lcd.setCursor(13, 0);
lcd.print("*");
lcd.setCursor(15, 0);
lcd.print((char)0);
lcd.setCursor(0, 1);
lcd.print("MIN");
lcd.setCursor(9, 1);
lcd.print("<");
lcd.print(dayMinTemp);
lcd.print(">");
lcd.setCursor(15, 1);
lcd.print((char)1);
break;
case 2:
lcd.print("MAX");
lcd.setCursor(9, 0);
lcd.print("<");
lcd.print(dayMaxTemp);
lcd.print(">");
lcd.setCursor(15, 0);
lcd.print((char)0);
lcd.setCursor(0, 1);
lcd.print("MIN");
lcd.setCursor(9, 1);
lcd.print("<");
lcd.print(dayMinTemp);
lcd.print(">");
lcd.setCursor(13, 1);
lcd.print("*");
lcd.setCursor(15, 1);
lcd.print((char)1);
break;
case 3:
lcd.print("Close");
lcd.setCursor(13, 0);
lcd.print("*");
lcd.setCursor(15, 0);
lcd.print((char)0);
lcd.setCursor(15, 1);
lcd.print((char)1);
break;
}
break;
case SCREEN_NIGHT_TEMP_MENU:
switch (menuItem) {
case 1:
lcd.print("MAX");
lcd.setCursor(9, 0);
lcd.print("<");
lcd.print(nightMaxTemp);
lcd.print(">");
lcd.setCursor(13, 0);
lcd.print("*");
lcd.setCursor(15, 0);
lcd.print((char)0);
lcd.setCursor(0, 1);
lcd.print("MIN");
lcd.setCursor(9, 1);
lcd.print("<");
lcd.print(nightMinTemp);
lcd.print(">");
lcd.setCursor(15, 1);
lcd.print((char)1);
break;
case 2:
lcd.print("MAX");
lcd.setCursor(9, 0);
lcd.print("<");
lcd.print(nightMaxTemp);
lcd.print(">");
lcd.setCursor(15, 0);
lcd.print((char)0);
lcd.setCursor(0, 1);
lcd.print("MIN");
lcd.setCursor(9, 1);
lcd.print("<");
lcd.print(nightMinTemp);
lcd.print(">");
lcd.setCursor(13, 1);
lcd.print("*");
lcd.setCursor(15, 1);
lcd.print((char)1);
break;
case 3:
lcd.print("Close");
lcd.setCursor(13, 0);
lcd.print("*");
lcd.setCursor(15, 0);
lcd.print((char)0);
lcd.setCursor(15, 1);
lcd.print((char)1);
break;
}
break;
case SCREEN_FAN_MENU:
switch (menuItem) {
case 1:
lcd.print("No./day");
lcd.setCursor(9, 0);
lcd.print("<");
lcd.print(fanCycles);
lcd.print(">");
lcd.setCursor(13, 0);
lcd.print("*");
lcd.setCursor(15, 0);
lcd.print((char)0);
lcd.setCursor(0, 1);
lcd.print("Duration");
lcd.setCursor(9, 1);
lcd.print("<");
lcd.print(fanCycleDuration);
lcd.print(">");
lcd.setCursor(15, 1);
lcd.print((char)1);
break;
case 2:
lcd.print("No./day");
lcd.setCursor(9, 0);
lcd.print("<");
lcd.print(fanCycles);
lcd.print(">");
lcd.setCursor(15, 0);
lcd.print((char)0);
lcd.setCursor(0, 1);
lcd.print("Duration");
lcd.setCursor(9, 1);
lcd.print("<");
lcd.print(fanCycleDuration);
lcd.print(">");
lcd.setCursor(13, 1);
lcd.print("*");
lcd.setCursor(15, 1);
lcd.print((char)1);
break;
case 3:
lcd.print("Close");
lcd.setCursor(13, 0);
lcd.print("*");
lcd.setCursor(15, 0);
lcd.print((char)0);
lcd.setCursor(15, 1);
lcd.print((char)1);
break;
}
break;
case SCREEN_LIGHT_MENU:
lcd.print("Lights are ");
if (dayTime) {
lcd.print("ON");
} else {
lcd.print("OFF");
}
lcd.setCursor(0, 1);
lcd.print("Close");
lcd.setCursor(15, 1);
lcd.print("*");
break;
case SCREEN_HUMIDITY_MENU:
switch (menuItem) {
case 1:
lcd.print("MAX");
lcd.setCursor(9, 0);
lcd.print("<");
lcd.print(maxHumidity);
lcd.print(">");
lcd.setCursor(13, 0);
lcd.print("*");
lcd.setCursor(15, 0);
lcd.print((char)0);
lcd.setCursor(0, 1);
lcd.print("MIN");
lcd.setCursor(9, 1);
lcd.print("<");
lcd.print(minHumidity);
lcd.print(">");
lcd.setCursor(15, 1);
lcd.print((char)1);
break;
case 2:
lcd.print("MAX");
lcd.setCursor(9, 0);
lcd.print("<");
lcd.print(maxHumidity);
lcd.print(">");
lcd.setCursor(15, 0);
lcd.print((char)0);
lcd.setCursor(0, 1);
lcd.print("MIN");
lcd.setCursor(9, 1);
lcd.print("<");
lcd.print(minHumidity);
lcd.print(">");
lcd.setCursor(13, 1);
lcd.print("*");
lcd.setCursor(15, 1);
lcd.print((char)1);
break;
case 3:
lcd.print("Close");
lcd.setCursor(13, 0);
lcd.print("*");
lcd.setCursor(15, 0);
lcd.print((char)0);
lcd.setCursor(15, 1);
lcd.print((char)1);
break;
}
break;
default:
Serial.println("ERROR");
break;
}
}