Cirkit Designer LogoCirkit DesignerYour all-in-one circuit design IDE Launch Cirkit Designer App

ESP32-S3 Based Smart Lock with Keypad and LCD Display

View and Edit Project In Cirkit DesignerImage of ESP32-S3 Based Smart Lock with Keypad and LCD Display

Circuit Documentation

Summary

This circuit is designed to create a secure locking mechanism using a keypad, an LCD display, and a servo motor controlled by an ESP32-S3 microcontroller. The user can enter a code via the keypad to lock or unlock the mechanism, with feedback provided on the LCD display.

Component List

1. 4x4 Keypad

 

2. 16x2 I2C LCD

 

3. Servo

 

4. ESP32-S3 (beta)

 

Wiring Details

4x4 Keypad

 

16x2 I2C LCD

 

Servo

 

Documented Code

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <ESP32Servo.h>

// ========= Pin configuration (ESP32-S3) =========
#define I2C_SDA 21
#define I2C_SCL 20

// Keypad pins: order must be {R1, R2, R3, R4} and {C1, C2, C3, C4}
const byte ROWS = 4;
const byte COLS = 4;
byte rowPins[ROWS] = {16, 17, 18, 8}; // R1, R2, R3, R4
byte colPins[COLS] = {5, 6, 7, 4};    // C1, C2, C3, C4

// Servo
const int servoPin = 15;              // Any PWM-capable GPIO

// ========= LCD =========
LiquidCrystal_I2C lcd(0x27, 16, 2);

// ========= Keypad map =========
char keys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

// ========= Servo =========
Servo lockServo;

// ========= State =========
String enteredCode = "";
String storedCode  = "";
bool isLocked = false;

void setup() {
  // I2C init on chosen pins
  Wire.begin(I2C_SDA, I2C_SCL);

  // LCD init
  lcd.init();       // LiquidCrystal_I2C typically uses init() on ESP32
  lcd.backlight();

  // Servo init (set safe pulse range for most hobby servos)
  // 500–2500 us gives full sweep for many servos; adjust if needed
  ESP32PWM::allocateTimer(0);
  ESP32PWM::allocateTimer(1);
  ESP32PWM::allocateTimer(2);
  ESP32PWM::allocateTimer(3);
  lockServo.setPeriodHertz(50); // 50 Hz for servos
  lockServo.attach(servoPin, 500, 2500);
  lockServo.write(0); // unlocked position

  // Initial LCD prompt
  lcd.setCursor(0, 0);
  lcd.print("Code to Lock:");
}

void loop() {
  char key = keypad.getKey();

  if (key) {
    if (key == '#') {
      if (!isLocked) {
        if (enteredCode.length() == 4) {
          storedCode = enteredCode;
          lockSafe();
        } else {
          displayError("Enter 4 digits", 0);
        }
      } else {
        if (enteredCode == storedCode) {
          unlockSafe();
        } else {
          displayError("Wrong Code", 1);
        }
      }
      enteredCode = "";
      // Clear masked digits on line 1
      lcd.setCursor(0, 1);
      lcd.print("                ");
    } else if (key >= '0' && key <= '9') {
      if (enteredCode.length() < 4) {
        enteredCode += key;
        lcd.setCursor(enteredCode.length() - 1, 1);
        lcd.print('*');
      }
    }
  }
}

void lockSafe() {
  isLocked = true;
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Locking Safe...");

  for (int pos = 0; pos <= 180; pos += 1) {
    lockServo.write(pos);
    delay(15);
  }

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Safe Locked");
  delay(2000);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Code to Unlock");
}

void unlockSafe() {
  isLocked = false;
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Unlocking Safe...");

  for (int pos = 180; pos >= 0; pos -= 1) {
    lockServo.write(pos);
    delay(15);
  }

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Safe Unlocked");
  delay(2000);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Code to Lock:");
}

void displayError(String message, int code) {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(message);
  delay(3000);
  lcd.clear();
  lcd.setCursor(0, 0);
  if (code == 0) {
    lcd.print("Code to Lock:");
  } else {
    lcd.print("Code to Unlock");
  }
}

This documentation provides a comprehensive overview of the circuit, detailing each component, its purpose, wiring connections, and the embedded code that drives the functionality of the system.