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]
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);
}
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.
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)
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.
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.