#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <ESP32Servo.h>
#include <NewPing.h>
// Setup LCD dan keypad
LiquidCrystal_I2C lcd(0x27, 16, 2);
const byte ROWS = 4, COLS = 4;
char keys[ROWS][COLS] = { {'1', '2', '3', 'A'}, {'4', '5', '6', 'B'}, {'7', '8', '9', 'C'}, {'*', '0', '#', 'D'} };
byte rowPins[ROWS] = {13, 12, 14, 27}, colPins[COLS] = {26, 25, 33, 32};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// sensor ultrasonik
Servo servo;
#define TRIG_PIN 18
#define ECHO_PIN 5
#define MAX_DISTANCE 200
NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DISTANCE);
// Variabel kunci dan PIN
String CORRECT_PIN = "123";
#define AUTO_LOCK_DELAY 5000
#define DYNAMIC_PIN_DELAY 10000
String inputPIN = "";
bool lockClosed = true;
bool doorClosed = true;
unsigned long doorClosedTime = 0;
unsigned long PINChangeTime = millis();
void setup() {
Serial.begin(115200);
lcd.init(); lcd.backlight();
servo.attach(15, 500, 2400);
servo.write(180); // Posisi servo kunci tertutup
inputPIN.reserve(3);
}
void loop() {
dynamicPIN ();
doorClosed = sonar.ping_cm() < 5; // Deteksi status pintu
if (lockClosed && doorClosed) {
showMessage("Kunci Tertutup");
handleKeypadInput();
} else if (lockClosed && !doorClosed) {
showMessage("Pintu Dibobol!"); // Peringatan jika pintu terbuka tapi kunci tertutup
handleKeypadInput();
} else if (!lockClosed && doorClosed) {
showMessage("Kunci Terbuka");
autoLock(); // Cek apakah perlu mengunci otomatis
} else if (!lockClosed && !doorClosed) {
showMessage("Kunci Terbuka");
doorClosedTime = 0; // Reset waktu jika pintu terbuka
}
}
void handleKeypadInput() {
char key = keypad.getKey();
if (!key) return;
if (key == '#') {
if (inputPIN == CORRECT_PIN) {
lcd.clear();
showMessage("Kunci Terbuka");
servo.write(90); // Buka kunci
lockClosed = false;
} else {
lcd.clear();
showMessage("PIN Salah");
delay(1000);
}
inputPIN = ""; // Reset input setelah pengecekan PIN
} else if (key == '*') {
lcd.clear();
inputPIN = ""; // Reset input PIN
} else {
inputPIN += key;
lcd.setCursor(0, 1);
lcd.print("PIN: " + inputPIN);
}
}
void autoLock() {
if (!doorClosedTime) doorClosedTime = millis(); // Catat waktu saat pintu tertutup
if (millis() - doorClosedTime >= AUTO_LOCK_DELAY) {
lockClosed = true;
servo.write(180); // Kunci pintu secara otomatis
showMessage("Kunci Tertutup");
doorClosedTime = 0;
}
}
void showMessage(String message) {
lcd.setCursor(0, 0);
lcd.print(message);
}
void dynamicPIN () {
if (millis() - PINChangeTime >= DYNAMIC_PIN_DELAY) {
PINChangeTime = millis();
CORRECT_PIN = String(millis() % 1000);
Serial.print("PIN: ");
Serial.println(CORRECT_PIN);
}
}