commit 7c953da861e659c9461706c960f0eca19dc2522b Author: FachriMaulana070904 Date: Thu Jul 30 12:23:21 2026 +0700 Upload files to "/" diff --git a/KODE_TA.ino b/KODE_TA.ino new file mode 100644 index 0000000..a513f0f --- /dev/null +++ b/KODE_TA.ino @@ -0,0 +1,687 @@ +#include +#include +#include +#include +#include "RTClib.h" +#include "time.h" +#include + +// ===================================== +// OBJECT +// ===================================== +Preferences prefs; +RTC_DS3231 rtc; +WiFiClientSecure client; + +// ===================================== +// WIFI +// ===================================== +const char* ssid = "Galaxy A16 2CF8"; +const char* password = "bismillah"; + +// ===================================== +// FIREBASE +// ===================================== +String baseURL = +"https://smartcabai-default-rtdb.firebaseio.com/"; + +// ===================================== +// PIN +// ===================================== +#define SENSOR_PIN 34 +#define RELAY_AIR 26 +#define RELAY_PESTISIDA 27 + +// ===================================== +// KALIBRASI SENSOR +// ===================================== +int nilaiKering = 3000; +int nilaiBasah = 2200; + +int batasKering = 60; + +// ===================================== +// VARIABEL SISTEM +// ===================================== +String mode = "AUTO"; + +String airStatus = "OFF"; +String pestStatus = "OFF"; + +bool pestisidaNyala = false; + +unsigned long waktuMulaiPestisida = 0; +unsigned long lastSemprotUnix = 0; + +unsigned long lastFirebase = 0; +unsigned long lastGetMode = 0; +unsigned long lastManualGet = 0; + +unsigned long firebaseCooldown = 0; + +bool firebaseError = false; + +// ===================================== +// CONNECT WIFI +// ===================================== +void connectWiFi() { + + WiFi.mode(WIFI_STA); + + WiFi.setSleep(false); + + WiFi.setAutoReconnect(true); + + WiFi.persistent(true); + + WiFi.config( + INADDR_NONE, + INADDR_NONE, + INADDR_NONE, + IPAddress(8,8,8,8), + IPAddress(8,8,4,4) + ); + + WiFi.begin(ssid, password); + + Serial.print("Connecting WiFi"); + + int timeout = 0; + + while (WiFi.status() != WL_CONNECTED && + timeout < 20) { + + delay(500); + + Serial.print("."); + + timeout++; + } + + if (WiFi.status() == WL_CONNECTED) { + + Serial.println("\nWiFi Connected"); + + Serial.print("IP : "); + + Serial.println(WiFi.localIP()); + + } else { + + Serial.println("\nOFFLINE MODE"); + } +} + +// ===================================== +// FIREBASE GET +// ===================================== +String getFirebase(String path) { + + if (WiFi.status() != WL_CONNECTED) { + return ""; + } + + HTTPClient http; + + String url = baseURL + path + ".json"; + + http.begin(client, url); + + http.setTimeout(10000); + + int httpCode = http.GET(); + + String hasil = ""; + + if (httpCode > 0) { + + hasil = http.getString(); + + hasil.replace("\"", ""); + + hasil.trim(); + + } else { + + firebaseError = true; + + firebaseCooldown = millis(); + } + + http.end(); + + delay(100); + + return hasil; +} + +// ===================================== +// FIREBASE PUT +// ===================================== +// ===================================== +// FIREBASE PUT +// ===================================== +void putFirebase(String path, + String value, + bool isString = false) { + + if (WiFi.status() != WL_CONNECTED) { + return; + } + + HTTPClient http; + + String url = baseURL + path + ".json"; + + http.begin(client, url); + + http.setTimeout(5000); + + http.addHeader( + "Content-Type", + "application/json" + ); + + String payload; + + if (isString) { + + payload = "\"" + value + "\""; + + } else { + + payload = value; + } + + int httpCode = + http.PUT(payload); + + if (httpCode <= 0) { + + firebaseError = true; + + firebaseCooldown = millis(); + } + + http.end(); +} +// ===================================== +// GET UNIX RTC +// ===================================== +unsigned long getUnixTimeRTC() { + + DateTime now = rtc.now(); + + Serial.print("Tanggal RTC : "); +Serial.print(now.day()); +Serial.print("/"); +Serial.print(now.month()); +Serial.print("/"); +Serial.print(now.year()); + +Serial.print(" "); + +Serial.print(now.hour()); +Serial.print(":"); +Serial.print(now.minute()); +Serial.print(":"); +Serial.println(now.second()); + +Serial.print("NOW UNIX : "); +Serial.println(now.unixtime()); + +Serial.print("LAST UNIX : "); +Serial.println(lastSemprotUnix); + + return now.unixtime(); +} + +// ===================================== +// SETUP +// ===================================== +void setup() { + + Serial.begin(115200); + + prefs.begin("spray", false); + + client.setInsecure(); + + // ================================= + // RELAY + // ================================= + pinMode(RELAY_AIR, OUTPUT); + + pinMode(RELAY_PESTISIDA, OUTPUT); + + digitalWrite(RELAY_AIR, HIGH); + + digitalWrite(RELAY_PESTISIDA, HIGH); + + // ================================= + // RTC + // ================================= + Wire.begin(21, 22); + + if (!rtc.begin()) { + + Serial.println("RTC ERROR"); + + while (1); + } + + // ================================= + // WIFI + // ================================= + connectWiFi(); + + // ================================= + // SYNC RTC DARI INTERNET + // ================================= + configTime(7 * 3600, + 0, + "pool.ntp.org"); + if (rtc.lostPower()) { + + struct tm timeinfo; + + if (getLocalTime(&timeinfo)) { + + rtc.adjust(DateTime( + timeinfo.tm_year + 1900, + timeinfo.tm_mon + 1, + timeinfo.tm_mday, + timeinfo.tm_hour, + timeinfo.tm_min, + timeinfo.tm_sec + )); + + Serial.println("RTC SYNC BERHASIL"); + + } else { + + Serial.println("GAGAL SYNC RTC"); + } + } + + // ================================= + // AMBIL DATA LAST SEMPROT + // ================================= + String lastData = + getFirebase("last_semprot"); + + if (lastData != "" && + lastData != "null" && + lastData != "0") { + + // dari firebase + unsigned long temp = strtoul( + lastData.c_str(), + NULL, + 10 + ); + + if(temp > 0) { + lastSemprotUnix = temp; + } + + // simpan lokal + prefs.putULong( + "lastUnix", + lastSemprotUnix + ); + + Serial.println( + "DATA DARI FIREBASE" + ); + + } else { + + // dari memori lokal + lastSemprotUnix = + prefs.getULong( + "lastUnix", + 0 + ); + + Serial.println( + "DATA DARI MEMORI LOKAL" + ); + + // jika belum ada data + if (lastSemprotUnix == 0) { + + lastSemprotUnix = + rtc.now().unixtime(); + + Serial.print("LAST SEMPROT BARU: "); + Serial.println(lastSemprotUnix); + + prefs.putULong( + "lastUnix", + lastSemprotUnix + ); + + Serial.println( + "DATA BARU DIBUAT" + ); + } + } + + Serial.println("SYSTEM READY"); +} + +// ===================================== +// LOOP +// ===================================== +void loop() { + + if(WiFi.status()!=WL_CONNECTED) { + WiFi.reconnect(); + } + + // ================================= + // FIREBASE COOLDOWN + // ================================= + if (firebaseError && + millis() - firebaseCooldown < 10000) { + + delay(1000); + + return; + } + + firebaseError = false; + + // ================================= + // STATUS WIFI + // ================================= + bool wifiConnected = + (WiFi.status() == WL_CONNECTED); + + if (!wifiConnected) { + + mode = "AUTO"; + } + + // ================================= + // AMBIL MODE DARI FIREBASE + // ================================= + if (wifiConnected && + millis() - lastGetMode >= 10000) { + + String firebaseMode = + getFirebase("mode"); + + if (firebaseMode != "") { + + mode = firebaseMode; + + mode.trim(); + } + + lastGetMode = millis(); + } + + // ================================= + // BACA SENSOR + // ================================= + int adc = analogRead(SENSOR_PIN); + + float kelembapan = + ((float)(nilaiKering - adc) / + (nilaiKering - nilaiBasah)) + * 100; + + kelembapan = + constrain( + kelembapan, + 0, + 100 + ); + + // ================================= + // RTC + // ================================= + DateTime now = rtc.now(); + + + int jam = now.hour(); + + int menit = now.minute(); + + // ================================= + // HITUNG COUNTDOWN + // ================================= + unsigned long nowUnix = + now.unixtime(); + + unsigned long intervalDetik = + 120UL * 3600UL; + + unsigned long elapsedDetik = + nowUnix - lastSemprotUnix; + + long sisaDetik; + + if (elapsedDetik >= intervalDetik) { + sisaDetik = 0; + } else { + sisaDetik = intervalDetik - elapsedDetik; + } + + // ================================= + // FORMAT COUNTDOWN + // ================================= + int hariSisa = sisaDetik / 86400; + int jamSisa = (sisaDetik % 86400) / 3600; + int menitSisa = (sisaDetik % 3600) / 60; + int detikSisa = sisaDetik % 60; + + String countdown; + + if (sisaDetik > 0) { + countdown = + String(hariSisa) + " Hari " + + String(jamSisa) + " Jam " + + String(menitSisa) + " Menit " + + String(detikSisa) + " Detik"; + } else { + countdown = "Siap Semprot"; + } + + // ================================= + // KIRIM FIREBASE + // ================================= + if (wifiConnected && + millis() - lastFirebase >= 1000) { + + putFirebase( + "kelembapan", + String(kelembapan, 1) + ); + + putFirebase( + "jeda_penyemprotan", + countdown, + true + ); + + lastFirebase = millis(); + } + + // ================================= + // SERIAL MONITOR + // ================================= + Serial.print("Mode : "); + + Serial.print(mode); + + Serial.print(" ADC: "); + + Serial.print(adc); + + Serial.print( + " || Kelembapan : " + ); + + Serial.print( + kelembapan, + 1 + ); + + Serial.print("%"); + + Serial.print( + " ||Jeda Penyemprotan : " + ); + + Serial.print(countdown); + Serial.print(" || "); + + if (wifiConnected) { + + Serial.println("ONLINE"); + + } else { + + Serial.println("OFFLINE"); + } + + // ================================= + // MODE AUTO + // ================================= + if (mode == "AUTO") { + + // ============================= + // POMPA AIR + // ============================= + if (kelembapan < + batasKering) { + + digitalWrite( + RELAY_AIR, + LOW + ); + + } else { + + digitalWrite( + RELAY_AIR, + HIGH + ); + } + + // ============================= + // PESTISIDA OTOMATIS + // ============================= + if (sisaDetik <= 0 && + !pestisidaNyala && + WiFi.status()==WL_CONNECTED) { + + Serial.println("PESTISIDA MULAI"); + + digitalWrite( + RELAY_PESTISIDA, + LOW + ); + + pestisidaNyala = true; + + waktuMulaiPestisida = + millis(); + } + + // ============================= + // MATIKAN PESTISIDA + // ============================= + if (pestisidaNyala && + millis() - + waktuMulaiPestisida + >= 7000) { + + Serial.println("PESTISIDA SELESAI"); + + digitalWrite( + RELAY_PESTISIDA, + HIGH + ); + + pestisidaNyala = false; + + lastSemprotUnix = + rtc.now().unixtime(); + + // simpan firebase + + putFirebase( + "last_semprot", + String(lastSemprotUnix) + ); + + // simpan lokal + prefs.putULong( + "lastUnix", + lastSemprotUnix + ); + } + } + + // ================================= + // MODE MANUAL + // ================================= + else if (mode == "MANUAL" && + wifiConnected) { + + // ============================= + // AMBIL STATUS MANUAL + // ============================= + if (millis() - + lastManualGet >= 5000) { + + airStatus = + getFirebase("pompa_air"); + + pestStatus = + getFirebase( + "pompa_pestisida" + ); + + lastManualGet = + millis(); + } + + // ============================= + // POMPA AIR + // ============================= + if (airStatus == "ON") { + + digitalWrite( + RELAY_AIR, + LOW + ); + + } else { + + digitalWrite( + RELAY_AIR, + HIGH + ); + } + // ============================= + // POMPA PESTISIDA + // ============================= + if (pestStatus == "ON") { + digitalWrite( + RELAY_PESTISIDA, + LOW + ); + } else { + digitalWrite( + RELAY_PESTISIDA, + HIGH + ); + } + } + delay(3000); +} \ No newline at end of file