/*
Wokwi | projects
Smart door locker
Maarifplayz55 - Sunday, February 22, 2026 7:58 AM
Access Control
*/
#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
#include <Servo.h>
#include <SPI.h>
#include <MFRC522.h>
#define SERVO_PIN 45
#define BUZZ_OK 9
#define BUZZ_ERR 8
#define LED_GREEN 11
#define LED_RED 10
#define DHT_PIN 12
#define MQ2_AOUT A0
#define VIBR_PIN 2
#define RFID_SS 53
#define RFID_RST 49
const String SECRET = "1234";
const int GAS_LIM = 400;
const float HUM_LIM = 80.0;
const int MAX_FAIL= 3;
const long CLOSE_T = 10000;
const long LOCK_T = 30000;
const byte CARDS[][4] = {
{0xDE,0xAD,0xBE,0xEF},
{0x01,0x02,0x03,0x04}
};
const int NCARD = 2;
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 rPins[ROWS]={32,33,34,35};
byte cPins[COLS]={36,37,38,39};
Keypad pad=Keypad(makeKeymap(keys),rPins,cPins,ROWS,COLS);
LiquidCrystal_I2C lcd(0x27,16,2);
DHT dht(DHT_PIN,DHT22);
Servo srv;
MFRC522 rfid(RFID_SS,RFID_RST);
String pin="";
int fails=0;
bool isOpen=false,locked=false,alarm=false;
unsigned long openAt=0,lockAt=0,sensorAt=0,lcdAt=0;
volatile bool quake=false;
void quakeISR(){ quake=true; }
void setup(){
Serial.begin(9600);
pinMode(BUZZ_OK, OUTPUT); digitalWrite(BUZZ_OK, LOW);
pinMode(BUZZ_ERR, OUTPUT); digitalWrite(BUZZ_ERR, LOW);
pinMode(LED_GREEN,OUTPUT); digitalWrite(LED_GREEN,LOW);
pinMode(LED_RED, OUTPUT); digitalWrite(LED_RED, LOW);
pinMode(VIBR_PIN, INPUT);
srv.attach(SERVO_PIN);
srv.write(0); delay(800);
srv.write(90); delay(800);
srv.write(0); delay(800);
attachInterrupt(digitalPinToInterrupt(VIBR_PIN),quakeISR,RISING);
dht.begin();
SPI.begin();
rfid.PCD_Init();
delay(50);
lcd.init(); lcd.backlight(); lcd.clear();
lcd.setCursor(0,0); lcd.print("SMART DOOR v9.0");
lcd.setCursor(0,1); lcd.print("Starting... ");
beepBoot();
delay(1000);
prompt();
Serial.println(F("Ready. PIN=1234"));
}
void loop(){
doQuake(); doSensors(); doRFID();
doKeypad(); doAutoClose(); doLockout();
}
void openDoor(){
isOpen=true; openAt=millis();
srv.write(90);
digitalWrite(LED_GREEN,HIGH);
Serial.println(F("[DOOR] OPEN"));
}
void closeDoor(){
if(alarm) return;
isOpen=false;
srv.write(0);
digitalWrite(LED_GREEN,LOW);
Serial.println(F("[DOOR] CLOSED"));
prompt();
}
void doAutoClose(){
if(!isOpen||alarm) return;
if(millis()-openAt>(unsigned long)CLOSE_T) closeDoor();
}
void doQuake(){
if(!quake) return;
quake=false; alarm=true;
digitalWrite(LED_RED,HIGH);
lcd.clear();
lcd.setCursor(0,0); lcd.print("!! EARTHQUAKE !!");
lcd.setCursor(0,1); lcd.print("DOOR OPENING! ");
openDoor();
for(int i=0;i<8;i++){
digitalWrite(BUZZ_ERR,HIGH); delay(150);
digitalWrite(BUZZ_ERR,LOW); delay(150);
}
alarm=false; digitalWrite(LED_RED,LOW);
prompt();
}
void doSensors(){
if(millis()-sensorAt<2000) return;
sensorAt=millis();
int gas=analogRead(MQ2_AOUT);
float hum=dht.readHumidity();
float tmp=dht.readTemperature();
Serial.print(F("Gas:")); Serial.print(gas);
Serial.print(F(" H:")); Serial.print(isnan(hum)?0:hum);
Serial.print(F(" T:")); Serial.println(isnan(tmp)?0:tmp);
if(gas>GAS_LIM){
alarm=true; digitalWrite(LED_RED,HIGH);
lcd.clear();
lcd.setCursor(0,0); lcd.print("** GAS ALERT!! **");
lcd.setCursor(0,1); lcd.print("EVACUATE! OPEN! ");
openDoor();
for(int i=0;i<10;i++){
digitalWrite(BUZZ_ERR,HIGH); delay(100);
digitalWrite(BUZZ_ERR,LOW); delay(150);
}
alarm=false; digitalWrite(LED_RED,LOW);
prompt(); return;
}
if(!isnan(hum)&&hum>HUM_LIM){
lcd.clear();
lcd.setCursor(0,0); lcd.print("HIGH HUMIDITY! ");
lcd.setCursor(0,1); lcd.print("DOOR OPENING! ");
openDoor();
digitalWrite(BUZZ_ERR,HIGH); delay(600);
digitalWrite(BUZZ_ERR,LOW);
return;
}
if(!alarm&&!locked&&!isOpen&&millis()-lcdAt>4000){
lcdAt=millis();
if(!isnan(hum)&&!isnan(tmp)){
lcd.setCursor(0,1);
lcd.print("H:"); lcd.print((int)hum);
lcd.print("% T:"); lcd.print((int)tmp);
lcd.print((char)223); lcd.print("C ");
}
}
}
void doRFID(){
if(locked||alarm) return;
if(!rfid.PICC_IsNewCardPresent()) return;
if(!rfid.PICC_ReadCardSerial()) return;
Serial.print(F("[RFID] UID:"));
for(byte i=0;i<rfid.uid.size;i++){
Serial.print(rfid.uid.uidByte[i]<0x10?" 0":" ");
Serial.print(rfid.uid.uidByte[i],HEX);
}
Serial.println();
if(cardOK()){
fails=0; lcd.clear();
lcd.setCursor(0,0); lcd.print("** RFID OK !! **");
lcd.setCursor(0,1); lcd.print("Welcome! ");
beepOK(); openDoor(); delay(1000); prompt();
}else{
fails++; lcd.clear();
lcd.setCursor(0,0); lcd.print("RFID DENIED! ");
lcd.setCursor(0,1); lcd.print("Unknown card ");
beepFail();
if(fails>=MAX_FAIL) startLock();
else{ delay(1000); prompt(); }
}
rfid.PICC_HaltA(); rfid.PCD_StopCrypto1();
}
bool cardOK(){
for(int c=0;c<NCARD;c++){
bool ok=true;
for(byte b=0;b<4;b++)
if(rfid.uid.uidByte[b]!=CARDS[c][b]){ok=false;break;}
if(ok) return true;
}
return false;
}
void doKeypad(){
if(locked||alarm) return;
char k=pad.getKey(); if(!k) return;
Serial.print(F("Key:")); Serial.println(k);
if(k=='#'){ checkPIN(); }
else if(k=='*'){ pin=""; if(isOpen) closeDoor(); else prompt(); }
else{
if(pin.length()<8){
pin+=k;
lcd.setCursor(0,1); lcd.print("PIN: ");
for(unsigned int i=0;i<pin.length();i++) lcd.print('*');
for(unsigned int i=pin.length();i<11;i++) lcd.print(' ');
}
}
}
void checkPIN(){
if(pin==SECRET){
fails=0; alarm=false; digitalWrite(LED_RED,LOW);
lcd.clear();
lcd.setCursor(0,0); lcd.print("** ACCESS OK!! **");
lcd.setCursor(0,1); lcd.print("Welcome! ");
beepOK(); openDoor(); delay(1000); prompt();
}else{
fails++;
lcd.clear();
lcd.setCursor(0,0); lcd.print("WRONG PIN! ");
lcd.setCursor(0,1); lcd.print("Left:"); lcd.print(MAX_FAIL-fails);
beepFail();
if(fails>=MAX_FAIL) startLock();
else{ delay(1000); prompt(); }
}
pin="";
}
void startLock(){
locked=true; alarm=true; lockAt=millis();
digitalWrite(LED_RED,HIGH);
lcd.clear();
lcd.setCursor(0,0); lcd.print("** LOCKED OUT **");
lcd.setCursor(0,1); lcd.print("Wait 30s... ");
for(int i=0;i<6;i++){
digitalWrite(BUZZ_ERR,HIGH); delay(100);
digitalWrite(BUZZ_ERR,LOW); delay(150);
}
}
void doLockout(){
if(!locked) return;
unsigned long el=millis()-lockAt;
if(millis()-lcdAt>1000){
lcdAt=millis();
long r=((long)LOCK_T-(long)el)/1000; if(r<0)r=0;
lcd.setCursor(0,1); lcd.print("Wait: ");
if(r<10) lcd.print(' '); lcd.print(r); lcd.print("s ");
}
if(el>=(unsigned long)LOCK_T){
locked=false; alarm=false; fails=0;
digitalWrite(BUZZ_ERR,LOW); digitalWrite(LED_RED,LOW);
prompt();
}
}
void beepBoot(){
for(int i=0;i<3;i++){
digitalWrite(BUZZ_OK,HIGH); delay(80);
digitalWrite(BUZZ_OK,LOW); delay(80);
}
}
void beepOK(){
digitalWrite(BUZZ_OK,HIGH); delay(200);
digitalWrite(BUZZ_OK,LOW); delay(80);
digitalWrite(BUZZ_OK,HIGH); delay(400);
digitalWrite(BUZZ_OK,LOW);
}
void beepFail(){
for(int i=0;i<3;i++){
digitalWrite(BUZZ_ERR,HIGH); delay(100);
digitalWrite(BUZZ_ERR,LOW); delay(150);
}
}
void prompt(){
lcd.clear();
lcd.setCursor(0,0); lcd.print(isOpen?"DOOR: OPEN ":"DOOR: LOCKED ");
lcd.setCursor(0,1); lcd.print("PIN/RFID: # OK ");
}Loading
mfrc522
mfrc522