4-Digit Password Lock System Using 4-Digit 7-Segment Display

4-Digit Password Lock System Using 4-Digit 7-Segment Display

HARDWARE REQUIRED:

  • PICUNO Microcontroller board
  • 1 × 5461AS-1 4-Digit 7-Segment Display (Common Cathode)
  • 3 × Push Buttons
  • 2 × 10kΩ resistor (pull-down)
  • 8 × 220Ω resistors (Current limiting for LEDs)
  • Breadboard
  • Jumper wires
  • USB cable

DESCRIPTION:

This project implements a secure 4-digit password lock system using the 5461AS-1 4-digit 7-segment LED display with the PicUNO microcontroller. It allows the user to enter a 4-digit numeric password using just two buttons:
  • One to scroll through digits (0–9) [NEXT Button]
  • One to confirm each digit [OK Button]
After entering all 4 digits, the system verifies the input against a preset password (e.g., 1234). Based on the result, it displays PASS or FAIL on the display. The result remains displayed until the user presses a third reset button to restart the process for a new attempt.

CIRCUIT DIAGRAM:

Circuit Diagram
  • Connect the PICUNO board to the computer using a USB cable.
  • Connect segment pins A to G and DP of display to GPIO 6 to 13 using 220Ω resistors.
  • Connect Digit pins 1,2,3,4 of the display to GPIO 18,19,20,21 respectively.
  • Connect one side of NEXT, OK and RESET buttons to 3.3 V.
  • Connect the other sides of the buttons to GPIO 15, 16, 22 respectively and connect a 10kΩ resistor from each GPIO to GND.

SCHEMATIC:

A → 220Ω → GPIO 6

B → 220Ω → GPIO 7

C → 220Ω → GPIO 8

D → 220Ω → GPIO 9

E → 220Ω → GPIO 10

F → 220Ω → GPIO 11

G → 220Ω → GPIO 12

DP → 220Ω → GPIO 13

Digit 1 → GPIO 18

Digit 2 → GPIO 19

Digit 3 → GPIO 20

Digit 4 → GPIO 21

NEXT Button one side → 3.3 V

Other side → GPIO 15 → 10kΩ → GND

OK Button one side → 3.3 V

Other side → GPIO 16 → 10kΩ → GND

RESET Button one side → 3.3 V

Other side → GPIO 22 → 10kΩ → GND

CODE -- C:

const int segmentPins[] = {6, 7, 8, 9, 10, 11, 12, 13};
const int digitPins[] = {18, 19, 20, 21};
const int scrollBtn = 15;
const int confirmBtn = 16;
const int resetBtn = 22;

int digitsMap[10][7] = {
  {1,1,1,1,1,1,0}, {0,1,1,0,0,0,0}, {1,1,0,1,1,0,1}, {1,1,1,1,0,0,1},
  {0,1,1,0,0,1,1}, {1,0,1,1,0,1,1}, {1,0,1,1,1,1,1}, {1,1,1,0,0,0,0},
  {1,1,1,1,1,1,1}, {1,1,1,1,0,1,1}
};

int currentDigit = 0;
int enteredDigits[4] = {0, 0, 0, 0};
int password[4] = {1, 2, 3, 4};
bool checking = false;
bool resultDisplayed = false;

void setup() {
  for (int i = 0; i < 8; i++) pinMode(segmentPins[i], OUTPUT);
  for (int i = 0; i < 4; i++) pinMode(digitPins[i], OUTPUT);
  pinMode(scrollBtn, INPUT);
  pinMode(confirmBtn, INPUT);
  pinMode(resetBtn, INPUT);
}

void loop() {
  if (digitalRead(resetBtn)) {
    checking = false;
    resultDisplayed = false;
    currentDigit = 0;
    for (int i = 0; i < 4; i++) enteredDigits[i] = 0;
    delay(200);
  }

  if (!checking) {
    if (digitalRead(scrollBtn)) {
      enteredDigits[currentDigit] = (enteredDigits[currentDigit] + 1) % 10;
      delay(200);
    }
    if (digitalRead(confirmBtn)) {
      currentDigit++;
      delay(200);
    }
    if (currentDigit >= 4) {
      checking = true;
      currentDigit = 0;
    }
    displayEntered();
  } else if (!resultDisplayed) {
    bool pass = true;
    for (int i = 0; i < 4; i++) {
      if (enteredDigits[i] != password[i]) pass = false;
    }
    resultDisplayed = true;
    while (true) {
      if (pass) displayPASS();
      else displayFAIL();
      if (digitalRead(resetBtn)) {
        checking = false;
        resultDisplayed = false;
        currentDigit = 0;
        for (int i = 0; i < 4; i++) enteredDigits[i] = 0;
        delay(200);
        break;
      }
    }
  }
}

void displayDigit(int num, int digitIndex) {
  for (int i = 0; i < 7; i++) digitalWrite(segmentPins[i], digitsMap[num][i]);
  digitalWrite(segmentPins[7], LOW);
  digitalWrite(digitPins[digitIndex], LOW);
  delay(2);
  clearSegments();
  digitalWrite(digitPins[digitIndex], HIGH);
}

void displayEntered() {
  for (int i = 0; i < 4; i++) {
    displayDigit(enteredDigits[i], i);
  }
}

void displayPASS() {
  int P[7] = {1,1,0,0,1,1,1};
  int A[7] = {1,1,1,0,1,1,1};
  int S[7] = {1,0,1,1,0,1,1};
  showCustom(P, 0);
  showCustom(A, 1);
  showCustom(S, 2);
  showCustom(S, 3);
}

void displayFAIL() {
  int F[7] = {1,0,0,0,1,1,1};
  int A[7] = {1,1,1,0,1,1,1};
  int I[7] = {0,1,1,0,0,0,0};
  int L[7] = {0,0,0,1,1,1,0};
  showCustom(F, 0);
  showCustom(A, 1);
  showCustom(I, 2);
  showCustom(L, 3);
}

void showCustom(int data[7], int digitIndex) {
  for (int i = 0; i < 7; i++) digitalWrite(segmentPins[i], data[i]);
  digitalWrite(segmentPins[7], LOW);
  digitalWrite(digitPins[digitIndex], LOW);
  delay(2);
  clearSegments();
  digitalWrite(digitPins[digitIndex], HIGH);
}

void clearSegments() {
  for (int i = 0; i < 8; i++) digitalWrite(segmentPins[i], LOW);
}
int digitsMap[10][7] = { ... }; - Contains the 7-segment encoding for digits 0 to 9. Each inner array represents segment ON/OFF states for a number.

int enteredDigits[4] = {0, 0, 0, 0}; - Stores user input digit-by-digit.

int password[4] = {....}; - Holds the correct 4-digit passcode to validate against.

void displayDigit(int num, int digitIndex) { ... } - Turns ON segments for one digit at a time.

void displayEntered() { ... } - Cycles through all 4 digits rapidly (multiplexing).

void displayPASS() { ... }, void displayFAIL() { ... } - These functions show custom characters P-A-S-S or F-A-I-L on the 4-digit display. Each character is built using custom 7-segment patterns.

if (!checking) { ... } else if (!resultDisplayed) { ... } - User scrolls and confirms 4 digits. After 4 digits, system checks the password. Displays result (PASS or FAIL) permanently using while (true) until reset is pressed.

if (digitalRead(resetBtn)) - The reset button allows the user to restart the process. Clears all entered digits, resets flags and allows re-entry.

CODE -- PYTHON:

from machine import Pin
import time

# Segment pins A-G + DP
segmentPins = [Pin(i, Pin.OUT) for i in range(6, 14)]
# Digit select pins
digitPins = [Pin(i, Pin.OUT) for i in range(18, 22)]

# Buttons
scrollBtn = Pin(15, Pin.IN)
confirmBtn = Pin(16, Pin.IN)
resetBtn = Pin(22, Pin.IN)

# Segment map for digits 0–9
digitsMap = [
    [1,1,1,1,1,1,0], [0,1,1,0,0,0,0], [1,1,0,1,1,0,1], [1,1,1,1,0,0,1],
    [0,1,1,0,0,1,1], [1,0,1,1,0,1,1], [1,0,1,1,1,1,1], [1,1,1,0,0,0,0],
    [1,1,1,1,1,1,1], [1,1,1,1,0,1,1]
]

# Custom letters for PASS and FAIL
letters = {
    "P": [1,1,0,0,1,1,1],
    "A": [1,1,1,0,1,1,1],
    "S": [1,0,1,1,0,1,1],
    "F": [1,0,0,0,1,1,1],
    "I": [0,1,1,0,0,0,0],
    "L": [0,0,0,1,1,1,0]
}

# State variables
enteredDigits = [0, 0, 0, 0]
password = [1, 2, 3, 4]
currentDigit = 0
checking = False
resultDisplayed = False
lastScroll = 0
lastConfirm = 0
lastReset = 0

def clearSegments():
    for s in segmentPins:
        s.value(0)

def showDigit(num):
    for i in range(7):
        segmentPins[i].value(digitsMap[num][i])
    segmentPins[7].value(0) # DP OFF

def showCustom(char):
    pattern = letters[char]
    for i in range(7):
        segmentPins[i].value(pattern[i])
    segmentPins[7].value(0)

def displayEntered():
    for i in range(4):
        digitPins[i].value(0)
        showDigit(enteredDigits[i])
        time.sleep_ms(2)
        clearSegments()
        digitPins[i].value(1)

def displayWord(word): # e.g., PASS or FAIL
    for i in range(4):
        digitPins[i].value(0)
        showCustom(word[i])
        time.sleep_ms(2)
        clearSegments()
        digitPins[i].value(1)

def resetState():
    global enteredDigits, currentDigit, checking, resultDisplayed
    enteredDigits = [0, 0, 0, 0]
    currentDigit = 0
    checking = False
    resultDisplayed = False

# Main loop
while True:
    # Handle reset button
    if resetBtn.value() == 1 and lastReset == 0:
        resetState()
        time.sleep_ms(200)
    lastReset = resetBtn.value()

    # If not checking result
    if not checking and not resultDisplayed:
        if scrollBtn.value() == 1 and lastScroll == 0:
            enteredDigits[currentDigit] = (enteredDigits[currentDigit] + 1) % 10
            time.sleep_ms(200)
        lastScroll = scrollBtn.value()

        if confirmBtn.value() == 1 and lastConfirm == 0:
            currentDigit += 1
            if currentDigit >= 4:
                checking = True
            time.sleep_ms(200)
        lastConfirm = confirmBtn.value()

        displayEntered()

    # Check password after all digits entered
    elif checking and not resultDisplayed:
        if enteredDigits == password:
            result = "PASS"
        else:
            result = "FAIL"
        resultDisplayed = True

    # Display result until reset
    if resultDisplayed:
        displayWord(result)
enteredDigits = [0, 0, 0, 0], password = [1, 2, 3, 4] - Stores the user's entered digits and the correct password to check against.

def displayEntered(): - Shows the 4 digits the user is currently entering, using multiplexing (digit-by-digit switching every 2 ms).

def displayWord(word): - Displays a custom 4-letter word by lighting segments for each character (using a segment bitmap for each letter). Keeps showing this until resetBtn is pressed.

def resetState(): - Resets all flags and states. Allows the user to try again after pressing the reset button.

if scrollBtn.value() == 1 and lastScroll == 0: - Implements edge detection: only act on button press, not while held. Ensures clean transitions and avoids accidental repeats.