#include #include "RtcDayLapse.h" #include #include "RBDdimmer.h" #include #include #include #include "SWHandler.h" #include uint32_t tickDisplay = 0; byte displayMode = 0; float temperature = 0; float humidity = 0; String ip = "NOT FOUND"; #define DHTPIN 2 // Pin data DHT22 terhubung ke pin D4 pada ESP8266 #define DHTTYPE DHT22 // Tipe sensor DHT const char* ssid1 = "12"; const char* password1 = "rachman12"; const char* ssid2 = "Rachman Tio"; const char* password2 = "tiomaulan99"; const char* ssid3 = "wifi_ps"; const char* password3 = "00000099"; // Parameters DHT dht(DHTPIN, DHTTYPE); RTC_DS3231 rtc; const int zeroCrossPin = 13; const int acdPin = 15; int MIN_POWER = 0; int MAX_POWER = 99; int power = 0; bool globalPowerStatus = true; // Variable to keep track of overall power status bool controlMode = false; // Kelembaban target berdasarkan hari inkubasi const int humidityDay1to18 = 55; const int humidityDay19to21 = 68; // Egg turning const int EGG_TURN_INTERVAL = 4 * 60 * 60 * 1000; // 4 hours in milliseconds const int LOCKDOWN_START_DAY = 18; unsigned long lastEggTurnTime = 0; // Objects dimmerLamp acd(acdPin, zeroCrossPin); ESP8266WebServer server(80); LiquidCrystal_I2C lcd(0x27, 16, 2); // Variables for timing unsigned long lastSetPowerTime = 0; bool setPowerCalled = false; int oldPower = -1; void setup() { Serial.begin(115200); delay(10); RtcDayLapseInit(); dht.begin(); lcd.begin(); lcd.backlight(); // Initialize relays SetupSwitch(); // Initialize dimmer acd.begin(NORMAL_MODE, ON); power = 0; acd.setPower(power); // Connect to Wi-Fi connectToWiFi(); displayIPAddress(WiFi.localIP()); Wire.begin(); Serial.print("Memory flag: "); uint8_t v = RtcGetMemoryFlag(); Serial.println(v); Serial.print("Set new flag to "); v++; Serial.print(v); if (RtcSetMemoryFlag(v)) { Serial.println(" : OK"); } else { Serial.println(" : FAILED"); } server.on("/", HTTP_GET, handleGetTime); server.on("/", HTTP_POST, handlePostTime); server.on("/dht", HTTP_GET, handleDht); server.on("/inkubator", HTTP_POST, handleInkubator); // Updated endpoint for handleInkubator server.begin(); Serial.println("HTTP server started"); } void loop() { server.handleClient(); RtcElapsedRefresh(); unsigned long currentTime = millis(); if (globalPowerStatus) { // Kembali ke logika kontrol suhu setelah 10 detik hanya jika setPowerCalled adalah true if (setPowerCalled && (currentTime - lastSetPowerTime >= 10000)) { setPowerCalled = false; // Reset flag } // Menjalankan kontrol suhu dan kelembaban hanya jika setPowerCalled adalah false if (!setPowerCalled) { handleTemperatureAndHumidityControl(); } // Handle egg turning if before lockdown period if (lapseDay <= LOCKDOWN_START_DAY) { turnEggs(); } } else { power = 0; } Serial.print("Current power: "); Serial.println(power); if (oldPower!=power){ oldPower = power; acd.setPower(power); if (power==0){ acd.setState(OFF); }else{ acd.setState(ON); } } HandleLCD(); delay(100); } void handleGetTime() { RtcElapsedRefresh(); StaticJsonDocument<200> doc; doc["day"] = lapseDay; doc["hours"] = lapseHours; doc["minutes"] = lapseMinutes; doc["seconds"] = lapseSeconds; String response; serializeJson(doc, response); server.send(200, "application/json", response); } void HandleLCD(){ if ((millis()-tickDisplay)>=3000){ tickDisplay = millis(); if (displayMode==0){ lcd.clear(); lcd.setCursor(0, 0); lcd.print("IP Address:"); lcd.setCursor(0, 1); lcd.print(ip); }else if(displayMode==1){ lcd.clear(); lcd.setCursor(0, 0); lcd.print("Hari Ke -"); lcd.print(lapseDay); lcd.print(" "); lcd.setCursor(0, 1); lcd.print(lapseHours); lcd.print(":"); lcd.print(lapseMinutes); lcd.print(":"); lcd.print(lapseSeconds); }else{ lcd.clear(); lcd.setCursor(0, 0); lcd.print("S: "); lcd.print(temperature); lcd.print(" C"); lcd.setCursor(11, 0); lcd.print("P: "); lcd.print(power); lcd.setCursor(0, 1); lcd.print("K: "); lcd.print(humidity); lcd.print(" %"); } displayMode++; if (displayMode>2) displayMode = 0; } } void handlePostTime() { if (server.hasArg("plain") == false) { server.send(400, "text/plain", "Bad Request"); return; } String body = server.arg("plain"); StaticJsonDocument<200> doc; DeserializationError error = deserializeJson(doc, body); if (error) { server.send(400, "text/plain", "Bad Request"); return; } int day = doc["day"]; if (day<0) day = 0; if (day>21) day = 21; RtcElapseSet(day); server.send(200, "text/plain", "Time updated"); } void handleDht() { float humidity = dht.readHumidity(); float temperature = dht.readTemperature(); if (isnan(humidity) || isnan(temperature)) { Serial.println("Failed to read from DHT sensor"); server.send(500, "text/plain", "Failed to read from DHT sensor"); return; } StaticJsonDocument<200> doc; doc["temperature"] = temperature; doc["humidity"] = humidity; String response; serializeJson(doc, response); Serial.print("Response: "); Serial.println(response); server.send(200, "application/json", response); } void handleInkubator() { // Renamed from handlePower to handleInkubator if (server.hasArg("plain") == false) { server.send(400, "text/plain", "Bad Request"); return; } String body = server.arg("plain"); StaticJsonDocument<200> doc; DeserializationError error = deserializeJson(doc, body); if (error) { server.send(400, "text/plain", "Bad Request"); return; } String powerStatus = doc["inkubator"]; if (powerStatus == "on") { globalPowerStatus = true; server.send(200, "text/plain", "All devices are ON"); Serial.println("All devices ON"); } else if (powerStatus == "off") { globalPowerStatus = false; SetSwitchState(SWITCH_TRAY, false); SetSwitchState(SWITCH_MIST, false); SetSwitchState(SWITCH_FAN, false); power = 0; acd.setPower(0); server.send(200, "text/plain", "All devices are OFF"); Serial.println("All devices OFF"); } else { server.send(400, "text/plain", "Invalid power status"); } } void handleTemperatureAndHumidityControl() { temperature = dht.readTemperature(); humidity = dht.readHumidity(); if (isnan(temperature) || isnan(humidity)) { Serial.println("Failed to read from DHT sensor"); return; } bool terlaluPanas = false; //versi feedback float deltaSuhu = 37.5 - temperature; int pw = abs(deltaSuhu); if (deltaSuhu>0.1){ //lebih dingin: //kipas mati if (pw<=0) pw = 1; power+=pw; }else if (deltaSuhu<-0.1){ //lebih panas: //dkipas hidup terlaluPanas = true; if (pw<=0) pw = 1; power-= pw; } if (powerMAX_POWER) power = MAX_POWER; // Kontrol kelembaban bool terlaluLembab = humidity > (getTargetHumidity() + 1); bool mistAktif = false; int targetHumidity = getTargetHumidity(); if (humidity < targetHumidity) { mistAktif = true; SetSwitchState(SWITCH_MIST, true); // Menyalakan mist maker jika kelembaban di bawah target //SetSwitchState(SWITCH_FAN, false); // Mematikan kipas } else { SetSwitchState(SWITCH_MIST, false); // Mematikan mist maker //SetSwitchState(SWITCH_FAN, true); // Menyalakan kipas } //fungsi kipas bool kipasOn = terlaluPanas || terlaluLembab || mistAktif; SetSwitchState(SWITCH_FAN, kipasOn); // Menyalakan kipas } int getTargetHumidity() { if (lapseDay <= LOCKDOWN_START_DAY ) { return humidityDay1to18; } else if (lapseDay <= 21) { return humidityDay19to21; } else { return 0; // Inkubasi selesai, lakukan sesuatu jika perlu } } void displayIPAddress(IPAddress ipAddress) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("IP Address:"); lcd.setCursor(0, 1); ip = ipAddress.toString(); lcd.print(ipAddress); } void clearIPAddress() { lcd.clear(); } void turnEggs() { static bool isTurning = false; // Untuk melacak apakah kita sedang dalam proses turning static unsigned long turnStartTime = 0; // Waktu saat kita mulai turning unsigned long currentTime = millis(); if (!isTurning) { // Memulai turning jika interval telah berlalu if (currentTime - lastEggTurnTime >= EGG_TURN_INTERVAL) { SetSwitchState(SWITCH_TRAY, true); // Mulai turning isTurning = true; // Tandai bahwa kita sedang turning turnStartTime = currentTime; // Simpan waktu saat kita mulai turning } } else { // Mematikan turning setelah 30 detik if (currentTime - turnStartTime >= 14000) { // 30 detik dalam milidetik SetSwitchState(SWITCH_TRAY, false); // Matikan turning isTurning = false; // Tandai bahwa turning telah selesai lastEggTurnTime = currentTime; // Perbarui waktu terakhir kita melakukan turning } } } void connectToWiFi() { WiFi.begin(ssid1, password1); unsigned long startAttemptTime = millis(); // Tunggu koneksi selama 10 detik (10000 milidetik) while (WiFi.status() != WL_CONNECTED && millis() - startAttemptTime < 10000) { delay(500); Serial.print("."); } // Jika percobaan pertama gagal, coba jaringan WiFi kedua if (WiFi.status() != WL_CONNECTED) { Serial.println(); Serial.println("Gagal terhubung ke jaringan pertama."); Serial.print("Menghubungkan ke "); Serial.println(ssid2); WiFi.begin(ssid2, password2); startAttemptTime = millis(); // Tunggu koneksi selama 10 detik lagi while (WiFi.status() != WL_CONNECTED && millis() - startAttemptTime < 10000) { delay(500); Serial.print("."); } } // Jika percobaan kedua gagal, coba jaringan WiFi ketiga if (WiFi.status() != WL_CONNECTED) { Serial.println(); Serial.println("Gagal terhubung ke jaringan kedua."); Serial.print("Menghubungkan ke "); Serial.println(ssid3); WiFi.begin(ssid3, password3); startAttemptTime = millis(); // Tunggu koneksi selama 10 detik lagi while (WiFi.status() != WL_CONNECTED && millis() - startAttemptTime < 10000) { delay(500); Serial.print("."); } } // Periksa status koneksi akhir if (WiFi.status() == WL_CONNECTED) { Serial.println(); Serial.println("WiFi terhubung"); Serial.println("Alamat IP: "); Serial.println(WiFi.localIP()); } else { Serial.println(); Serial.println("Gagal terhubung ke jaringan manapun."); } }