Upload files to "/"

This commit is contained in:
lindadwiwinandha 2025-08-05 10:53:24 +07:00
commit ad37effced
1 changed files with 280 additions and 0 deletions

280
Celengan_Final.ino Normal file
View File

@ -0,0 +1,280 @@
#include <Wire.h>
#include <Adafruit_PCF8574.h>
#include <LiquidCrystal_I2C.h>
#include <ThingerESP8266.h>
// --- THINGER.IO ---
#define USERNAME "lindadwi"
#define DEVICE_ID "Celengan_Pintar"
#define DEVICE_CREDENTIAL "celengan8266"
#define SSID "ozie 3"
#define PASSWORD "followkami"
ThingerESP8266 thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL);
// --- TCS3200 ---
#define S0 D5
#define S1 D6
#define S2 D7
#define S3 D8
#define sensorOut D3
// --- RELAY & SWITCH ---
#define RELAY_PIN D0
#define SWITCH_PIN D4
// --- KEYPAD PCF8574 ---
Adafruit_PCF8574 pcf;
const byte ROWS = 4, COLS = 3;
char keys[ROWS][COLS] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}
};
int rowPins[4] = {0, 1, 2, 3};
int colPins[3] = {4, 5, 6};
// --- LCD I2C ---
LiquidCrystal_I2C lcd(0x27, 16, 2);
// --- GLOBAL ---
String nominal = "Tidak dikenali";
const int TOLERANSI = 20;
String inputSandi = "";
bool relayAktif = false;
bool pintuBaruDibuka = false;
bool pintuTerbukaSebelumnya = false;
int totalSaldo = 0;
void setup() {
Serial.begin(9600);
// Thinger
thing.add_wifi(SSID, PASSWORD);
// Resource realtime saldo
thing["total_saldo"] >> [](pson &out){
out = totalSaldo;
};
// TCS3200
pinMode(S0, OUTPUT); pinMode(S1, OUTPUT);
pinMode(S2, OUTPUT); pinMode(S3, OUTPUT);
pinMode(sensorOut, INPUT);
digitalWrite(S0, HIGH);
digitalWrite(S1, LOW);
// RELAY & SWITCH
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, HIGH); // Relay OFF
pinMode(SWITCH_PIN, INPUT_PULLUP);
// KEYPAD
if (!pcf.begin(0x20)) {
Serial.println("PCF8574 tidak terdeteksi!");
while (1);
}
for (int i = 0; i < 8; i++) pcf.pinMode(i, INPUT_PULLUP);
// LCD
lcd.begin(16, 2);
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Masukkan uang");
}
// === LOOP ===
void loop() {
thing.handle();
bool pintuTertutup = digitalRead(SWITCH_PIN) == LOW;
// Deteksi pintu dibuka untuk reset saldo
if (!pintuTertutup && !pintuTerbukaSebelumnya) {
if (totalSaldo > 0) {
Serial.println("Pintu dibuka - reset saldo");
pson data;
data["status"] = "diambil";
data["saldo"] = totalSaldo;
thing.write_bucket("data_uang", data);
totalSaldo = 0;
}
pintuTerbukaSebelumnya = true;
}
if (pintuTertutup && pintuTerbukaSebelumnya) {
pintuTerbukaSebelumnya = false;
}
// Kontrol relay berdasarkan status
if (relayAktif) {
if (!pintuTertutup) {
pintuBaruDibuka = true;
} else if (pintuBaruDibuka && pintuTertutup) {
relayAktif = false;
digitalWrite(RELAY_PIN, HIGH); // Relay OFF
pintuBaruDibuka = false;
Serial.println("Pintu ditutup kembali - Relay OFF");
lcd.setCursor(0, 0);
lcd.print("Pintu tertutup ");
lcd.setCursor(0, 1);
lcd.print("Akses selesai ");
delay(2000);
lcd.setCursor(0, 0);
lcd.print("Masukkan uang ");
lcd.setCursor(0, 1);
lcd.print(" ");
}
}
// === TOMBOL ===
char tombol = bacaTombol();
if (tombol != 0) {
inputSandi += tombol;
if (inputSandi.length() > 4) inputSandi.remove(0, 1);
lcd.setCursor(0, 0);
lcd.print("Masukkan sandi ");
lcd.setCursor(0, 1);
lcd.print(inputSandi + " ");
if (tombol == '*') {
if (nominal != "Tidak dikenali") {
int nilai = konversiNominalKeInt(nominal);
if (nilai > 0) {
totalSaldo += nilai;
lcd.setCursor(0, 0);
lcd.print("Akses diterima ");
lcd.setCursor(0, 1);
lcd.print("Tambah: " + nominal + " ");
Serial.println("Menambah: " + nominal);
pson data;
data["status"] = "tambah";
data["saldo"] = totalSaldo;
data["nominal"] = nominal;
thing.write_bucket("data_uang", data);
delay(2000);
lcd.setCursor(0, 0);
lcd.print("Masukkan uang ");
lcd.setCursor(0, 1);
lcd.print(" ");
}
}
else if (inputSandi == "123*") {
if (pintuTertutup) {
relayAktif = true;
digitalWrite(RELAY_PIN, LOW); // Relay ON
Serial.println("Akses diterima - Relay ON");
lcd.setCursor(0, 0);
lcd.print("Akses diterima ");
} else {
Serial.println("Pintu tidak rapat");
lcd.setCursor(0, 0);
lcd.print("Pintu terbuka ");
}
lcd.setCursor(0, 1);
lcd.print(" ");
delay(2000);
lcd.setCursor(0, 0);
lcd.print("Masukkan uang ");
lcd.setCursor(0, 1);
lcd.print(" ");
}
else {
relayAktif = false;
digitalWrite(RELAY_PIN, HIGH); // Relay OFF
Serial.println("Akses ditolak");
lcd.setCursor(0, 0);
lcd.print("Akses ditolak ");
lcd.setCursor(0, 1);
lcd.print(" ");
delay(2000);
lcd.setCursor(0, 0);
lcd.print("Masukkan uang ");
lcd.setCursor(0, 1);
lcd.print(" ");
}
inputSandi = "";
}
}
// === DETEKSI WARNA ===
int red = bacaWarna(LOW, LOW);
int green = bacaWarna(HIGH, HIGH);
int blue = bacaWarna(LOW, HIGH);
Serial.print("R: "); Serial.print(red);
Serial.print(" G: "); Serial.print(green);
Serial.print(" B: "); Serial.println(blue);
nominal = detectUang(red, green, blue);
Serial.println("Terdeteksi: " + nominal);
lcd.setCursor(0, 1);
if (nominal == "Tidak dikenali") {
lcd.print("... ");
} else {
lcd.print("Nominal: " + nominal + " ");
}
delay(1000);
}
// === BACA WARNA ===
int bacaWarna(bool s2, bool s3) {
digitalWrite(S2, s2);
digitalWrite(S3, s3);
return pulseIn(sensorOut, LOW);
}
// === KONVERSI NOMINAL ===
int konversiNominalKeInt(String nominal) {
if (nominal == "1k") return 1000;
if (nominal == "2k") return 2000;
if (nominal == "5k") return 5000;
if (nominal == "10k") return 10000;
if (nominal == "20k") return 20000;
if (nominal == "50k") return 50000;
if (nominal == "100k") return 100000;
return 0;
}
// === DETEKSI UANG ===
bool isInRange(int val, int ref) {
return val >= (ref - TOLERANSI) && val <= (ref + TOLERANSI);
}
String detectUang(int r, int g, int b) {
if (isInRange(r,195) && isInRange(g,200) && isInRange(b,196)) return "1k";
if (isInRange(r,132) && isInRange(g,165) && isInRange(b,132)) return "2k";
if (isInRange(r,215) && isInRange(g,260) && isInRange(b,215)) return "10k";
if (isInRange(r,155) && isInRange(g,157) && isInRange(b,155)) return "20k";
if (isInRange(r,137) && isInRange(g,170) && isInRange(b,137)) return "50k";
if (isInRange(r,148) && isInRange(g,167) && isInRange(b,148)) return "100k";
if (isInRange(r,175) && isInRange(g,171) && isInRange(b,175)) return "5k";
return "Tidak dikenali";
}
// === BACA TOMBOL ===
char bacaTombol() {
for (int r = 0; r < ROWS; r++) {
pcf.pinMode(rowPins[r], OUTPUT);
pcf.digitalWrite(rowPins[r], LOW);
delayMicroseconds(50);
for (int c = 0; c < COLS; c++) {
if (!pcf.digitalRead(colPins[c])) {
char key = keys[r][c];
while (!pcf.digitalRead(colPins[c]));
pcf.pinMode(rowPins[r], INPUT_PULLUP);
return key;
}
}
pcf.pinMode(rowPins[r], INPUT_PULLUP);
}
return 0;
}