Skip to main content

Smart Security System | Arduino UNO | IR + Servo + LCD + Keypad

Smart Security System | Arduino UNO | IR + Servo + LCD + Keypad

๐Ÿ” Smart Security System

Arduino UNO · IR Sensors · Servo · LCD · Keypad · Buzzer

๐Ÿ”Ž What is This Project?

This is a Password-Protected Car Parking System built with Arduino UNO. It manages parking slots, controls a servo barrier, and uses IR sensors to detect cars entering and exiting. Features:
  • ๐Ÿ” 4×4 Keypad – for password authentication (Entry)
  • ๐Ÿ“ก 2× IR Sensors – Entry (IR1) and Exit (IR2) detection
  • ๐Ÿ”„ SG90 Servo Motor – automatic barrier control
  • ๐Ÿ“Ÿ 16×2 LCD with I²C – displays slot availability and status
  • ๐Ÿ”Š Active Buzzer (MH-FMD) – audio feedback (active-LOW)

⚙️ How It Works

• The system continuously monitors IR sensors for car entry and exit.
• When a car approaches the entry gate (IR1), the system checks for available slots.
• If a slot is available, the Keypad prompts for a password.
• Enter the correct password (default: 1234) and press D to submit.
• If correct: Servo opens the gate, slot count decreases, and the car enters.
• Once the car passes IR2 (exit sensor), the gate closes automatically.
• For exit: IR2 is triggered first, the gate opens, and the slot count increases.
• The LCD shows real-time slot availability and system status.

๐Ÿ“ฆ Components Required


๐Ÿ–จ️ 3D Printable Files


๐Ÿ”Œ Pin Connections (Arduino UNO)

Component Arduino Pin Notes
Keypad (Rows)D2, D3, D4, D54 Rows
Keypad (Columns)D6, D7, D8, D94 Columns
Servo SignalD10PWM control
IR Sensor 1 (Entry)D11Car entry detection
IR Sensor 2 (Exit)D12Car exit detection
Active Buzzer (MH-FMD)D13Audio output (active-LOW)
LCD I²C (SDA)A4I2C Data
LCD I²C (SCL)A5I2C Clock
Power5V / GNDFrom Arduino or battery
Important: The MH-FMD active buzzer is active-LOW – it turns ON when the pin is LOW and OFF when HIGH. The code handles this correctly.
Use a 7.4V Li-ion battery with a 2200ยตF capacitor across the power rails to stabilize voltage for the servo motor.

⚡ Features & Specifications

๐Ÿ” Password Protected Entry
๐Ÿ“ก 2× IR Detection
๐Ÿ”„ Servo Barrier Control
๐Ÿ“Ÿ LCD Slot Display
๐Ÿ”Š Audio Feedback
๐Ÿ”‹ Battery Powered


๐Ÿ’ป Arduino Code

Parking_System.ino
/*
 * ========================================
 *   PASSWORD-PROTECTED CAR PARKING SYSTEM
 * ========================================
 * Components:
 *   - Arduino Uno
 *   - 4x4 Keypad       → D2 to D9
 *   - 16x2 LCD I2C     → A4 (SDA), A5 (SCL)
 *   - Servo SG90       → D10
 *   - IR Sensor 1 (Entry) → D11
 *   - IR Sensor 2 (Exit)  → D12
 *   - Active Buzzer MH-FMD → D13
 *
 * Libraries needed:
 *   - Keypad            (by Mark Stanley)
 *   - LiquidCrystal_I2C (by Frank de Brabander)
 *   - Password          (by Justin Shaw)
 *   - Servo             (built-in)
 *
 * Keys:
 *   D = Enter / Submit
 *   C = Clear / Reset
 *   * = Backspace
 *
 * BUZZER FIX: MH-FMD is active-LOW
 *   buzzerOn()  = LOW
 *   buzzerOff() = HIGH
 * ========================================
 */

#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
#include <Password.h>
#include <Servo.h>

// --- PINS ---
#define SERVO_PIN   10
#define IR1_PIN     11
#define IR2_PIN     12
#define BUZZER_PIN  13

// --- PASSWORD ---
Password   password     = Password("1234");
const byte PASSWORD_LEN = 4;

// --- PARKING ---
int Slot = 4;
const int MaxSlots = 4;

// --- SERVO ANGLES ---
const int SERVO_CLOSED = 5;    // Closed position angle
const int SERVO_OPEN   = 100;  // Open position angle

// --- STATE ---
byte currentLen = 0;
bool carEntering = false;
bool carExiting = false;
bool passwordMode = false;
bool waitingForIR2 = false;
bool ir1WasTriggered = false;

// --- SERVO ---
Servo myservo;

// --- KEYPAD ---
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
  {'D','C','B','A'},
  {'#','9','6','3'},
  {'0','8','5','2'},
  {'*','7','4','1'}
};
byte rowPins[ROWS] = {2, 3, 4, 5};
byte colPins[COLS] = {6, 7, 8, 9};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

// --- LCD ---
LiquidCrystal_I2C lcd(0x27, 16, 2);

// --- CUSTOM CHARACTERS ---
byte lockChar[8]   = {0b01110,0b10001,0b10001,0b11111,0b11011,0b11011,0b11111,0b00000};
byte unlockChar[8] = {0b01110,0b10000,0b10000,0b11111,0b11011,0b11011,0b11111,0b00000};
byte tickChar[8]   = {0b00000,0b00001,0b00011,0b10110,0b11100,0b01000,0b00000,0b00000};
byte crossChar[8]  = {0b00000,0b10001,0b01010,0b00100,0b01010,0b10001,0b00000,0b00000};

// ===================================================
// HELPER FUNCTIONS
// ===================================================
int centerCol(int textLen) {
  int col = (16 - textLen) / 2;
  return (col < 0) ? 0 : col;
}

void printCenter(int row, String text) {
  lcd.setCursor(0, row);
  lcd.print("                ");
  lcd.setCursor(centerCol(text.length()), row);
  lcd.print(text);
}

int pwStartCol() {
  int width = PASSWORD_LEN * 2 - 1;
  return centerCol(width);
}

void drawPasswordRow() {
  int col = pwStartCol();
  lcd.setCursor(0, 1);
  lcd.print("                ");
  for (byte i = 0; i < PASSWORD_LEN; i++) {
    lcd.setCursor(col + i * 2, 1);
    lcd.print(i < currentLen ? '*' : '_');
  }
}

void showEnterPassword() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.write(byte(0));
  lcd.print(" Enter Password ");
  drawPasswordRow();
}

void resetPW() {
  password.reset();
  currentLen = 0;
}

// ===================================================
// ACTIVE BUZZER FUNCTIONS (MH-FMD = active-LOW)
// ===================================================
void buzzerOn() {
  digitalWrite(BUZZER_PIN, LOW);
}

void buzzerOff() {
  digitalWrite(BUZZER_PIN, HIGH);
}

void sadTone() {
  for (int i = 0; i < 3; i++) {
    buzzerOn();
    delay(400);
    buzzerOff();
    delay(300);
  }
}

void alarmingTone() {
  for (int i = 0; i < 8; i++) {
    buzzerOn();
    delay(100);
    buzzerOff();
    delay(80);
  }
}

void progressiveTone() {
  buzzerOn();  delay(100);  buzzerOff();  delay(100);
  buzzerOn();  delay(80);   buzzerOff();  delay(80);
  buzzerOn();  delay(60);   buzzerOff();  delay(60);
  buzzerOn();  delay(40);   buzzerOff();  delay(40);
  buzzerOn();  delay(200);  buzzerOff();
}

void shortBeep(int duration) {
  buzzerOn();
  delay(duration);
  buzzerOff();
  delay(50);
}

// ===================================================
// PASSWORD CHECK
// ===================================================
void accessGranted() {
  passwordMode = false;

  int col = pwStartCol();
  for (byte i = currentLen; i < PASSWORD_LEN; i++) {
    lcd.setCursor(col + i * 2, 1);
    lcd.print('*');
    shortBeep(40);
    delay(50);
  }

  for (int f = 0; f < 2; f++) {
    lcd.setCursor(0, 1);
    lcd.print("                ");
    delay(100);
    for (byte i = 0; i < PASSWORD_LEN; i++) {
      lcd.setCursor(col + i * 2, 1);
      lcd.print('*');
    }
    delay(100);
  }

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.write(byte(3));
  lcd.print(" ENTRY GRANTED ");
  lcd.setCursor(0, 1);
  lcd.write(byte(1));
  lcd.print(" Gate Opening..");

  progressiveTone();

  myservo.write(SERVO_OPEN);   // Instant open
  Slot--;

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Gate Opened!");
  delay(1500);

  waitingForIR2 = true;
  resetPW();
}

void accessDenied() {
  for (int i = 0; i < 3; i++) {
    lcd.clear();
    lcd.setCursor(centerCol(14), 0);
    lcd.write(byte(4));
    lcd.print(" WRONG!");
    delay(120);
    lcd.clear();
    delay(80);
  }

  alarmingTone();

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.write(byte(4));
  lcd.print(" ENTRY DENIED  ");
  lcd.setCursor(0, 1);
  lcd.print("   Try Again    ");
  delay(2000);

  resetPW();
  showEnterPassword();
}

void checkPassword() {
  if (password.evaluate()) {
    accessGranted();
  } else {
    accessDenied();
  }
}

// ===================================================
// SHOW IDLE SCREEN
// ===================================================
void showIdleScreen() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("    WELCOME!    ");
  lcd.setCursor(0, 1);
  lcd.print("Slot Left: ");
  lcd.print(Slot);
  if (Slot < 10) lcd.print(" ");
}

// ===================================================
// SETUP
// ===================================================
void setup() {
  Serial.begin(9600);
  Serial.println("SYSTEM STARTING...");

  pinMode(IR1_PIN, INPUT);
  pinMode(IR2_PIN, INPUT);

  digitalWrite(BUZZER_PIN, HIGH);
  pinMode(BUZZER_PIN, OUTPUT);
  buzzerOff();

  myservo.attach(SERVO_PIN);
  myservo.write(SERVO_CLOSED);   // Start at 5°

  lcd.init();
  lcd.backlight();
  lcd.createChar(0, lockChar);
  lcd.createChar(1, unlockChar);
  lcd.createChar(3, tickChar);
  lcd.createChar(4, crossChar);

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("    ARDUINO    ");
  lcd.setCursor(0, 1);
  lcd.print(" PARKING SYSTEM ");
  shortBeep(100);
  delay(200);
  shortBeep(100);
  delay(2000);

  showIdleScreen();
  Serial.println("SETUP COMPLETE");
}

// ===================================================
// LOOP
// ===================================================
void loop() {

  // --- Waiting for car to pass IR2 ---
  if (waitingForIR2) {
    if (digitalRead(IR2_PIN) == LOW) {
      Serial.println("Car passed IR2");
      delay(2000);
      myservo.write(SERVO_CLOSED);   // Instant close
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Gate Closed!");
      shortBeep(150);
      delay(2000);
      waitingForIR2 = false;
      carEntering = false;
      resetPW();
      showIdleScreen();
    }
    return;
  }

  // --- Password Mode ---
  if (passwordMode) {
    char key = keypad.getKey();

    if (key != NO_KEY) {
      Serial.print("Key: ");
      Serial.println(key);

      if (key == 'C') {
        Serial.println("CANCELLED");
        resetPW();
        passwordMode = false;
        carEntering = false;
        lcd.clear();
        printCenter(0, "  Entry Aborted ");
        delay(1500);
        showIdleScreen();
        return;
      }
      else if (key == '*') {
        if (currentLen > 0) {
          currentLen--;
          shortBeep(40);
          drawPasswordRow();
        }
      }
      else if (key == 'D') {
        if (currentLen > 0) {
          Serial.println("ENTER pressed");
          checkPassword();
        }
      }
      else {
        if (currentLen < PASSWORD_LEN) {
          password.append(key);
          currentLen++;
          shortBeep(50);
          drawPasswordRow();
          Serial.print("Digit ");
          Serial.print(currentLen);
          Serial.println("/4 entered");
        }
      }
    }
    return;
  }

  // --- Check IR1 (Entry) ---
  bool ir1State = digitalRead(IR1_PIN);

  if (ir1State == LOW && !carEntering && !carExiting && !ir1WasTriggered) {
    ir1WasTriggered = true;
    Serial.println("IR1 TRIGGERED - Car detected");

    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Car Detected!");
    shortBeep(100);
    delay(1500);

    if (Slot > 0) {
      Serial.println("Slots available - entering password mode");
      carEntering = true;
      passwordMode = true;
      resetPW();
      showEnterPassword();
    } else {
      Serial.println("Parking full");
      lcd.clear();
      printCenter(0, "    SORRY :(    ");
      printCenter(1, "  Parking Full  ");
      sadTone();
      delay(3000);
      showIdleScreen();
    }
  }

  if (ir1State == HIGH) {
    ir1WasTriggered = false;
  }

  // --- Check IR2 (Exit) ---
  bool ir2State = digitalRead(IR2_PIN);
  static bool ir2WasTriggered = false;

  if (ir2State == LOW && !carExiting && !carEntering && !ir2WasTriggered) {
    ir2WasTriggered = true;
    Serial.println("IR2 TRIGGERED - Car exiting");

    if (Slot == MaxSlots) {
      lcd.clear();
      printCenter(0, " No Cars Left! ");
      shortBeep(200);
      delay(2000);
      showIdleScreen();
    } else {
      carExiting = true;
      myservo.write(SERVO_OPEN);   // Instant open
      shortBeep(100);
      delay(150);
      shortBeep(100);

      if (Slot < MaxSlots) Slot++;

      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Car Exiting...");
      delay(2000);

      while (digitalRead(IR1_PIN) == HIGH) delay(50);
      while (digitalRead(IR1_PIN) == LOW)  delay(50);

      delay(1500);
      myservo.write(SERVO_CLOSED);   // Instant close
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Gate Closed!");
      shortBeep(150);
      delay(2000);
      carExiting = false;
      showIdleScreen();
    }
  }

  if (ir2State == HIGH) {
    ir2WasTriggered = false;
  }
}
๐Ÿ“ก Code Features: Password-protected entry (default: 1234), servo barrier control, IR-based car detection (entry & exit), dynamic slot management (4 slots), custom LCD characters, active buzzer feedback (progressive, alarming, sad tones), and auto-close after car passes.
๐Ÿ”ง To use: Install Keypad, LiquidCrystal_I2C, Password, and Servo libraries. Change password on line ~35 to your preference.

๐Ÿ› ️ Assembly Steps

  • 1️⃣ 3D print the enclosure (if using).
  • 2️⃣ Connect all components according to the pin table above.
  • 3️⃣ Connect the 7.4V battery with a 2200ยตF capacitor across the power rails.
  • 4️⃣ Install required libraries: Keypad, LiquidCrystal_I2C, Password, and Servo (built-in).
  • 5️⃣ Change the default password in the code (line ~35) to your preferred password.
  • 6️⃣ Upload the code to Arduino UNO.
  • 7️⃣ Test: IR1 (entry) triggers password prompt → enter password + D to open gate.

๐ŸŽ“ Design Your Own PCBs with Altium

For designing professional PCBs for custom parking or security systems, Altium makes electronics design easier, faster, and more connected. Students get free access to Altium Student Lab – step‑by‑step courses & certifications.

๐Ÿ‘‰ Explore Altium Student Lab →

๐Ÿ’ก Tip: The default password is 1234. To change it, modify line ~35 in the code: Password password = Password("1234"); to your desired 4-digit password.
Keypad mapping: D = Submit, C = Clear/Reset, * = Backspace.

Comments

Popular posts from this blog

Solar Tracking System

Dual-Axis Solar Tracking System | Arduino SimpleCircuits Arduino Solar DIY Renewable Energy Project Dual-Axis Solar Tracking System Build a high-performance solar tracker that follows the sun in real-time. Four LDR sensors, an Arduino UNO, and two servo motors — boosting energy capture by up to 40% versus fixed mounts. 40% More Efficient 4 LDR Sensors 2 Servo Axes <300mA Power Draw Finished Build System Overview How the System Works The tracker reads the sky through four LDR sensors placed around the panel, computes intensity deltas, and drives two SG90 servos in a real-time closed loop — keeping the panel perpendicular to sunlight from sunrise to sunset. ...

Arduino Code Car Parking System

 // Created by Simple Circuits  #include <Wire.h>  #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27,16,2);    #include <Servo.h>  Servo myservo; int IR1 = 2; int IR2 = 3; int Slot = 4;           //Total number of parking Slots int flag1 = 0; int flag2 = 0; void setup() {   Serial.begin(9600);      lcd.init(); //initialize the lcd     lcd.backlight(); //open the backlight     pinMode(IR1, INPUT); pinMode(IR2, INPUT);    myservo.attach(4); myservo.write(100); lcd.setCursor (0,0); lcd.print("     ARDUINO    "); lcd.setCursor (0,1); lcd.print(" PARKING SYSTEM "); delay (2000); lcd.clear();   } void loop(){  if(digitalRead (IR1) == LOW && flag1==0){ if(Slot>0){flag1=1; if(flag2==0){myservo.write(0); Slot = Slot-1;} }else{ lcd.setCursor (0,0); lcd.print("    SORRY :(    ");   lc...

Arduino Code

 //define Pins #include <Servo.h> Servo servo; int trigPin = 11; int echoPin = 12; // defines variables long duration; int distance; void setup()  {   servo.attach(13);   servo.write(180);  delay(2000);    // Sets the trigPin as an Output pinMode(trigPin, OUTPUT); // Sets the echoPin as an Input  pinMode(echoPin, INPUT); } void loop()  { // Clears the trigPin digitalWrite(trigPin, LOW); delayMicroseconds(2); // Sets the trigPin on HIGH state for 10 micro seconds digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); // Reads the echoPin, returns the sound wave travel time in microseconds duration = pulseIn(echoPin, HIGH); // Calculating the distance distance= duration*0.034/2; // Prints the distance on the Serial Monitor Serial.print("Distance: "); Serial.println(distance); if ( distance <= 25   ) // Change Distance according to Ultrasonic Sensor Placement  { servo.write(180); delay(3000); ...