Copy the code by clicking the “Copy Icon” situated in the righ upper corner of the code block.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <Servo.h>
#include <EEPROM.h>
#include <Adafruit_NeoPixel.h>
#include <DFRobotDFPlayerMini.h>
#include <SoftwareSerial.h>
#define maxPasswordLength 4
#define buzzerPin 12
#define servoPin A1
#define ledPin 13 // Use A0 (D14) for LED strip output
#define numPixels 1
SoftwareSerial mySerial(10, 11); // RX, TX for DFPlayer Mini
DFRobotDFPlayerMini dfPlayer;
LiquidCrystal_I2C lcd(0x27, 20, 4);
Servo myServo;
Adafruit_NeoPixel strip = Adafruit_NeoPixel(numPixels, ledPin, NEO_GRB + NEO_KHZ800);
// Keypad setup
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] = {9, 8, 7, 6}; // Connect to the row pinouts of the keypad
byte colPins[COLS] = {5, 4, 3, 2}; // Connect to the column pinouts of the keypad
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
String currentPassword = "1234";
String inputPassword = "";
boolean settingPassword = false;
boolean confirmingPassword = false;
void setup() {
pinMode(buzzerPin, OUTPUT);
pinMode(ledPin, OUTPUT); // Set A0 as an output pin
myServo.attach(servoPin);
strip.begin();
strip.show();
lcd.init();
lcd.backlight();
mySerial.begin(9600);
if (!dfPlayer.begin(mySerial)) {
lcd.setCursor(0, 0);
lcd.print("DFPlayer Error");
while (true);
}
dfPlayer.volume(30); // Set volume to a high level
loadPassword();
}
void loop() {
char key = keypad.getKey(); // Get the key pressed on the keypad
if (key == 'B' && !settingPassword && !confirmingPassword) { // Press 'B' to set a new password
settingPassword = true;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter Old Pass:");
inputPassword = "";
return;
}
if (settingPassword) {
if (key == 'A') { // Press 'A' to confirm old password
if (inputPassword == currentPassword) {
confirmingPassword = true;
settingPassword = false;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter New Pass:");
inputPassword = "";
} else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Wrong Old Pass");
blinkLED(255, 0, 0, 3, 200);
beepBuzzer(3, 200);
playAudio(1); // Play "Wrong Password" audio
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter Old Pass:");
inputPassword = "";
}
return;
}
if (key == 'C') { // Press 'C' to clear input
inputPassword = "";
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter Old Pass:");
} else if (key == 'D') { // Press 'D' to delete the last character
if (inputPassword.length() > 0) {
inputPassword.remove(inputPassword.length() - 1);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter Old Pass:");
lcd.setCursor(0, 1);
lcd.print(inputPassword);
}
} else if (key != NO_KEY) { // Entering the old password
if (inputPassword.length() < maxPasswordLength) {
inputPassword += key;
lcd.setCursor(0, 1);
lcd.print(inputPassword);
}
}
return;
}
if (confirmingPassword) {
if (key == 'A') { // Press 'A' to confirm the new password
if (inputPassword.length() == maxPasswordLength) {
savePassword(inputPassword);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Password Saved");
blinkLED(0, 255, 0, 3, 200);
beepBuzzer(3, 200);
playAudio(2); // Play "Password Saved" audio
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter Password:");
confirmingPassword = false;
} else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Invalid Length");
blinkLED(255, 0, 0, 3, 200);
beepBuzzer(3, 200);
playAudio(3); // Play "Invalid Length" audio
delay(1000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter New Pass:");
lcd.setCursor(0, 1);
lcd.print(inputPassword);
}
return;
}
if (key == 'C') { // Press 'C' to clear the new password input
inputPassword = "";
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter New Pass:");
} else if (key == 'D') { // Press 'D' to delete the last character of the new password
if (inputPassword.length() > 0) {
inputPassword.remove(inputPassword.length() - 1);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter New Pass:");
lcd.setCursor(0, 1);
lcd.print(inputPassword);
}
} else if (key != NO_KEY) { // Entering the new password
if (inputPassword.length() < maxPasswordLength) {
inputPassword += key;
lcd.setCursor(0, 1);
lcd.print(inputPassword);
}
}
return;
}
// Handle normal password entry
if (key == 'A') { // Press 'A' to confirm the password
checkPassword();
} else if (key == 'C') { // Press 'C' to clear the input
inputPassword = "";
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter Password:");
} else if (key == 'D') { // Press 'D' to delete the last character
if (inputPassword.length() > 0) {
inputPassword.remove(inputPassword.length() - 1);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter Password:");
lcd.setCursor(0, 1);
lcd.print(inputPassword);
}
} else if (key != NO_KEY) { // Entering the password
if (inputPassword.length() < maxPasswordLength) {
inputPassword += key;
lcd.setCursor(0, 1);
lcd.print(inputPassword);
}
}
}
void checkPassword() {
if (inputPassword == currentPassword) {
myServo.write(90); // Unlock position
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Door Unlocked");
blinkLED(0, 255, 0, 3, 200);
beepBuzzer(3, 200);
playAudio(4); // Play "Door Unlocked" audio
delay(5000); // Keep the door unlocked for 5 seconds
myServo.write(0); // Lock position
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Re-Locked");
playAudio(5); // Play "Re-Locked" audio
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter Password:");
} else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Wrong Password");
blinkLED(255, 0, 0, 3, 200);
beepBuzzer(3, 200);
playAudio(1); // Play "Wrong Password" audio
delay(1000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter Password:");
}
inputPassword = ""; // Clear the input after checking
}
void loadPassword() {
char pwd[maxPasswordLength + 1];
for (int i = 0; i < maxPasswordLength; i++) {
pwd[i] = EEPROM.read(i);
}
pwd[maxPasswordLength] = '\0';
currentPassword = String(pwd);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Password Loaded");
delay(1000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter Password:");
}
void savePassword(String newPassword) {
for (int i = 0; i < maxPasswordLength; i++) {
EEPROM.write(i, newPassword[i]);
}
currentPassword = newPassword;
}
void blinkLED(int red, int green, int blue, int times, int delayTime) {
for (int i = 0; i < times; i++) {
strip.setPixelColor(0, strip.Color(red, green, blue));
strip.show();
delay(delayTime);
strip.setPixelColor(0, strip.Color(0, 0, 0));
strip.show();
delay(delayTime);
}
}
void beepBuzzer(int times, int delayTime) {
for (int i = 0; i < times; i++) {
digitalWrite(buzzerPin, HIGH);
delay(delayTime);
digitalWrite(buzzerPin, LOW);
delay(delayTime);
}
}
void playAudio(int trackNumber) {
dfPlayer.play(trackNumber);
}
1. Library Inclusions
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <Servo.h>
#include <EEPROM.h>
#include <Adafruit_NeoPixel.h>
#include <DFRobotDFPlayerMini.h>
#include <SoftwareSerial.h>
- Wire.h: I2C communication (used by the LCD).
- LiquidCrystal_I2C.h: Controls the 20×4 LCD over I²C at address
0x27
. - Keypad.h: Reads button presses from a 4×4 matrix keypad.
- Servo.h: Drives the servo motor that physically locks/unlocks the door.
- EEPROM.h: Stores and retrieves the 4-digit password in non-volatile memory.
- Adafruit_NeoPixel.h: Controls the RGB LED strip (used here as a single-pixel indicator).
- DFRobotDFPlayerMini.h + SoftwareSerial.h: Interface and communicate with the DFPlayer Mini MP3 module for audio feedback.
2. Configuration Constants & Pins
#define maxPasswordLength 4
#define buzzerPin 12
#define servoPin A1
#define ledPin 13
#define numPixels 1
- maxPasswordLength: Password is exactly 4 digits.
- buzzerPin: Piezo buzzer output.
- servoPin: Analog pin A1 driving the lock servo.
- ledPin: Pin for the NeoPixel data input.
- numPixels: Only one RGB LED pixel in the strip.
3. Hardware Object Instantiations
SoftwareSerial mySerial(10, 11); // RX, TX for DFPlayer
DFRobotDFPlayerMini dfPlayer; // DFPlayer instance
LiquidCrystal_I2C lcd(0x27, 20, 4); // 20×4 I2C LCD
Servo myServo; // Door servo
Adafruit_NeoPixel strip(numPixels, ledPin, NEO_GRB + NEO_KHZ800);
- SoftwareSerial mySerial(10, 11): Creates a serial link to DFPlayer on pins 10(RX)/11(TX).
- dfPlayer: Controls audio playback (error beeps, confirmations).
- lcd: Text display to prompt user and show status.
- myServo: Moves between locked (0°) and unlocked (90°).
- strip: One-pixel NeoPixel for colored feedback (red/green).
4. Keypad Definition
const byte ROWS = 4, COLS = 4;
char keys[ROWS][COLS] = {
{'1','2','3','A'}, {'4','5','6','B'},
{'7','8','9','C'}, {'*','0','#','D'}
};
byte rowPins[ROWS] = {9,8,7,6}, colPins[COLS] = {5,4,3,2};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
- Defines a 4×4 layout.
- Rows on pins 9–6, columns on 5–2.
- Keys
A
,B
,C
,D
serve as “confirm,” “set new password,” “clear,” and “delete” controls.
5. Password State Variables
String currentPassword = "1234";
String inputPassword = "";
boolean settingPassword = false;
boolean confirmingPassword = false;
- currentPassword: Holds the active 4-digit code (loaded from EEPROM on startup).
- inputPassword: Accumulates user keystrokes.
- settingPassword / confirmingPassword: Track whether the sketch is in “change password” mode.
6. setup()
void setup() {
pinMode(buzzerPin, OUTPUT);
pinMode(ledPin, OUTPUT);
myServo.attach(servoPin);
strip.begin(); strip.show();
lcd.init(); lcd.backlight();
mySerial.begin(9600);
if (!dfPlayer.begin(mySerial)) { … } // Halt on DFPlayer error
dfPlayer.volume(30);
loadPassword(); // Read the saved password from EEPROM
}
- Pin modes for buzzer and LED.
- Attach servo and initialize NeoPixel.
- Initialize the LCD and DFPlayer audio module.
- Set volume on DFPlayer.
- Call
loadPassword()
to fetch the last-saved code and prompt “Enter Password:”.
7. loop()
: Main Input Handler
- Read one key:
char key = keypad.getKey();
- If user pressed ‘B’ (start password‐change), prompt “Enter Old Pass:” and set
settingPassword = true
. - If in
settingPassword
:- ‘A’ → confirm old code, compare to
currentPassword
; on match, switch toconfirmingPassword
(enter new pass), else show error feedback. - ‘C’ → clear entry.
- ‘D’ → backspace (delete last digit).
- Any digit → append to
inputPassword
(up to 4 digits) and display.
- ‘A’ → confirm old code, compare to
- If in
confirmingPassword
(entering new pass):- ‘A’ → confirm new code; if length == 4 then
savePassword()
, feedback and return to normal mode; else show “Invalid Length.” - ‘C’/‘D’/digits** behave as clear, backspace, or append, similar to above.
- ‘A’ → confirm new code; if length == 4 then
- Normal password entry:
- ‘A’ → call
checkPassword()
(unlock on match, error on mismatch). - ‘C’ → clear entry.
- ‘D’ → delete last digit.
- Digit → append to
inputPassword
.
- ‘A’ → call
8. checkPassword()
void checkPassword() {
if (inputPassword == currentPassword) {
// Unlock sequence
myServo.write(90);
lcd.print("Door Unlocked");
blinkLED(green), beepBuzzer, playAudio(track 4);
delay(5000);
myServo.write(0);
lcd.print("Re-Locked");
playAudio(track 5);
} else {
// Wrong password feedback
lcd.print("Wrong Password");
blinkLED(red), beepBuzzer, playAudio(track 1);
}
inputPassword = "";
lcd.print("Enter Password:");
}
- Correct code:
- Rotate servo to 90° to unlock.
- Green LED blinks, buzzer beeps, plays “Unlocked” audio.
- Wait 5 s, relock (servo → 0°), play “Re-Locked” audio.
- Incorrect code: Red blink + buzzer + “Wrong Password” audio.
- Always reset
inputPassword
and prompt again.
9. EEPROM Persistence: loadPassword()
& savePassword()
void loadPassword() {
for (int i=0; i<4; i++) pwd[i] = EEPROM.read(i);
currentPassword = String(pwd);
lcd.print("Password Loaded");
delay(1000);
lcd.print("Enter Password:");
}
void savePassword(String newPassword) {
for (int i=0; i<4; i++) EEPROM.write(i, newPassword[i]);
currentPassword = newPassword;
}
- loadPassword(): Reads four bytes from EEPROM addresses 0–3, converts to a
String
, and shows a brief “Password Loaded” message. - savePassword(): Writes each character of the new 4-digit code to EEPROM and updates
currentPassword
.
10. Feedback Helpers
blinkLED(int red, int green, int blue, int times, int delayTime)
Cycles the single NeoPixel on/off in the specified RGB color for the given number of times.
beepBuzzer(int times, int delayTime)
Turns the buzzer on/off rapidly to produce audible beeps.
playAudio(int trackNumber)
Sends the play command to DFPlayer Mini to play pre-loaded MP3 tracks (e.g. “Wrong Password,” “Password Saved,” etc.).
How It All Fits
- Startup: Reads stored password, initializes all peripherals.
- Idle: Prompts “Enter Password:” on LCD.
- User Interaction: Keypad drives all state changes—entering passwords, switching to change-password mode, and confirming actions.
- Visual & Audio: Neopixel, buzzer, and MP3 tracks reinforce success/failure.
- Security: Password is stored in EEPROM so it survives power‐cycles, and the servo physically locks/unlocks a door mechanism.