#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
#include <RTClib.h>
// ================== LCD ==================
LiquidCrystal_I2C lcd(0x27, 20, 4);
// ================== DHT ==================
#define DHTPIN 4
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
// ================== RTC ==================
RTC_DS3231 rtc;
// ================== Buttons ==================
#define BTN_UP 12
#define BTN_DOWN 13
#define BTN_SELECT 14
#define BTN_BACK 27
// ================== Control Pins ==================
#define HEATER_PIN 25
#define HUMID_PIN 26
#define FAN_PIN 33
#define COOLER_PIN 32
#define TURN_PIN 15
// ================== Variables ==================
float setTemp = 37.5, setHum = 55;
float currentTemp = 0, currentHum = 0;
float tempHigh = 38.5, tempLow = 36.5;
float humHigh = 65, humLow = 40;
bool inMenu = false, editing = false;
int menuIndex = 0, lastMenuIndex = -1;
unsigned long lastUpdate = 0;
// ================== Menu Items ==================
String menuItems[] = {
"Set Temp", "Set Hum",
"Temp High", "Temp Low",
"Hum High", "Hum Low",
"Ventilation", "Cooling",
"Turning Ctrl"
};
int menuLength = sizeof(menuItems) / sizeof(menuItems[0]);
// ================== Button Function ==================
bool readButton(int pin) {
static unsigned long lastPress[40];
int index = pin;
if (digitalRead(pin) == LOW) {
if (millis() - lastPress[index] > 150) {
lastPress[index] = millis();
return true;
}
}
return false;
}
// ================== Show Main Screen ==================
void showMainScreen() {
float t = dht.readTemperature();
float h = dht.readHumidity();
if (!isnan(t)) currentTemp = t;
if (!isnan(h)) currentHum = h;
DateTime now = rtc.now();
lcd.setCursor(0,0);
lcd.print("T:"); lcd.print(currentTemp,1); lcd.print((char)223);
lcd.print(" H:"); lcd.print(currentHum,0); lcd.print("% ");
lcd.setCursor(0,1);
lcd.print("SetT:"); lcd.print(setTemp,1);
lcd.print(" SetH:"); lcd.print(setHum,0); lcd.print(" ");
lcd.setCursor(0,2);
lcd.print("Time:");
if (now.hour()<10) lcd.print("0");
lcd.print(now.hour()); lcd.print(":");
if (now.minute()<10) lcd.print("0");
lcd.print(now.minute()); lcd.print(" ");
lcd.setCursor(0,3);
lcd.print("Day:"); lcd.print(now.day()); lcd.print("/");
lcd.print(now.month()); lcd.print(" ");
}
// ================== Menu System ==================
void showMenu() {
if (!editing) {
if (menuIndex != lastMenuIndex) {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Settings");
for (int i=0; i<3 && i<menuLength; i++) {
int item = (menuIndex + i) % menuLength;
lcd.setCursor(0,i+1);
if (i==0) lcd.print(">"); else lcd.print(" ");
lcd.print(menuItems[item]);
}
lastMenuIndex = menuIndex;
}
if (readButton(BTN_UP)) { menuIndex = (menuIndex - 1 + menuLength) % menuLength; lastMenuIndex=-1; }
if (readButton(BTN_DOWN)) { menuIndex = (menuIndex + 1) % menuLength; lastMenuIndex=-1; }
if (readButton(BTN_SELECT)) { editing = true; lcd.clear(); }
if (readButton(BTN_BACK)) { inMenu = false; lcd.clear(); }
} else {
// Placeholder: Edit values
lcd.setCursor(0,0);
lcd.print("Edit: "); lcd.print(menuItems[menuIndex]);
if (readButton(BTN_UP)) setTemp += 0.1;
if (readButton(BTN_DOWN)) setTemp -= 0.1;
if (readButton(BTN_BACK)) editing=false;
}
}
// ================== Control Logic ==================
void controlSystem() {
// Heater
if (currentTemp < tempLow) digitalWrite(HEATER_PIN, HIGH);
else if (currentTemp > tempHigh) digitalWrite(HEATER_PIN, LOW);
// Humidity
if (currentHum < humLow) digitalWrite(HUMID_PIN, HIGH);
else if (currentHum > humHigh) digitalWrite(HUMID_PIN, LOW);
// Cooling / Ventilation (كمثال بسيط)
if (currentTemp > tempHigh+0.5) digitalWrite(COOLER_PIN, HIGH);
else digitalWrite(COOLER_PIN, LOW);
if (currentTemp > setTemp) digitalWrite(FAN_PIN, HIGH);
else digitalWrite(FAN_PIN, LOW);
// Turning (ممكن نضيف تايمر للتقليب كل X ساعات)
}
// ================== Setup ==================
void setup() {
lcd.init();
lcd.backlight();
dht.begin();
rtc.begin();
pinMode(BTN_UP, INPUT_PULLUP);
pinMode(BTN_DOWN, INPUT_PULLUP);
pinMode(BTN_SELECT, INPUT_PULLUP);
pinMode(BTN_BACK, INPUT_PULLUP);
pinMode(HEATER_PIN, OUTPUT);
pinMode(HUMID_PIN, OUTPUT);
pinMode(FAN_PIN, OUTPUT);
pinMode(COOLER_PIN, OUTPUT);
pinMode(TURN_PIN, OUTPUT);
lcd.setCursor(0,0);
lcd.print("Incubator Ctrl");
delay(1500);
lcd.clear();
}
// ================== Loop ==================
void loop() {
if (!inMenu) {
if (millis() - lastUpdate > 1000) {
showMainScreen();
lastUpdate = millis();
}
if (readButton(BTN_SELECT)) { inMenu = true; lcd.clear(); }
} else {
showMenu();
}
controlSystem();
}