#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <ESP32Servo.h>
#include <Preferences.h>
#include <EEPROM.h>
// LCD setup
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Keypad setup
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] = {15, 2, 0, 4};
byte colPins[COLS] = {16, 17, 5, 19};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// Relay, servo, and pin setup
Servo gateServo;
#define SERVO_PIN 18
#define RELAY_PIN 22
// Preferences and EEPROM setup
Preferences preferences;
#define EEPROM_SIZE 64
#define EEPROM_PASSWORD_ADDR 0
// Default password
String defaultPassword = "09090909";
String correctPassword = "";
String inputPassword = "";
// State variables
bool isUnlocked = false;
bool changePasswordMode = false;
bool enterNewPassword = false;
int starPressCount = 0;
unsigned long lastStarPressTime = 0;
const unsigned long doublePressInterval = 500;
void setup() {
Serial.begin(115200);
// Initialize Preferences and EEPROM
preferences.begin("pass_storage", false);
EEPROM.begin(EEPROM_SIZE);
// Read password from Preferences or EEPROM
correctPassword = preferences.getString("password", "");
if (correctPassword == "") {
correctPassword = readPasswordFromEEPROM();
if (correctPassword == "" || correctPassword.indexOf((char)255) != -1) {
correctPassword = defaultPassword;
writePasswordToPreferences(correctPassword);
writePasswordToEEPROM(correctPassword);
}
}
Serial.println("Current Password in EEPROM:");
Serial.println(correctPassword);
Wire.begin(25, 26);
lcd.begin(16, 2);
lcd.backlight();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Nhap mk:");
gateServo.attach(SERVO_PIN);
gateServo.write(0); // Start with the door closed
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, LOW);
}
void loop() {
char key = keypad.getKey();
if (key) {
Serial.print("Key pressed: ");
Serial.println(key);
if (key == '*') {
unsigned long currentTime = millis();
if (currentTime - lastStarPressTime <= doublePressInterval) {
starPressCount++;
} else {
starPressCount = 1;
}
lastStarPressTime = currentTime;
if (starPressCount == 2) {
if (isUnlocked) {
closeDoor(); // Close door when ** is pressed
}
} else if (starPressCount == 3) {
enterPasswordChangeMode();
starPressCount = 0;
}
} else if (key == '#') {
if (changePasswordMode) {
if (!enterNewPassword) {
checkOldPassword();
} else {
saveNewPassword();
}
} else {
checkPassword();
}
} else {
inputPassword += key;
displayPassword();
}
}
}
void enterPasswordChangeMode() {
changePasswordMode = true;
inputPassword = "";
lcd.clear();
lcd.print("Nhap MK cu:");
}
void checkOldPassword() {
if (inputPassword == correctPassword) {
enterNewPassword = true;
inputPassword = "";
lcd.clear();
lcd.print("MK moi (kytu>8):");
} else {
lcd.clear();
lcd.print("Sai MK cu");
delay(2000);
changePasswordMode = false;
enterNewPassword = false;
inputPassword = "";
lcd.clear();
lcd.print("Nhap mat khau:");
}
}
void saveNewPassword() {
if (inputPassword.length() > 8) {
correctPassword = inputPassword;
writePasswordToPreferences(correctPassword);
writePasswordToEEPROM(correctPassword);
lcd.clear();
lcd.print("Doi MK thanh cong");
delay(2000);
} else {
lcd.clear();
lcd.print("MK > 8 ky tu");
delay(2000);
}
changePasswordMode = false;
enterNewPassword = false;
inputPassword = "";
lcd.clear();
lcd.print("Nhap mat khau:");
}
void checkPassword() {
if (inputPassword == correctPassword) {
lcd.clear();
lcd.print("Mat khau dung");
openDoor();
delay(2000);
} else {
lcd.clear();
lcd.print("Sai mat khau");
delay(2000);
}
inputPassword = "";
lcd.clear();
lcd.print("Nhap mat khau:");
}
// Open the door with the servo
void openDoor() {
gateServo.write(90); // Open door (90 degrees)
digitalWrite(RELAY_PIN, HIGH); // Relay on to indicate door is open
lcd.clear();
lcd.print("Cua da mo");
isUnlocked = true; // Keep door open until ** is pressed to close
}
// Close the door with the servo
void closeDoor() {
gateServo.write(0); // Close door (0 degrees)
digitalWrite(RELAY_PIN, LOW); // Relay off to indicate door is closed
lcd.clear();
lcd.print("Cua da dong");
delay(2000);
isUnlocked = false;
}
// Save password to Preferences
void writePasswordToPreferences(String password) {
preferences.putString("password", password);
}
// Save password to EEPROM
void writePasswordToEEPROM(String password) {
clearEEPROM();
for (int i = 0; i < password.length(); i++) {
EEPROM.write(EEPROM_PASSWORD_ADDR + i, password[i]);
}
EEPROM.write(EEPROM_PASSWORD_ADDR + password.length(), '\0');
EEPROM.commit();
}
// Read password from EEPROM
String readPasswordFromEEPROM() {
String password = "";
for (int i = 0; i < 32; i++) {
char c = EEPROM.read(EEPROM_PASSWORD_ADDR + i);
if (c == '\0') break;
password += c;
}
return password;
}
// Clear EEPROM data
void clearEEPROM() {
for (int i = 0; i < EEPROM_SIZE; i++) {
EEPROM.write(i, 0);
}
EEPROM.commit();
}
// Display password as '*' on LCD
void displayPassword() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Nhap mat khau:");
lcd.setCursor(0, 1);
for (int i = 0; i < inputPassword.length(); i++) {
lcd.print("*");
}
}