#include #include #include #include "DHT.h" // ===== FIREBASE ===== #define API_KEY "AIzaSyCiOW-xdrQRerccECUA3R8Ynwgp4POPoNg" #define DATABASE_URL "https://smartgh-2cc3c-default-rtdb.firebaseio.com/" #define USER_EMAIL "test@gmail.com" #define USER_PASSWORD "123456" FirebaseData fbdo; FirebaseAuth auth; FirebaseConfig config; // ===== RELAY PIN ===== int RELAY_WATER = 19; int RELAY_FERTILIZER = 18; int RELAY_COOLER = 25; // ===== SENSOR PIN ===== #define DHTPIN 5 #define DHTTYPE DHT22 #define SOIL_PIN 34 DHT dht(DHTPIN, DHTTYPE); // ===== TIMER SENSOR ===== unsigned long lastSensorTime = 0; const unsigned long sensorInterval = 5000; // 5 detik // Min-Max scaling limits const int soilMinRaw = 876; // Minimum raw sensor value (wet soil) const int soilMaxRaw = 2554; // Maximum raw sensor value (dry soil) const float soilMinScaled = 0.0; // Minimum scaled value const float soilMaxScaled = 100.0; // Maximum scaled value void setup() { Serial.begin(115200); pinMode(RELAY_WATER, OUTPUT); pinMode(RELAY_FERTILIZER, OUTPUT); pinMode(RELAY_COOLER, OUTPUT); pinMode(SOIL_PIN, INPUT); digitalWrite(RELAY_WATER, HIGH); digitalWrite(RELAY_FERTILIZER, HIGH); digitalWrite(RELAY_COOLER, LOW); dht.begin(); // WiFi Manager WiFiManager wm; if (!wm.autoConnect("SmartGH-Setup")) { Serial.println("Gagal connect, restart..."); delay(3000); ESP.restart(); } Serial.println("WiFi Connected."); // Firebase config.api_key = API_KEY; config.database_url = DATABASE_URL; auth.user.email = USER_EMAIL; auth.user.password = USER_PASSWORD; Firebase.begin(&config, &auth); Firebase.reconnectWiFi(true); } void loop() { if (Firebase.ready()) { // === Manual Control === if (Firebase.RTDB.getBool(&fbdo, "/status/devices/water")) { digitalWrite(RELAY_WATER, fbdo.boolData() ? LOW : HIGH); } if (Firebase.RTDB.getBool(&fbdo, "/status/devices/fertilizer")) { digitalWrite(RELAY_FERTILIZER, fbdo.boolData() ? LOW : HIGH); } // === Sensor Update === if (millis() - lastSensorTime > sensorInterval) { lastSensorTime = millis(); float temp = dht.readTemperature(); float hum = dht.readHumidity(); int soilRaw = analogRead(SOIL_PIN); // Min-Max Scaling untuk Kelembapan Tanah float soilPercent = (float)(soilMaxRaw - soilRaw) / (soilMaxRaw - soilMinRaw) * (soilMaxScaled - soilMinScaled) + soilMinScaled; soilPercent = constrain(soilPercent, 0, 100); // Membatasi agar nilai tidak melebihi 100% Serial.println("----- SENSOR -----"); Serial.printf("Temp: %.1f °C\n", temp); Serial.printf("Hum: %.1f %%\n", hum); Serial.printf("Soil Raw: %d → Soil Moisture: %.1f %%\n", soilRaw, soilPercent); // Simpan ke Firebase Firebase.RTDB.setFloat(&fbdo, "/sensor/data/temperature", temp); Firebase.RTDB.setFloat(&fbdo, "/sensor/data/humidity", hum); Firebase.RTDB.setFloat(&fbdo, "/sensor/data/soilMoisture", soilPercent); // === Pendingin Otomatis / Manual === bool manualMode = true; if (Firebase.RTDB.getBool(&fbdo, "/status/mode_manual/cooler")) { manualMode = fbdo.boolData(); } if (manualMode) { if (Firebase.RTDB.getBool(&fbdo, "/status/devices/cooler")) { digitalWrite(RELAY_COOLER, fbdo.boolData() ? HIGH : LOW); } Serial.println("Cooler mode: MANUAL"); } else { if (temp > 34.0) { digitalWrite(RELAY_COOLER, HIGH); Firebase.RTDB.setBool(&fbdo, "/status/devices/cooler", true); Serial.println("Cooler AUTO ON (Temp > 34)"); } else { digitalWrite(RELAY_COOLER, LOW); Firebase.RTDB.setBool(&fbdo, "/status/devices/cooler", false); Serial.println("Cooler AUTO OFF (Temp normal)"); } Serial.println("Cooler mode: AUTO"); } Serial.println("--------------------\n"); } } delay(500); }