From 07f12ca050bad6f64f48d44de7e00064ccb1ab6b Mon Sep 17 00:00:00 2001 From: SETYANINGSIH Date: Thu, 23 Jul 2026 11:27:28 +0700 Subject: [PATCH] KODE ESP --- sketch_apr14a_copy_20260414222139.ino | 589 ++++++++++++++++++++++++++ 1 file changed, 589 insertions(+) create mode 100644 sketch_apr14a_copy_20260414222139.ino diff --git a/sketch_apr14a_copy_20260414222139.ino b/sketch_apr14a_copy_20260414222139.ino new file mode 100644 index 0000000..dd4da7c --- /dev/null +++ b/sketch_apr14a_copy_20260414222139.ino @@ -0,0 +1,589 @@ +#include +#include +#include +#include +#include +#include + +#include "soc/soc.h" +#include "soc/rtc_cntl_reg.h" + + +// ================= FIREBASE ================= +#define API_KEY "AIzaSyDOt0tippHwz6JaPG9Zo147ATJ9USV5bKs" +#define DATABASE_URL "https://tabungankuy-30a9d-default-rtdb.firebaseio.com/" +#define LEGACY_TOKEN "FTqzKI4HW32paLnR9pQXB72YoUHN1NXEjZMfjO4f" + +// ================= TCS3200 ================= +#define S0 14 +#define S1 27 +#define S2 26 +#define S3 25 +#define SENSOR_OUT 33 + +// ================= HARDWARE ================= +#define SERVO_MASUK_PIN 4 +#define SERVO_TURUN_PIN 5 +#define SERVO_BUKA_PIN 15 + +// ================= OBJECT ================= +LiquidCrystal_I2C lcd(0x27, 16, 2); + +FirebaseData fbdo; +FirebaseAuth auth; +FirebaseConfig config; + +Servo servoMasuk; +Servo servoTurun; +Servo servoBuka; + +// ================= STATE ================= +int lastDetectedVal = 0; + +bool lastKonfirmasi = false; +bool lastBukaTabungan = false; +bool lastServoMasuk = false; + +bool servoAttached = false; + +// ===================================================== +// LCD +// ===================================================== + +void lcdDefault() { + + lcd.clear(); + + lcd.setCursor(0, 0); + lcd.print(" TABUNGANKU "); + + lcd.setCursor(0, 1); + lcd.print(" SIAP DIGUNAKAN "); +} + +void lcdUangTerdeteksi(int nilai) { + + lcd.clear(); + + lcd.setCursor(0, 0); + lcd.print("UANG TERDETEKSI"); + + lcd.setCursor(0, 1); + + String text = "Rp " + String(nilai); + + while (text.length() < 16) + text += " "; + + lcd.print(text); +} + +void lcdUangMasuk(int nilai) { + + lcd.clear(); + + lcd.setCursor(0, 0); + lcd.print(" UANG MASUK "); + + lcd.setCursor(0, 1); + + String text = "Rp " + String(nilai); + + while (text.length() < 16) + text += " "; + + lcd.print(text); +} + +void lcdTabunganTerbuka() { + + lcd.clear(); + + lcd.setCursor(0, 0); + lcd.print(" TABUNGAN "); + + lcd.setCursor(0, 1); + lcd.print(" TERBUKA "); +} + +void updateLCD() { + + if (lastBukaTabungan) { + + lcdTabunganTerbuka(); + + } else if (lastKonfirmasi && lastDetectedVal > 0) { + + lcdUangMasuk(lastDetectedVal); + + } else if (lastDetectedVal > 0) { + + lcdUangTerdeteksi(lastDetectedVal); + + } else { + + lcdDefault(); + } +} + +// ===================================================== +// WIFI +// ===================================================== + +void connectWiFi() { + + WiFi.mode(WIFI_STA); + WiFi.setSleep(false); + + WiFiManager wm; + + wm.setTimeout(180); // 3 menit untuk setup WiFi + + bool res = wm.autoConnect("TABUNGANKU_SETUP"); + + if (!res) { + Serial.println("Gagal konek WiFi"); + ESP.restart(); + } + + Serial.println("WiFi Connected!"); + Serial.print("IP : "); + Serial.println(WiFi.localIP()); +} + +// ===================================================== +// FIREBASE +// ===================================================== + +void setupFirebase() { + + config.api_key = API_KEY; + config.database_url = DATABASE_URL; + + config.signer.tokens.legacy_token = LEGACY_TOKEN; + + Firebase.begin(&config, &auth); + + Firebase.reconnectWiFi(true); + + Serial.println("Firebase Connected"); +} + +// ===================================================== +// TCS3200 +// ===================================================== + +void setupTCS3200() { + + pinMode(S0, OUTPUT); + pinMode(S1, OUTPUT); + + pinMode(S2, OUTPUT); + pinMode(S3, OUTPUT); + + pinMode(SENSOR_OUT, INPUT); + + digitalWrite(S0, HIGH); + digitalWrite(S1, LOW); + + Serial.println("Sensor TCS3200 Ready"); +} + +int avgFreq(int s2Val, int s3Val) { + + long total = 0; + + for (int i = 0; i < 3; i++) { + + digitalWrite(S2, s2Val); + digitalWrite(S3, s3Val); + + delayMicroseconds(300); + + total += pulseIn(SENSOR_OUT, LOW); + } + + return total / 3; +} + +// ===================================================== +// DETEKSI UANG +// ===================================================== + +void cekUangKertas() { + + static unsigned long lastCheck = 0; + static unsigned long lastDetectedTime = 0; + + static int lastDetectedValue = 0; + + if (millis() - lastCheck < 300) + return; + + lastCheck = millis(); + + if (lastKonfirmasi) + return; + + int r = avgFreq(LOW, LOW); + int g = avgFreq(HIGH, HIGH); + int b = avgFreq(LOW, HIGH); + + Serial.print("R: "); + Serial.print(r); + + Serial.print(" | G: "); + Serial.print(g); + + Serial.print(" | B: "); + Serial.println(b); + + int val = 0; + + if (r>=110&&r<=120 && g>=140&&g<=150 && b>=124&&b<=134) val = 100000; + else if (r>=175&&r<=185 && g>=160&&g<=170 && b>=150&&b<=160) val = 50000; + else if (r>=138&&r<=148 && g>=125&&g<=135 && b>=105&&b<=115) val = 20000; + else if (r>=145&&r<=155 && g>=180&&g<=190 && b>=150&&b<=160) val = 10000; + else if (r>=115&&r<=125 && g>=169&&g<=179 && b>=140&&b<=150) val = 5000; + else if (r>=145&&r<=155 && g>=145&&g<=155 && b>=120&&b<=130) val = 2000; + else if (r>=129&&r<=139 && g>=125&&g<=135 && b>=120&&b<=130) val = 1000; + + if (val > 0 && + (millis() - lastDetectedTime > 1500 || + val != lastDetectedValue)) { + + Serial.println("===================="); + Serial.print("Uang : Rp "); + Serial.println(val); + Serial.println("===================="); + + Firebase.RTDB.setInt( + &fbdo, + "/tabungan/detected_value", + val + ); + + lastDetectedTime = millis(); + lastDetectedValue = val; + + lastDetectedVal = val; + + updateLCD(); + } +} + +// ===================================================== +// SERVO HELPER +// ===================================================== + +void attachServo() { + + if (!servoAttached) { + + servoMasuk.attach(SERVO_MASUK_PIN); + servoTurun.attach(SERVO_TURUN_PIN); + servoBuka.attach(SERVO_BUKA_PIN); + + + servoAttached = true; + + delay(300); + + servoMasuk.write(0); + servoTurun.write(0); + servoBuka.write(0); + } +} + +// ===================================================== +// FIREBASE LISTENER +// ===================================================== + +void cekKonfirmasiFlutter() { + + if (!Firebase.RTDB.getBool( + &fbdo, + "/tabungan/konfirmasi_masuk")) + return; + + bool konfirmasi = fbdo.boolData(); + + if (konfirmasi == lastKonfirmasi) + return; + + lastKonfirmasi = konfirmasi; + + Serial.print("Konfirmasi: "); + Serial.println(konfirmasi); + + attachServo(); + + if (konfirmasi) { + + servoTurun.write(90); + + Serial.println("Servo Turun Aktif"); + + } else { + + servoTurun.write(0); + + Serial.println("Servo Turun Mati"); + + // reset nominal ketika tombol batalkan ditekan + lastDetectedVal = 0; + + Firebase.RTDB.setInt( + &fbdo, + "/tabungan/detected_value", + 0 + ); + + Serial.println("Detected Reset"); + + // kembali ke tampilan awal + lcdDefault(); + + return; + } + + updateLCD(); +} + +void cekServoMasuk() { + + if (!Firebase.RTDB.getBool( + &fbdo, + "/tabungan/masukkan_uang")) + return; + + bool buka = fbdo.boolData(); + + if (buka == lastServoMasuk) + return; + + lastServoMasuk = buka; + + attachServo(); + + servoMasuk.write(buka ? 150 : 0); + + Serial.print("Servo Masuk: "); + + Serial.println( + buka ? "BUKA" : "TUTUP" + ); +} + +void cekServoBukaTabungan() { + + static bool sedangBuka = false; + static unsigned long waktuBuka = 0; + static int lastSisa = -1; + + if (!Firebase.RTDB.getBool( + &fbdo, + "/tabungan/buka_tabungan")) + return; + + bool buka = fbdo.boolData(); + + // buka servo sekali saat menerima TRUE + if (buka && !sedangBuka) { + + attachServo(); + + servoBuka.write(150); + + waktuBuka = millis(); + sedangBuka = true; + + lastBukaTabungan = true; + + Serial.println("Servo Tabungan: TERBUKA"); + } + + // countdown 25 detik + if (sedangBuka) { + + int sisa = 25 - ((millis() - waktuBuka) / 1000); + + if (sisa < 0) sisa = 0; + + if (sisa != lastSisa) { + + lastSisa = sisa; + + lcd.clear(); + + lcd.setCursor(0, 0); + lcd.print("Pintu Terbuka"); + + lcd.setCursor(0, 1); + lcd.print("Sisa:"); + lcd.print(sisa); + lcd.print(" dtk"); + } + + // tutup otomatis setelah 25 detik + if (millis() - waktuBuka >= 25000) { + + servoBuka.write(0); + + sedangBuka = false; + lastBukaTabungan = false; + + Firebase.RTDB.setBool( + &fbdo, + "/tabungan/buka_tabungan", + false + ); + + lcdDefault(); + + Serial.println("Servo Tabungan: TERTUTUP"); + } + } +} + + + void cekDetectedValueFirebase() { + + static unsigned long lastSync = 0; + + if (millis() - lastSync < 1000) + return; + + lastSync = millis(); + + if (!Firebase.RTDB.getInt( + &fbdo, + "/tabungan/detected_value")) + return; + + int val = fbdo.intData(); + + // jika nilai direset dari Flutter + if (val == 0) { + + lastDetectedVal = 0; + + lcdDefault(); + + return; + } + + if (lastKonfirmasi) + return; + + if (val == lastDetectedVal) + return; + + lastDetectedVal = val; + + Serial.print("Sync Firebase: "); + Serial.println(val); + + updateLCD(); +} + +// ===================================================== +// SETUP +// ===================================================== + +void setup() { + + // disable brownout sementara + WRITE_PERI_REG( + RTC_CNTL_BROWN_OUT_REG, + 0 + ); + + Serial.begin(115200); + + Serial.println(); + Serial.println("System Booting..."); + + Wire.begin(); + + lcd.init(); + lcd.backlight(); + + lcd.clear(); + + lcd.setCursor(0, 0); + lcd.print(" TABUNGANKU "); + + lcd.setCursor(0, 1); + lcd.print(" BOOTING... "); + + setupTCS3200(); + + + // JANGAN attach servo di awal + // supaya tidak brownout + + connectWiFi(); + + setupFirebase(); + + // reset firebase + Firebase.RTDB.setInt( + &fbdo, + "/tabungan/detected_value", + 0 + ); + + Firebase.RTDB.setBool( + &fbdo, + "/tabungan/konfirmasi_masuk", + false + ); + + Firebase.RTDB.setBool( + &fbdo, + "/tabungan/masukkan_uang", + false + ); + + Firebase.RTDB.setBool( + &fbdo, + "/tabungan/buka_tabungan", + false + ); + + Serial.println("Firebase Reset"); + + lcdDefault(); + + Serial.println("System Ready"); +} + +// ===================================================== +// LOOP +// ===================================================== + +void loop() { + + static unsigned long lastWiFiCheck = 0; + + if (millis() - lastWiFiCheck > 10000) { + lastWiFiCheck = millis(); + + if (WiFi.status() != WL_CONNECTED) { + connectWiFi(); + } + } + + cekUangKertas(); + + cekKonfirmasiFlutter(); + + cekServoMasuk(); + + cekServoBukaTabungan(); + + cekDetectedValueFirebase(); + + delay(200); +} \ No newline at end of file