// ESP32 Digital Password Door Lock System with Facial Recognition
// Enhanced for waterproofing, energy efficiency, and security
#include <WiFi.h>
#include <WebServer.h>
#include <Keypad.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <ESP32Servo.h>
#include "esp_camera.h"
#include "esp_timer.h"
#include "img_converters.h"
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
// Network credentials
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// Components pin configuration
#define SERVO_PIN 4
#define BUZZER_PIN 2
#define RED_LED 5
#define GREEN_LED 15
#define PIR_MOTION_PIN 16
// Keypad configuration
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] = {13, 12, 14, 27};
byte colPins[COLS] = {26, 25, 33, 32};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// LCD configuration
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Servo configuration
Servo lockServo;
// Password management
const String MASTER_PASSWORD = "1234";
String currentPassword = "5555";
String inputPassword = "";
bool doorLocked = true;
int failedAttempts = 0;
const int MAX_FAILED_ATTEMPTS = 5;
// Energy management
unsigned long lastActivityTime = 0;
const unsigned long SLEEP_DELAY = 30000; // Sleep after 30 seconds of inactivity
bool motionDetected = false;
bool deepSleepEnabled = true;
// Face recognition variables
bool faceRecognitionEnabled = true;
bool faceDetected = false;
bool faceRecognized = false;
// Web server for mobile app integration
WebServer server(80);
bool notificationSent = false;
// Power harvesting simulation
float harvestedEnergy = 0.0;
const float KEYPRESS_ENERGY = 0.01; // Energy harvested per keypress in mJ
void setup() {
// Initialize serial communication
Serial.begin(115200);
// Pin modes
pinMode(BUZZER_PIN, OUTPUT);
pinMode(RED_LED, OUTPUT);
pinMode(GREEN_LED, OUTPUT);
pinMode(PIR_MOTION_PIN, INPUT);
// Initialize servo
lockServo.attach(SERVO_PIN);
lockServo.write(0); // Locked position
// Initialize LCD
Wire.begin();
lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Door Lock System");
lcd.setCursor(0, 1);
lcd.print("Initializing...");
delay(2000);
// Connect to WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to WiFi. IP: ");
Serial.println(WiFi.localIP());
// Simulate camera initialization
initCamera();
// Setup web server routes
setupWebServer();
server.begin();
// Initial state
lockDoor();
// Ready to use
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("System Ready");
lcd.setCursor(0, 1);
lcd.print("Enter Password:");
// Beep to indicate ready
beep(100);
}
void loop() {
// Handle web server clients
server.handleClient();
// Check for motion to wake device from sleep mode
if (digitalRead(PIR_MOTION_PIN) == HIGH) {
motionDetected = true;
lastActivityTime = millis();
wakeUp();
// Simulate face detection when motion detected
if (faceRecognitionEnabled) {
detectFace();
}
}
// Handle keypad input
char key = keypad.getKey();
if (key) {
// Simulate energy harvesting from keypress
harvestEnergy(key);
// Reset sleep timer on activity
lastActivityTime = millis();
// Process the key press
processKeyPress(key);
}
// Check if face was recognized
if (faceRecognized && doorLocked) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Face Recognized");
lcd.setCursor(0, 1);
lcd.print("Door Unlocking");
// Unlock door
unlockDoor();
// Send notification
if (!notificationSent) {
sendNotification("Door unlocked by facial recognition");
notificationSent = true;
}
// Reset after 5 seconds
delay(5000);
lockDoor();
faceRecognized = false;
notificationSent = false;
}
// Check for deep sleep condition
if (deepSleepEnabled && (millis() - lastActivityTime > SLEEP_DELAY) && doorLocked) {
enterDeepSleep();
}
}
// Process keypad input
void processKeyPress(char key) {
beep(50); // Short beep for feedback
if (key == '#') {
// Submit password
checkPassword();
}
else if (key == '*') {
// Clear input
inputPassword = "";
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Input cleared");
lcd.setCursor(0, 1);
lcd.print("Enter Password:");
}
else if (key == 'A') {
// Change password mode
promptMasterPassword();
}
else if (key == 'D' && !doorLocked) {
// Force lock door
lockDoor();
}
else {
// Add to password input
inputPassword += key;
// Update display with asterisks
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter Password:");
lcd.setCursor(0, 1);
String displayMask = "";
for (int i = 0; i < inputPassword.length(); i++) {
displayMask += "*";
}
lcd.print(displayMask);
}
}
// Check if entered password is correct
void checkPassword() {
if (inputPassword == currentPassword) {
// Correct password
failedAttempts = 0;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Access Granted");
lcd.setCursor(0, 1);
lcd.print("Door Unlocking");
digitalWrite(GREEN_LED, HIGH);
beepSuccess();
// Unlock door
unlockDoor();
// Send notification
if (!notificationSent) {
sendNotification("Door unlocked with password");
notificationSent = true;
}
// Automatically lock after 5 seconds
delay(5000);
lockDoor();
notificationSent = false;
digitalWrite(GREEN_LED, LOW);
}
else {
// Wrong password
failedAttempts++;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Wrong Password!");
lcd.setCursor(0, 1);
lcd.print("Attempts: " + String(failedAttempts) + "/" + String(MAX_FAILED_ATTEMPTS));
digitalWrite(RED_LED, HIGH);
beepError();
delay(1000);
digitalWrite(RED_LED, LOW);
// Check if max attempts reached
if (failedAttempts >= MAX_FAILED_ATTEMPTS) {
triggerAlarm();
}
}
// Reset input
inputPassword = "";
// Return to main screen after 2 seconds
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Door Lock System");
lcd.setCursor(0, 1);
lcd.print("Enter Password:");
}
// Master password entry for changing the password
void promptMasterPassword() {
inputPassword = "";
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter Master PWD:");
// Get master password input
while (true) {
char key = keypad.getKey();
if (key) {
beep(50);
if (key == '#') {
break; // Confirm input
}
else if (key == '*') {
inputPassword = "";
lcd.setCursor(0, 1);
lcd.print(" ");
}
else {
inputPassword += key;
lcd.setCursor(0, 1);
String displayMask = "";
for (int i = 0; i < inputPassword.length(); i++) {
displayMask += "*";
}
lcd.print(displayMask);
}
}
}
// Verify master password
if (inputPassword == MASTER_PASSWORD) {
changePassword();
}
else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Invalid Master");
lcd.setCursor(0, 1);
lcd.print("Password!");
beepError();
delay(2000);
inputPassword = "";
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Door Lock System");
lcd.setCursor(0, 1);
lcd.print("Enter Password:");
}
}
// Change the door lock password
void changePassword() {
inputPassword = "";
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("New Password:");
// Get new password
while (true) {
char key = keypad.getKey();
if (key) {
beep(50);
if (key == '#') {
if (inputPassword.length() > 0) {
break; // Confirm if password not empty
}
}
else if (key == '*') {
inputPassword = "";
lcd.setCursor(0, 1);
lcd.print(" ");
}
else {
inputPassword += key;
lcd.setCursor(0, 1);
String displayMask = "";
for (int i = 0; i < inputPassword.length(); i++) {
displayMask += "*";
}
lcd.print(displayMask);
}
}
}
// Save new password
if (inputPassword.length() > 0) {
currentPassword = inputPassword;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Password Changed");
lcd.setCursor(0, 1);
lcd.print("Successfully!");
beepSuccess();
delay(2000);
}
inputPassword = "";
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Door Lock System");
lcd.setCursor(0, 1);
lcd.print("Enter Password:");
}
// Lock the door
void lockDoor() {
lockServo.write(0); // 0 degrees = locked position
doorLocked = true;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Door Locked");
delay(1000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Door Lock System");
lcd.setCursor(0, 1);
lcd.print("Enter Password:");
}
// Unlock the door
void unlockDoor() {
lockServo.write(90); // 90 degrees = unlocked position
doorLocked = false;
}
// Sound patterns
void beep(int duration) {
digitalWrite(BUZZER_PIN, HIGH);
delay(duration);
digitalWrite(BUZZER_PIN, LOW);
}
void beepSuccess() {
beep(100);
delay(100);
beep(100);
}
void beepError() {
beep(300);
}
// Trigger alarm after 5 failed attempts
void triggerAlarm() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("INTRUDER ALERT!");
lcd.setCursor(0, 1);
lcd.print("System Locked");
// Send emergency notification
sendNotification("EMERGENCY: Multiple failed attempts detected!");
// Sound alarm and flash LED
for (int i = 0; i < 10; i++) {
digitalWrite(RED_LED, HIGH);
digitalWrite(BUZZER_PIN, HIGH);
delay(500);
digitalWrite(RED_LED, LOW);
digitalWrite(BUZZER_PIN, LOW);
delay(200);
}
// Lock system for 30 seconds
delay(30000);
// Reset failed attempts
failedAttempts = 0;
}
// Simulate camera and face recognition
void initCamera() {
Serial.println("Initializing camera...");
delay(1000);
Serial.println("Camera initialized");
}
void detectFace() {
// Simulate face detection process
Serial.println("Detecting face...");
delay(500);
// Randomly simulate face detection (for demo)
faceDetected = (random(100) > 40); // 60% chance of detection
if (faceDetected) {
Serial.println("Face detected!");
// Simulate face recognition (for demo)
faceRecognized = (random(100) > 50); // 50% chance of recognition if face detected
if (faceRecognized) {
Serial.println("Face recognized!");
} else {
Serial.println("Face not recognized");
}
} else {
Serial.println("No face detected");
faceRecognized = false;
}
}
// Energy management functions
void enterDeepSleep() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Entering Sleep");
lcd.setCursor(0, 1);
lcd.print("Mode...");
delay(2000);
lcd.noBacklight();
// In real hardware, would use:
// esp_sleep_enable_ext0_wakeup(PIR_MOTION_PIN, HIGH);
// esp_deep_sleep_start();
Serial.println("Entering deep sleep mode");
}
void wakeUp() {
lcd.backlight();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Door Lock System");
lcd.setCursor(0, 1);
lcd.print("Enter Password:");
beep(50);
Serial.println("Waking up from sleep mode");
}
// Simulate energy harvesting from keypad
void harvestEnergy(char key) {
harvestedEnergy += KEYPRESS_ENERGY;
Serial.print("Energy harvested: ");
Serial.print(harvestedEnergy);
Serial.println(" mJ");
}
// Mobile app integration
void setupWebServer() {
server.on("/", HTTP_GET, []() {
server.send(200, "text/html", "<html><body><h1>Door Lock System</h1><p>System is running</p></body></html>");
});
server.on("/status", HTTP_GET, []() {
String status = "{\"locked\": " + String(doorLocked ? "true" : "false") +
", \"failedAttempts\": " + String(failedAttempts) +
", \"batteryLevel\": " + String(100) +
", \"harvestedEnergy\": " + String(harvestedEnergy) + "}";
server.send(200, "application/json", status);
});
server.on("/unlock", HTTP_GET, []() {
unlockDoor();
server.send(200, "text/plain", "Door unlocked remotely");
delay(5000);
lockDoor();
});
}
void sendNotification(String message) {
Serial.print("Notification sent: ");
Serial.println(message);
// In a real implementation, this would send HTTP request to a notification service
}