#include #include #include #include // ================= KONFIGURASI WIFI ================= #define WIFI_SSID "Waris" #define WIFI_PASSWORD "bayardulu" // ================= KONFIGURASI FIREBASE ================= #define DATABASE_URL "https://sigesit-48741-default-rtdb.firebaseio.com" #define DATABASE_SECRET "eaUKMEaqkEdhqUfPoMjdkxLkX0ay7R3W7luQIDrQ" // ================= KONFIGURASI PIN ================= const int SENSOR_PIN = 34; const int RELAY_PIN = 25; // ================= KALIBRASI SENSOR ================= const int SOIL_DRY = 3200; const int SOIL_WET = 1200; // ================= FIREBASE OBJECT ================= FirebaseData fbdo; FirebaseAuth auth; FirebaseConfig config; // ================= VARIABEL KONTROL ================= unsigned long prevMillis = 0; const long INTERVAL = 3000; // Update setiap 3 detik bool isManual = false; int pumpStatus = 0; // Untuk mendeteksi perubahan status pompa bool lastPumpState = false; void setup() { Serial.begin(115200); delay(1000); Serial.println("\n--- SISTEM SIGESIT DIMULAI ---"); pinMode(SENSOR_PIN, INPUT); pinMode(RELAY_PIN, OUTPUT); // Relay OFF saat awal digitalWrite(RELAY_PIN, HIGH); // ================= KONEKSI WIFI ================= WiFi.begin(WIFI_SSID, WIFI_PASSWORD); Serial.print("Menghubungkan ke WiFi: "); Serial.println(WIFI_SSID); int timeout = 0; while (WiFi.status() != WL_CONNECTED && timeout < 20) { delay(500); Serial.print("."); timeout++; } if (WiFi.status() == WL_CONNECTED) { Serial.println("\n[OK] WiFi Terhubung!"); Serial.print("IP Address: "); Serial.println(WiFi.localIP()); } else { Serial.println("\n[GAGAL] WiFi tidak terhubung!"); } // ================= FIREBASE ================= config.database_url = DATABASE_URL; config.signer.tokens.legacy_token = DATABASE_SECRET; Firebase.reconnectWiFi(true); Firebase.begin(&config, &auth); configTime(0, 0, "pool.ntp.org"); Serial.println("[OK] Firebase Siap!"); } void loop() { if (Firebase.ready()) { // ================================================= // A. KONTROL RESPONSIVE DARI FIREBASE // ================================================= if (Firebase.RTDB.getBool(&fbdo, "/sensor/is_manual")) { isManual = fbdo.to(); } if (isManual) { if (Firebase.RTDB.getInt(&fbdo, "/sensor/pump_status")) { pumpStatus = fbdo.to(); digitalWrite( RELAY_PIN, (pumpStatus == 1) ? LOW : HIGH ); } } // ================================================= // B. PEMBACAAN SENSOR // ================================================= unsigned long currentMillis = millis(); if (currentMillis - prevMillis >= INTERVAL) { prevMillis = currentMillis; int nilaiADC = analogRead(SENSOR_PIN); int soilPercent = map( nilaiADC, SOIL_DRY, SOIL_WET, 0, 100 ); soilPercent = constrain(soilPercent, 0, 100); // ================================================= // C. MODE OTOMATIS POMPA // ================================================= if (!isManual) { if (soilPercent < 50) { digitalWrite(RELAY_PIN, LOW); pumpStatus = 1; } else if (soilPercent > 56) { digitalWrite(RELAY_PIN, HIGH); pumpStatus = 0; } } // ================================================= // D. SERIAL MONITOR // ================================================= Serial.print("Kelembaban: "); Serial.print(soilPercent); Serial.print("% | "); Serial.print("Pompa: "); Serial.print(pumpStatus == 1 ? "NYALA" : "MATI"); Serial.print(" | Mode: "); Serial.println(isManual ? "MANUAL" : "OTOMATIS"); // ================================================= // E. UPDATE REALTIME KE FIREBASE // ================================================= FirebaseJson json; json.set("soil_percent", soilPercent); json.set("pump_status", pumpStatus); json.set("is_manual", isManual); if (!Firebase.RTDB.updateNode(&fbdo, "/sensor", &json)) { Serial.print("Gagal Update Firebase: "); Serial.println(fbdo.errorReason()); } // ================================================= // F. RIWAYAT PENYIRAMAN // ================================================= // ================= POMPA MENYALA ================= if (pumpStatus == 1 && !lastPumpState) { FirebaseJson history; history.set("timestamp/.sv", "timestamp"); history.set("value", soilPercent); history.set("pump", "Penyiraman Aktif"); if (Firebase.RTDB.pushJSON(&fbdo, "/history", &history)) { Serial.println(">>> Penyiraman Aktif"); } else { Serial.print("Gagal Simpan Riwayat: "); Serial.println(fbdo.errorReason()); } } // ================= POMPA MATI ================= if (pumpStatus == 0 && lastPumpState) { FirebaseJson history; history.set("timestamp/.sv", "timestamp"); history.set("value", soilPercent); history.set("pump", "Penyiraman Selesai"); if (Firebase.RTDB.pushJSON(&fbdo, "/history", &history)) { Serial.println(">>> Penyiraman Selesai"); } else { Serial.print("Gagal Simpan Riwayat: "); Serial.println(fbdo.errorReason()); } } // Simpan status pompa sebelumnya lastPumpState = (pumpStatus == 1); } } else { static unsigned long lastError = 0; if (millis() - lastError > 5000) { lastError = millis(); Serial.println("Menunggu Firebase Ready..."); } } // ================================================= // AUTO RECONNECT WIFI // ================================================= if (WiFi.status() != WL_CONNECTED) { WiFi.begin(WIFI_SSID, WIFI_PASSWORD); } }