#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
// Konfigurasi Keypad 4x4
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {5, 4, 3, 2};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// Konfigurasi LCD I2C
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Pin Relay
const int RELAY_PIN = 12;
const int MAGNETIC_CONTACT_PIN = 11;
// Variabel untuk PIN
String masterPIN = "123456"; // PIN Admin default
const int MAX_ACCESS_PINS = 5;
String accessPINs[MAX_ACCESS_PINS] = {"1234", "", "", "", ""}; // Array untuk menyimpan PIN akses
int numAccessPINs = 1; // Jumlah PIN akses yang aktif
String inputPIN = "";
boolean unlockMode = false;
// Status sistem
enum SystemState {
LOCKED,
UNLOCKED,
ADMIN_MODE
};
SystemState currentState = LOCKED;
void setup() {
Serial.begin(9600);
// Inisialisasi LCD
lcd.init();
lcd.backlight();
lcd.clear();
lcd.print("System Starting..");
// Inisialisasi Relay
pinMode(RELAY_PIN, OUTPUT);
pinMode(MAGNETIC_CONTACT_PIN, INPUT_PULLUP);
digitalWrite(RELAY_PIN, HIGH); // Relay normally closed
lcd.clear();
lcd.print("Rumah Koecha");
delay(1000);
showMainScreen();
}
void loop() {
char key = keypad.getKey();
if (key) {
processKeyInput(key);
}
}
void processKeyInput(char key) {
if (currentState == ADMIN_MODE) {
processAdminMode(key);
} else {
if (key == '*') { // Clear input
inputPIN = "";
showMainScreen();
}
else if (key == '#') { // Submit PIN
if (inputPIN == masterPIN) {
currentState = ADMIN_MODE;
showAdminMenu();
} else if (checkAccessPIN(inputPIN)) {
unlockSystem();
} else {
lcd.clear();
lcd.print("Wrong PIN!");
delay(2000);
inputPIN = "";
showMainScreen();
}
}
else {
if (inputPIN.length() < 6) {
inputPIN += key;
updatePINDisplay();
}
}
}
}
bool checkAccessPIN(String pin) {
for(int i = 0; i < MAX_ACCESS_PINS; i++) {
if(accessPINs[i] == pin) return true;
}
return false;
}
void showMainScreen() {
lcd.clear();
lcd.print("Enter PIN:");
lcd.setCursor(0, 1);
}
void updatePINDisplay() {
lcd.clear();
lcd.print("Enter PIN:");
lcd.setCursor(0, 1);
for (int i = 0; i < inputPIN.length(); i++) {
lcd.print("*");
}
}
void showAdminMenu() {
lcd.clear();
lcd.print("1:Add 2:Del 3:List");
lcd.setCursor(0, 1);
lcd.print("4:Admin *:Exit");
}
void processAdminMode(char key) {
switch (key) {
case '1':
addAccessPIN();
break;
case '2':
deleteAccessPIN();
break;
case '3':
listAccessPINs();
break;
case '4':
changeAdminPIN();
break;
case '*':
currentState = LOCKED;
showMainScreen();
break;
}
}
void addAccessPIN() {
if(numAccessPINs >= MAX_ACCESS_PINS) {
lcd.clear();
lcd.print("Memory Full!");
delay(2000);
showAdminMenu();
return;
}
inputPIN = "";
lcd.clear();
lcd.print("New Access PIN:");
lcd.setCursor(0, 1);
while (true) {
char key = keypad.getKey();
if (key) {
if (key == '#') {
if (inputPIN.length() >= 4) {
// Cek apakah PIN sudah ada
if(checkAccessPIN(inputPIN)) {
lcd.clear();
lcd.print("PIN exists!");
delay(2000);
showAdminMenu();
return;
}
// Tambahkan PIN baru
accessPINs[numAccessPINs] = inputPIN;
numAccessPINs++;
lcd.clear();
lcd.print("PIN Added!");
delay(2000);
showAdminMenu();
return;
}
}
else if (key == '*') {
showAdminMenu();
return;
}
else if (inputPIN.length() < 6) {
inputPIN += key;
lcd.setCursor(inputPIN.length()-1, 1);
lcd.print("*");
}
}
}
}
void deleteAccessPIN() {
inputPIN = "";
lcd.clear();
lcd.print("Del PIN:");
lcd.setCursor(0, 1);
while (true) {
char key = keypad.getKey();
if (key) {
if (key == '#') {
if (inputPIN.length() >= 4) {
bool found = false;
// Cari dan hapus PIN
for(int i = 0; i < numAccessPINs; i++) {
if(accessPINs[i] == inputPIN) {
// Geser PIN yang tersisa
for(int j = i; j < numAccessPINs - 1; j++) {
accessPINs[j] = accessPINs[j+1];
}
accessPINs[numAccessPINs-1] = "";
numAccessPINs--;
found = true;
break;
}
}
lcd.clear();
if(found) {
lcd.print("PIN Deleted!");
} else {
lcd.print("PIN Not Found!");
}
delay(2000);
showAdminMenu();
return;
}
}
else if (key == '*') {
showAdminMenu();
return;
}
else if (inputPIN.length() < 6) {
inputPIN += key;
lcd.setCursor(inputPIN.length()-1, 1);
lcd.print("*");
}
}
}
}
void listAccessPINs() {
int currentPin = 0;
while(true) {
lcd.clear();
if(numAccessPINs == 0) {
lcd.print("No PINs!");
lcd.setCursor(0, 1);
lcd.print("*:Back");
} else {
lcd.print("PIN ");
lcd.print(currentPin + 1);
lcd.print(": ");
lcd.print(accessPINs[currentPin]);
lcd.setCursor(0, 1);
lcd.print("*:Back #:Next");
}
char key = keypad.getKey();
while(!key) key = keypad.getKey();
if(key == '*') {
showAdminMenu();
return;
} else if(key == '#' && numAccessPINs > 0) {
currentPin = (currentPin + 1) % numAccessPINs;
}
}
}
void changeAdminPIN() {
inputPIN = "";
lcd.clear();
lcd.print("New Admin PIN:");
lcd.setCursor(0, 1);
while (true) {
char key = keypad.getKey();
if (key) {
if (key == '#') {
if (inputPIN.length() >= 4) {
masterPIN = inputPIN;
lcd.clear();
lcd.print("Admin PIN");
lcd.setCursor(0, 1);
lcd.print("Changed!");
delay(2000);
showAdminMenu();
return;
}
}
else if (key == '*') {
showAdminMenu();
return;
}
else if (inputPIN.length() < 6) {
inputPIN += key;
lcd.setCursor(inputPIN.length()-1, 1);
lcd.print("*");
}
}
}
}
// void unlockSystem() {
// currentState = UNLOCKED;
// digitalWrite(RELAY_PIN, LOW); // Activate relay
// lcd.clear();
// lcd.print("Pintu terbuka!");
// delay(3000);
// digitalWrite(RELAY_PIN, HIGH); // Deactivate relay
// currentState = LOCKED;
// inputPIN = "";
// showMainScreen();
// }
void unlockSystem() {
currentState = UNLOCKED;
digitalWrite(RELAY_PIN, LOW); // Activate relay
lcd.clear();
lcd.print("Pintu terbuka!");
// Loop sampai magnetic contact tersambung
while(true) {
if(digitalRead(MAGNETIC_CONTACT_PIN) == LOW) { // Magnetic contact tersambung (pintu tertutup)
lcd.clear();
lcd.print("Pintu tertutup");
lcd.setCursor(0, 1);
lcd.print("Mengunci...");
delay(3000); // Tunggu 3 detik
digitalWrite(RELAY_PIN, HIGH); // Deactivate relay
break;
}
// Update display setiap 2 detik jika pintu masih terbuka
static unsigned long lastUpdate = 0;
if(millis() - lastUpdate >= 2000) {
lcd.clear();
lcd.print("Tunggu pintu");
lcd.setCursor(0, 1);
lcd.print("tertutup...");
lastUpdate = millis();
}
// Tetap membaca keypad untuk fungsi lain jika diperlukan
char key = keypad.getKey();
if(key) {
// Handle emergency lock jika diperlukan
if(key == '#') {
lcd.clear();
lcd.print("Force lock!");
delay(1000);
digitalWrite(RELAY_PIN, HIGH);
break;
}
}
}
currentState = LOCKED;
inputPIN = "";
showMainScreen();
}