Skip to main content

Password Door Lock Using Arduino

Password Door Lock with Solenoid | SimpleCircuits
Security & Access Control

Password
Door Lock
with Solenoid

A real, relay-controlled solenoid door lock using Arduino UNO, 4×4 keypad, I²C LCD, and a 7.4V Li-ion + MT3608 boost converter. Three-attempt lockout, auto-relock, animated LCD feedback.

4×4Keypad
12VSolenoid
3Max Attempts
10sAuto-Relock
10sLockout
Password Door Lock with Solenoid Finished Build

System Overview

How the System Works

The user enters a password on the keypad. Arduino compares it against the stored password using the Password library. On match, the relay de-energises to release the solenoid lock. Three wrong attempts trigger a 10-second lockout with alarm buzzer. Correct entry gives a 10-second unlock window before auto-relock.

01

Input

User presses digits on the 4×4 keypad. Each keypress shows * on LCD row 1.

02

Verify

Press D to submit. Password library compares entry to stored hash.

03

Actuate

Relay pin goes LOW → solenoid releases → door unlocks physically.

04

Auto-Relock

After 10 s countdown on LCD, relay returns HIGH and door locks again.

✓ Correct Password
  • 3 happy beeps from buzzer
  • Relay → LOW (solenoid opens)
  • LCD: "ACCESS GRANTED — DOOR OPEN"
  • Countdown 10 s then auto-relock
  • LCD: "DOOR LOCKED — See you soon!"
✕ Wrong Password
  • Buzzer beeps for 3 seconds
  • Relay stays HIGH (locked)
  • LCD: "ACCESS DENIED — Attempts Left: N"
  • After 3 failures: 10 s lockout + alarm
  • LCD shows live countdown during lockout

Bill of Materials

Components Required

Eight components. The MT3608 boost converter is key — it steps the 7.4V Li-ion up to 12V needed by the solenoid lock.

ComponentPurposeBuy
Arduino UNO Main controller Buy Now
MT3608 Boost Converter 7.4V → 12V for solenoid Buy Now
16×2 LCD with I2C SDA → A4, SCL → A5 Buy Now
4×4 Keypad Pins D2–D9 Buy Now
5V Relay Module Controls solenoid on D10 Buy Now
Solenoid Lock 12V electromagnetic latch Buy Now
7.4V Li-ion Battery Powers MT3608 + Arduino Buy Now
Jumper Wires M-M, M-F assortment Buy Now

Wiring Reference

Pin Connections

Every wire in one place. The keypad occupies D2–D9, leaving D10 and D11 for relay and buzzer. The LCD uses the I²C bus on A4/A5 — no extra pins consumed.

ComponentComponent PinArduino PinNotes
4×4 KeypadRow 1–4D2, D3, D4, D5Row pins in order
4×4 KeypadCol 1–4D6, D7, D8, D9Column pins in order
16×2 LCD (I²C)SDAA4I²C Data, addr 0x27
16×2 LCD (I²C)SCLA5I²C Clock
16×2 LCD (I²C)VCC5VArduino 5V rail
16×2 LCD (I²C)GNDGNDCommon ground
5V Relay ModuleIN / SignalD10HIGH = locked, LOW = open
5V Relay ModuleVCC5VArduino 5V rail
5V Relay ModuleGNDGNDCommon ground
Active Buzzer+ (Positive)D11Active buzzer, 5V logic
Active Buzzer– (Negative)GNDCommon ground
MT3608 BoostIN+7.4V Bat+Battery positive
MT3608 BoostIN–GND (common)Common ground rail
MT3608 BoostOUT+ (12V)Relay COM12V to relay common terminal
Solenoid Lock+ WireRelay NORelay Normally Open
Solenoid Lock– WireGND (common)Common ground rail
Arduino UNOVIN7.4V Bat+Or use 5V from USB + separate 12V for solenoid
⚠️

Important: Set the MT3608 output to exactly 12V using the trim pot and a multimeter before connecting the solenoid. All grounds must share a common rail — Arduino GND, MT3608 IN–, and solenoid GND must all be joined together.


Controls

Keypad Key Functions

Only three special keys. All other keys (0–9, A, B, #) act as password characters.

D

Enter / Submit

Submits the entered password for verification.

C

Clear / Reset

Wipes all entered digits and returns to the entry screen.

*

Backspace

Deletes the last digit entered. Gives a short beep.

0–9

Password Digits

Each press appends a character. Shown as * on the LCD.


Build Guide

Assembly Steps

01

Set MT3608 Output Voltage

Connect 7.4V battery to MT3608 input. Use a multimeter on the output. Trim the onboard pot until output reads exactly 12V. Do this before wiring the solenoid.

02

Wire the Keypad

Connect keypad row pins R1–R4 to Arduino D2–D5. Column pins C1–C4 to D6–D9. Match the physical order on your keypad module.

03

Connect the I²C LCD

VCC → 5V, GND → GND, SDA → A4, SCL → A5. Default I²C address is 0x27. If display is blank, try 0x3F in the code.

04

Wire the Relay Module

Relay IN → D10, VCC → 5V, GND → GND. Connect MT3608 12V output to relay COM terminal. Solenoid + wire to relay NO (Normally Open) terminal.

05

Connect the Buzzer

Active buzzer positive → D11, negative → GND. Ensure it is an active buzzer (not passive) — it beeps with just a HIGH/LOW signal.

06

Common Ground Rail

Join Arduino GND, MT3608 IN–, relay GND, buzzer GND, and solenoid – wire all to the same ground rail. This is critical for proper operation.

07

Install Libraries & Upload Code

Install: Keypad (Mark Stanley), LiquidCrystal_I2C (Frank de Brabander), Password (Justin Shaw). Change the password string and PASSWORD_LEN in the code, then upload.

08

Power On & Test

Watch the welcome sequence on LCD. Enter your password and press D. Test wrong attempts to verify lockout. Confirm solenoid clicks on correct entry.


Demo

Full Tutorial Video

Complete wiring walkthrough, LCD animations, lockout demonstration, and solenoid operation in real-time.

🎥

Watch for exact wire routing — especially how the 12V solenoid power path runs through the relay. The video also shows MT3608 voltage adjustment and LCD I²C address troubleshooting.


Firmware

Arduino Code

Change the password inside Password("1234") and update PASSWORD_LEN to match. Supports 4–8 digit passwords.

password_door_lock.ino — Arduino C++
/*
 * ========================================
 *   PASSWORD DOOR LOCK — SIMPLE CIRCUITS
 * ========================================
 * Components:
 *   - Arduino Uno
 *   - 4x4 Keypad       → D2 to D9
 *   - 16x2 LCD I2C     → A4 (SDA), A5 (SCL)
 *   - Relay Module      → D10 (HIGH=locked, LOW=open)
 *   - Active Buzzer     → D11
 *   - 7.4V Li-ion + MT3608 → 12V Solenoid
 *
 * Libraries needed:
 *   - Keypad            (by Mark Stanley)
 *   - LiquidCrystal_I2C (by Frank de Brabander)
 *   - Password          (by Justin Shaw)
 *
 * Keys:
 *   D = Enter / Submit
 *   C = Clear / Reset
 *   * = Backspace
 * ========================================
 */

#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
#include <Password.h>

// ─── PINS ───────────────────────────────────────────
#define RELAY_PIN   10
#define BUZZER_PIN  11

// ═══════════════════════════════════════════════════
//   PASSWORD  ← Change here
// ═══════════════════════════════════════════════════
Password   password     = Password("1234");
const byte PASSWORD_LEN = 4;   // match length above (4–8)

// ─── SETTINGS ───────────────────────────────────────
const int  MAX_ATTEMPTS  = 3;
const long LOCKOUT_MS    = 10000;  // 10 sec lockout
const long UNLOCK_MS     = 10000;  // 10 sec auto-relock
const int  WRONG_BEEP_MS = 160;

// ─── STATE ──────────────────────────────────────────
byte currentLen    = 0;
int  wrongAttempts = 0;
bool isLockedOut   = false;
long lockoutStart  = 0;

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

// ─── LCD ────────────────────────────────────────────
LiquidCrystal_I2C lcd(0x27, 16, 2);  // try 0x3F if blank

// ─── CUSTOM LCD CHARACTERS ──────────────────────────
byte lockChar[8]   = {0b01110,0b10001,0b10001,0b11111,0b11011,0b11011,0b11111,0b00000};
byte unlockChar[8] = {0b01110,0b10000,0b10000,0b11111,0b11011,0b11011,0b11111,0b00000};
byte noteChar[8]   = {0b01111,0b01001,0b01001,0b01001,0b11001,0b11001,0b01110,0b00000};
byte starChar[8]   = {0b00100,0b10101,0b01110,0b11111,0b01110,0b10101,0b00100,0b00000};
byte tickChar[8]   = {0b00000,0b00001,0b00011,0b10110,0b11100,0b01000,0b00000,0b00000};

// ─── HELPERS ────────────────────────────────────────
int centerCol(int textLen) {
  int col = (16 - textLen) / 2;
  return (col < 0) ? 0 : col;
}

void printCenter(int row, String text) {
  lcd.setCursor(0, row);
  lcd.print("                ");
  lcd.setCursor(centerCol(text.length()), row);
  lcd.print(text);
}

int pwStartCol() {
  int width = PASSWORD_LEN * 2 - 1;
  return centerCol(width);
}

void drawPasswordRow() {
  int col = pwStartCol();
  lcd.setCursor(0, 1);
  lcd.print("                ");
  for (byte i = 0; i < PASSWORD_LEN; i++) {
    lcd.setCursor(col + i * 2, 1);
    lcd.print(i < currentLen ? '*' : '_');
  }
}

// ═══════════════════════════════════════════════════
//   SETUP
// ═══════════════════════════════════════════════════
void setup() {
  pinMode(RELAY_PIN,  OUTPUT);
  pinMode(BUZZER_PIN, OUTPUT);
  digitalWrite(RELAY_PIN,  HIGH);  // HIGH = locked
  digitalWrite(BUZZER_PIN, LOW);

  lcd.init();
  lcd.backlight();
  lcd.createChar(0, lockChar);
  lcd.createChar(1, unlockChar);
  lcd.createChar(2, noteChar);
  lcd.createChar(3, starChar);
  lcd.createChar(4, tickChar);

  welcomeSequence();
  showEnterPassword();
}

// ═══════════════════════════════════════════════════
//   LOOP
// ═══════════════════════════════════════════════════
void loop() {
  if (isLockedOut) {
    long elapsed = millis() - lockoutStart;
    if (elapsed >= LOCKOUT_MS) {
      isLockedOut   = false;
      wrongAttempts = 0;
      resetPW();
      showEnterPassword();
    } else {
      int s = (LOCKOUT_MS - elapsed) / 1000 + 1;
      lcd.setCursor(0, 1);
      String line = "  Wait: " + String(s) + "s       ";
      lcd.print(line.substring(0, 16));
    }
    return;
  }

  char key = keypad.getKey();
  if (key == NO_KEY) return;
  delay(60);

  if      (key == 'C') { resetPW(); showEnterPassword(); }
  else if (key == '*') { if (currentLen > 0) { currentLen--; buzzOnce(60); drawPasswordRow(); } }
  else if (key == 'D') { if (currentLen == 0) return; checkPassword(); }
  else {
    if (currentLen < PASSWORD_LEN) {
      password.append(key);
      currentLen++;
      buzzOnce(160);
      drawPasswordRow();
    }
  }
}

// ═══════════════════════════════════════════════════
//   CHECK / GRANTED / DENIED
// ═══════════════════════════════════════════════════
void checkPassword() {
  if (password.evaluate()) accessGranted();
  else accessDenied();
}

void accessGranted() {
  wrongAttempts = 0;
  int col = pwStartCol();
  for (byte i = currentLen; i < PASSWORD_LEN; i++) {
    lcd.setCursor(col + i * 2, 1); lcd.print('*'); buzzOnce(50); delay(60);
  }
  for (int f = 0; f < 3; f++) {
    lcd.setCursor(0, 1); lcd.print("                "); delay(120);
    for (byte i = 0; i < PASSWORD_LEN; i++) { lcd.setCursor(col + i * 2, 1); lcd.print('*'); }
    delay(120);
  }
  lcd.clear();
  lcd.setCursor(0, 0); lcd.write(byte(1)); lcd.print(" ACCESS GRANTED");
  lcd.setCursor(3, 1); lcd.write(byte(4)); lcd.print(" DOOR OPEN "); lcd.write(byte(4));
  buzzOnce(100); delay(80); buzzOnce(100); delay(80); buzzOnce(300);
  digitalWrite(RELAY_PIN, LOW);
  for (int s = 10; s >= 1; s--) {
    String line = "Locking in: " + String(s) + "s";
    lcd.setCursor(0, 1); lcd.print("                ");
    lcd.setCursor(centerCol(line.length()), 1); lcd.print(line); delay(1000);
  }
  digitalWrite(RELAY_PIN, HIGH);
  lcd.clear();
  lcd.setCursor(0, 0); lcd.write(byte(0)); lcd.print("  DOOR LOCKED  "); lcd.write(byte(0));
  lcd.setCursor(centerCol(13), 1); lcd.print("See you soon!");
  buzzOnce(200); delay(1500);
  resetPW(); showEnterPassword();
}

void accessDenied() {
  wrongAttempts++;
  int left = MAX_ATTEMPTS - wrongAttempts;
  for (int i = 0; i < 4; i++) {
    lcd.clear(); lcd.setCursor(centerCol(14), 0); lcd.write(byte(0)); lcd.print(" WRONG!"); delay(90);
    lcd.clear(); delay(70);
  }
  lcd.clear();
  lcd.setCursor(0, 0); lcd.write(byte(0)); lcd.print("  ACCESS DENIED ");
  lcd.setCursor(0, 1);
  if (left > 0) { String line = "Attempts Left: " + String(left); lcd.setCursor(centerCol(line.length()), 1); lcd.print(line); }
  else { lcd.setCursor(centerCol(13), 1); lcd.print("Last Attempt!"); }
  long beepStart = millis();
  while (millis() - beepStart < 3000) { buzzOnce(WRONG_BEEP_MS); delay(WRONG_BEEP_MS); }
  if (wrongAttempts >= MAX_ATTEMPTS) {
    isLockedOut = true; lockoutStart = millis();
    lcd.clear();
    lcd.setCursor(0, 0); lcd.print("!! LOCKED OUT !!");
    lcd.setCursor(centerCol(15), 1); lcd.print("Wait 10 seconds");
    long alarmStart = millis();
    while (millis() - alarmStart < 3000) { buzzOnce(150); delay(100); }
    resetPW(); return;
  }
  resetPW(); showEnterPassword();
}

void showEnterPassword() {
  lcd.clear();
  lcd.setCursor(0, 0); lcd.write(byte(0)); lcd.print(" Enter Password ");
  drawPasswordRow();
}

void welcomeSequence() {
  lcd.clear();
  lcd.setCursor(0, 0); lcd.write(byte(2)); lcd.print("  SUBSCRIBE  "); lcd.write(byte(2));
  for (int i = 15; i >= 1; i--) {
    lcd.setCursor(0, 1); lcd.print("                ");
    lcd.setCursor(i, 1);
    String s = "SIMPLE CIRCUITS";
    int cv = 16 - i; if (cv > (int)s.length()) cv = s.length();
    lcd.print(s.substring(0, cv)); delay(50);
  }
  delay(300);
  buzzOnce(80); delay(100); buzzOnce(80); delay(100); buzzOnce(160); delay(300);
  for (int i = 0; i < 3; i++) {
    lcd.clear();
    lcd.setCursor(0,0); lcd.write(byte(3)); lcd.setCursor(15,0); lcd.write(byte(3));
    lcd.setCursor(centerCol(9), 0); lcd.print("SUBSCRIBE"); delay(130);
    lcd.clear();
    lcd.setCursor(1,0); lcd.write(byte(3)); lcd.setCursor(14,0); lcd.write(byte(3));
    lcd.setCursor(centerCol(10), 0); lcd.print("SUBSCRIBE!"); delay(130);
  }
  lcd.clear(); lcd.setCursor(centerCol(10), 0); lcd.print("SUBSCRIBE!"); lcd.setCursor(1, 1); lcd.print("SIMPLE CIRCUITS");
  buzzOnce(400); delay(800);
  lcd.clear(); lcd.setCursor(centerCol(9), 0); lcd.print("SUBSCRIBE");
  String brand = "SIMPLE CIRCUITS";
  for (int i = 0; i < (int)brand.length(); i++) { lcd.setCursor(1 + i, 1); lcd.print(brand[i]); buzzOnce(30); delay(80); }
  delay(500);
  for (int i = 0; i < 3; i++) { lcd.noBacklight(); delay(150); lcd.backlight(); delay(150); }
  buzzOnce(400); delay(400);
}

void resetPW() { password.reset(); currentLen = 0; }

void buzzOnce(int ms) { digitalWrite(BUZZER_PIN, HIGH); delay(ms); digitalWrite(BUZZER_PIN, LOW); delay(10); }

setup()

Relay starts HIGH (locked). Custom LCD characters loaded. Welcome sequence plays with typewriter animation and backlight flash.

loop()

Handles lockout countdown live on LCD. Polls keypad for D (submit), C (clear), * (backspace), or digit input with asterisk display.

accessGranted()

Fills and flashes asterisks, relay LOW for 10 s countdown, auto-relocks with lock icon and goodbye message.

accessDenied()

Shake animation on LCD, 3 s buzzer alarm, attempt counter. After 3 failures: 10 s siren lockout with live timer.

welcomeSequence()

Slide-in text, star bounce animation, typewriter brand reveal, backlight flash — runs once on boot.

To Change Password

Edit the string in Password("1234") and set PASSWORD_LEN to match. Supports 4–8 digits.


Design Your Own PCBs with Altium

For designing professional PCBs — like a custom PCBA for this door lock with all components on one board — I use Altium. It makes electronics design faster, cleaner, and production-ready.

Students get free access via Altium Student Lab — sign up with your university email for step-by-step PCB courses and industry certifications.

👉 Start designing with Altium →

Diamond & Onyx Theme · Designed for makers & builders

Comments

Popular posts from this blog

Solar Tracking System

Dual-Axis Solar Tracking System | Arduino SimpleCircuits Arduino Solar DIY Renewable Energy Project Dual-Axis Solar Tracking System Build a high-performance solar tracker that follows the sun in real-time. Four LDR sensors, an Arduino UNO, and two servo motors — boosting energy capture by up to 40% versus fixed mounts. 40% More Efficient 4 LDR Sensors 2 Servo Axes <300mA Power Draw Finished Build System Overview How the System Works The tracker reads the sky through four LDR sensors placed around the panel, computes intensity deltas, and drives two SG90 servos in a real-time closed loop — keeping the panel perpendicular to sunlight from sunrise to sunset. ...

Arduino Code

 //define Pins #include <Servo.h> Servo servo; int trigPin = 11; int echoPin = 12; // defines variables long duration; int distance; void setup()  {   servo.attach(13);   servo.write(180);  delay(2000);    // Sets the trigPin as an Output pinMode(trigPin, OUTPUT); // Sets the echoPin as an Input  pinMode(echoPin, INPUT); } void loop()  { // Clears the trigPin digitalWrite(trigPin, LOW); delayMicroseconds(2); // Sets the trigPin on HIGH state for 10 micro seconds digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); // Reads the echoPin, returns the sound wave travel time in microseconds duration = pulseIn(echoPin, HIGH); // Calculating the distance distance= duration*0.034/2; // Prints the distance on the Serial Monitor Serial.print("Distance: "); Serial.println(distance); if ( distance <= 25   ) // Change Distance according to Ultrasonic Sensor Placement  { servo.write(180); delay(3000); ...

Arduino Code Car Parking System

 // Created by Simple Circuits  #include <Wire.h>  #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27,16,2);    #include <Servo.h>  Servo myservo; int IR1 = 2; int IR2 = 3; int Slot = 4;           //Total number of parking Slots int flag1 = 0; int flag2 = 0; void setup() {   Serial.begin(9600);      lcd.init(); //initialize the lcd     lcd.backlight(); //open the backlight     pinMode(IR1, INPUT); pinMode(IR2, INPUT);    myservo.attach(4); myservo.write(100); lcd.setCursor (0,0); lcd.print("     ARDUINO    "); lcd.setCursor (0,1); lcd.print(" PARKING SYSTEM "); delay (2000); lcd.clear();   } void loop(){  if(digitalRead (IR1) == LOW && flag1==0){ if(Slot>0){flag1=1; if(flag2==0){myservo.write(0); Slot = Slot-1;} }else{ lcd.setCursor (0,0); lcd.print("    SORRY :(    ");   lc...