Upload files to "/"
This commit is contained in:
commit
ad37effced
|
@ -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;
|
||||||
|
}
|
Loading…
Reference in New Issue