#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>
// LCD setup
LiquidCrystal_I2C lcd(0x27, 16, 2); // change if your I2C scanner shows different
// Servo setup
Servo lockServo;
int servoPin = 9;
// Buzzer setup
int buzzer = 8;
// RGB LED pins
int redPin = 5;
int greenPin = 3;
int bluePin = 2;
// Password setup
String correctPassword = "1234";
String inputPassword = "";
// Flag for new password entry
bool waitingForNewCode = false;
void setup() {
// Servo attach
lockServo.attach(servoPin);
lockServo.write(0); // locked position
// Buzzer
pinMode(buzzer, OUTPUT);
digitalWrite(buzzer, LOW);
// RGB LED
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
turnOffRGB();
// LCD
lcd.init();
lcd.backlight();
lcd.setCursor(0,0);
lcd.print("Safe Door System");
delay(2000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Enter Code:");
// Serial for Bluetooth / Monitor
Serial.begin(9600);
Serial.println("System Ready. Type 4 characters for password.");
Serial.println("Type R,G,B,Y,C,M to control RGB LED.");
}
void loop() {
recvCode();
// Once 4 chars are entered → check password
if (inputPassword.length() == 4) {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Checking...");
Serial.print("Password entered: ");
Serial.println(inputPassword);
if (!waitingForNewCode) {
// Normal login
if (inputPassword == correctPassword) {
lcd.setCursor(0,1);
lcd.print("Access Granted");
Serial.println("Access Granted");
unlockDoor();
// Ask for new code
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Enter New Code:");
Serial.println("Waiting for new 4-digit code...");
inputPassword = "";
waitingForNewCode = true;
} else {
lcd.setCursor(0,1);
lcd.print("Access Denied");
Serial.println("Access Denied Wrong code.");
alarm();
resetPrompt();
}
} else {
// Saving new code
correctPassword = inputPassword;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("New Code Saved");
Serial.print("New password set: ");
Serial.println(correctPassword);
delay(2000);
lockDoor();
resetPrompt();
waitingForNewCode = false;
}
// Reset after checking
inputPassword = "";
}
// Also check for LED commands separately
recvLEDControl();
}
void recvCode() {
while (Serial.available() > 0) {
char rc = Serial.peek(); // look at next char without removing
// Check if it's a LED command
if (rc == 'R' || rc == 'G' || rc == 'B' || rc == 'Y' || rc == 'C' || rc == 'M') {
recvLEDControl();
return;
}
// Now read normally
rc = Serial.read();
// Ignore newline/carriage return
if (rc == '\n' || rc == '\r') {
return;
}
// Limit input to 4 chars
if (inputPassword.length() < 4) {
inputPassword += rc;
// Show * instead of real digits
lcd.setCursor(0,1);
for (int i = 0; i < inputPassword.length(); i++) {
lcd.print("*");
}
}
}
}
void recvLEDControl() {
if (Serial.available() > 0) {
char cmd = Serial.read();
switch (cmd) {
case 'R': setColor(1,0,0); Serial.println("LED: RED"); break;
case 'G': setColor(0,1,0); Serial.println("LED: GREEN"); break;
case 'B': setColor(0,0,1); Serial.println("LED: BLUE"); break;
case 'Y': setColor(1,1,0); Serial.println("LED: YELLOW"); break;
case 'C': setColor(0,1,1); Serial.println("LED: CYAN"); break;
case 'M': setColor(1,0,1); Serial.println("LED: MAGENTA"); break;
}
}
}
void setColor(bool r, bool g, bool b) {
digitalWrite(redPin, r ? HIGH : LOW);
digitalWrite(greenPin, g ? HIGH : LOW);
digitalWrite(bluePin, b ? HIGH : LOW);
}
void turnOffRGB() {
digitalWrite(redPin, LOW);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, LOW);
}
void unlockDoor() {
Serial.println("Unlocking door...");
lockServo.write(90); // unlock position
delay(2000); // wait while open
}
void lockDoor() {
Serial.println("Locking door...");
lockServo.write(0); // lock position
// make click sound
digitalWrite(buzzer, HIGH);
delay(100);
digitalWrite(buzzer, LOW);
}
void alarm() {
Serial.println("Alarm triggered!");
for (int i = 0; i < 5; i++) {
digitalWrite(buzzer, HIGH);
delay(200);
digitalWrite(buzzer, LOW);
delay(200);
}
}
void resetPrompt() {
delay(2000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Enter Code:");
}