Home Security System

Author: Olteanu Robert

Master: AAC2

Project Description

The main goal for this project was to develop a security system based on IoT devices, mainly based on ESP32 development board and an RFID module and a RFID card and also a Tag which have a unique identifier to which I added some programming logic using a security keycode that user can type in using a 3×4 keypad, and for a good user experience I decided to add a small LCD 16×2 so the user can actually see if the keycode was wrong, or the card/tag he/she scanned is invalid.

Another good thing about the ESP32 is the fact that it has a built in WiFi module that allowed me to build a small dashboard in Adafruit.io where there are displayed a few information like, the current keycode, a log containing a small history and some status widgets.

Hardware Description

For the hardware parts I used:

  • ESP32 Development Board → It's a low-cost, low-power system on a chip (SoC) with WiFi and dula-mode Bluetooth capabilities, it has a dual-core or a single-core microprocessor with a clock rate of up to 240 MHz. ESP32 is highly integrated with built-in switches, power amplifier, low-noise receive amplifiers, filters, and power management modules. It is engineered for mobile devices, wearable electronics, and IoT applications.[1]
  • RFC522 RFID Module → Based on MFRC522 IC, is designed to create a 13.56MHz electromagnetic field that it uses to communicate with the RFID tags. The reader can communicate with a microcontroller over a 4-pin Serial Peripheral Interface (SPI). It also supports communication over I2c and UART protocols.[2]
  • 3×4 Membrane Keypad → It's a 12 keys keypad, slightly raised providing feedback when pressed.
  • LCD 16×2 with I2C Interface → A Liquid Crystal Display (LCD), which is a basic module and used commonly in various devices and circuits. 16×2 means it can display 16 characters per line and there are 2 lines. The Inter-Integrated Circuit (I2C) it's a bus interface connection protocol incorporated into devices for serial communication.

I attached below a diagram generated using circuito.io, but I used a version that involved less wires.

Software Description

In the table below I described all the libraries used to develop the project.

Library Description
SPI.h Serial Peripheral Interface is a synchronous serial data protocol used for communicating with one ore more devices quickly
MFRC522.h Standard library to interact with the MFRC522 module to read/write different types of RFID cards
Keypad.h Standard library for using matrix style keypads with Arduino
LiquidCrystal_I2C.h Offers a few functions to interact easily with the LCD display for displaying characters or erasing them
Wire.h Allows you to communicate with I2C/TWI devices
Adafruit_MQTT.h Arduino library for MQTT support, including accessing the Adafruit.io
Adafruit_MQTT_Client.h Part of the Adafruit_MQTT library suite

Next thing the software is split in two main parts:

  1. Initial setup - this is where all the components / modules are getting initialized
    • WiFi - The ESP32 tries to connect to the configured network until succeed and it gets the IP address
    • MQTT - The Adafruit.io supports data transfer using MQTT, and on this initial setup there is needed to subscribe to all topics needed while the publishers doesn't need to.
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
 
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);
Adafruit_MQTT_Publish hs_log = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/HS_Log");
Adafruit_MQTT_Publish hs_door = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/HS_DoorStatus");
Adafruit_MQTT_Subscribe hs_code = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/HS_DoorCode");
...
mqtt.subscribe(&hs_code);
  • RFC522 - Initialize the SPI Bus then initialize the RFID module.
  • LCD16x2 - Initialize the LCD and if the module supports, the backlight for a better display of messages
  • Keypad - Define the keypad and it's GPIO pins used
#include <Keypad.h>
#include <SPI.h>
#include <MFRC522.h>
#include <LiquidCrystal_I2C.h>
 
// Keypad
#define ROW_NUM     4 
#define COLUMN_NUM  3
char keys[ROW_NUM][COLUMN_NUM] = {
  {'#', '0', '*'},
  {'9', '8', '7'},
  {'6', '5', '4'},
  {'3', '2', '1'}
};
 
byte pin_rows[ROW_NUM] = {0, 2, 15, 13}; 
byte pin_column[COLUMN_NUM] = {17, 16, 4};
Keypad keypad = Keypad( makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM );
 
// MFRC522
#define SS_PIN  5  // ESP32 pin GIOP5 
#define RST_PIN 27 // ESP32 pin GIOP27 
MFRC522 rfid(SS_PIN, RST_PIN);
 
// LCD
int lcdColumns = 16;
int lcdRows = 2;
LiquidCrystal_I2C lcd(0x27, lcdColumns, lcdRows); 
 
...
 
SPI.begin(); // init SPI bus
rfid.PCD_Init(); // init MFRC522
 
lcd.init();
lcd.backlight();
  1. Loop - this is looping until the ESP32 is stopped by user.
    • Connect to MQTT - this is done on each iteration to ensure a good connectivity
    • Read code subscription - first time after initial setup the user must insert his/her keycode of 4 characters inside Adafruit.io dashboard
MQTT_connect();
Adafruit_MQTT_Subscribe *subscription;
 
// Await code to be set from dashboard
while(code.equals("####")){
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Awaiting code...");
    while((subscription = mqtt.readSubscription(5000))) {
        if(subscription == &hs_code) {
        Serial.print(F("Got: "));
        Serial.println((char*)hs_code.lastread);
        code = (char*)hs_code.lastread;
        }
    }
}
  • Card scan - Wait until a card is scanned and check if it's a valid one
if(rfid.PICC_IsNewCardPresent()) {
Serial.println("Card present");
if(rfid.PICC_ReadCardSerial()) {
    Serial.println("Read Serial");
    for (int i=0; i<rfid.uid.size; i++) {
    if(rfid.uid.uidByte[i] != availableCard[i]) {
        char msg[] = "Invalid card scanned";
        hs_log.publish(msg); // publish message 
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("Invalid card");
        delay(3000); // wait to be able to see the message from lcd
  • Type code - If the card was valid the user is prompted to input the security code
bool scannedCard() {
  int idx = 0;
 
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Insert code:");
  lcd.setCursor(0,1);
 
  do {
    do{
      keyp = keypad.getKey();
    }while(!keyp);
    kcode[idx] = keyp;
    idx++;
    lcd.print("*");
  }while(idx < 4);
 
  for(int i=0; i<4;i++){
    if(kcode[i] != code.charAt(i)) { // code is the variable containing the current keycode
      return false;
    }
  }
  return true;
}
  • Update status - anything from opening a door / disabling alarm etc.
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Door opened");
char msg[] = "Door opened";
hs_log.publish(msg); // publish message to logs
delay(7000); // open door / disable alarm etc.
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Door closed");
char msg2[] = "Door closed";
hs_log.publish(msg2); // publish message to logs
delay(3000); // wait to be able to read the lcd message

Software logical workflow

Down below I created a small logical workflow for the code described in the previous chapter to be easily understood.

References

iothings/proiecte/2021/homesecurity.txt · Last modified: 2022/01/28 01:14 by robert.olteanu1909
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0