Smart Home Security System

Project Overview

Smart Home Security System is a hands-on project designed for creating a basic home security setup.

This project will involve:
- one or more Passive Infrared (PIR) motion sensor to detect movement in the environment
- a keypad for arming/disarming
- an alarm system or a buzzer to alert users when unauthorized motion is detected.

This alarm system will be designed mostly to be used on doors or windows, setting the sensors on the trajectory of motion realized by the door or window.

I will also create a web application in order to be able to arm or disarm the alarm from a distance.

Additionally, the system will send emails with every update, arming, disarming or alarm set-offs.

Hardware

These are the hardware components used for the alarm:

  1. Passive Infrared (PIR) Motion Sensor: Detects movement in the environment. Ideal for sensing motion in areas like doorways, windows, or hallways. This sensor is the one that triggers the alarm in the moment movement is being captured in a set area.

  2. Keypad: Used for arming/disarming the security system. A membrane keypad with push-buttons. Users enter a password or code to control the system state.

  3. Buzzer (Alarm System): Serves as an alert mechanism. Emits a loud sound when the system detects unauthorized motion, alerting homeowners or neighbors.

  4. Jumper wires

  5. Breadboard

The hardware with everything connected can be seen below:

Software

Library and Pin Definitions:

#include <Keypad.h>

#define buzzer 10
#define trigPin 11
#define echoPin 12

#define RXp2 16
#define TXp2 17

The code starts by including the Keypad library and defining pin numbers for various components like the buzzer and PIR sensor. Global Variables:

long duration;
int distance, initialDistance, currentDistance, i;
int screenOffMsg = 0;
String password = "1234";
String tempPassword;
boolean activated = false; // State of the alarm
boolean isActivated;
boolean activateAlarm = true;
boolean alarmActivated = false;
boolean specialAlarmActivated = true;
boolean enteredPassword; // State of the entered password to stop the alarm
boolean passChangeMode = false;
boolean passChanged = false;

Keypad Configuration:

In the Smart Home Security System project, the keypad configuration plays a crucial role. It involves mapping each button on the keypad to a specific function or input. The keypad uses a matrix layout, which means it has rows and columns of buttons. In the code, the keyMap array defines the characters or numbers associated with each button.

The pins of the Arduino are configured to interface with this matrix. Each row and column of the keypad is connected to a specific pin on the Arduino. The rowPins and colPins arrays in the code specify which Arduino pins are connected to which rows and columns of the keypad.

When a button is pressed, the Arduino detects which row and column are activated, and the corresponding character from the keyMap is identified. This setup allows for efficient detection of multiple button presses and is commonly used in security systems for password input.

const byte ROWS = 4;
const byte COLS = 4;
char keypressed;

char keyMap[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {9, 8, 7, 6}; 
byte colPins[COLS] = {5, 4, 3, 2}; 


Keypad myKeypad = Keypad(makeKeymap(keyMap), rowPins, colPins, ROWS, COLS);


The setup function in the Arduino code for the Smart Home Security System is where the initial configuration of the system takes place. It begins by initializing serial communication, which is crucial for debugging and interfacing with other devices. The function then sets up the pin modes for various components, such as the buzzer and the PIR sensor, to define their roles as input or output. This step is essential for the Arduino to interact correctly with these hardware components. While the specific initialization of the keypad is not detailed in the provided snippet, typically, this would also be configured here, linking the physical keypad layout to the Arduino's input pins. This initial setup ensures that all components are ready to function as intended when the main program loop begins.

void setup() {
  Serial.begin(9600);
  // Serial2.begin(9600, SERIAL_8N1, RXp2, TXp2);
  pinMode(buzzer, OUTPUT);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
}


In the main loop of the Arduino program for the Smart Home Security System, the code continuously monitors and responds to various conditions. It checks for incoming commands from the ESP32, which are critical for remotely controlling the alarm system. Depending on the received commands, the system is either armed or disarmed. The loop also manages the state of the alarm, activating it based on predefined conditions like detecting motion through the PIR sensor. Additionally, it handles user interactions with the keypad, allowing for manual arming/disarming and password changes. This loop is the heart of the system, constantly checking and responding to changes in its environment and user inputs.

void loop() {
  // Check for commands from ESP32
  if (Serial.available() > 0) {
    String command = Serial.readStringUntil('\n'); // Read the command from ESP32
    command.trim(); // Remove any whitespace

    Serial.print("Received command: "); Serial.println(command);

    if (command.equals("ARM")) {
      // specialActivateAlarm = true;  // Set the alarm activation flag
      activateAlarm = true;
    } else if (command.equals("DISARM")) {
      specialAlarmActivated = false;  // Set the alarm deactivation flag
      activateAlarm = false;
      alarmActivated = false;
      screenOffMsg = 0;
    }
  }
  // Serial2.println("Message Received: ");
  // Serial2.println(Serial2.readString());
  if(activateAlarm == true) {
    Serial.println("Alarm will be activated in: ");

    int countdown = 1;
    while(countdown != 0) {
      Serial.println(countdown);
      countdown--;
      // tone(buzzer, 700, 1000);
      digitalWrite(buzzer, LOW);
      delay(1000);
      digitalWrite(buzzer, HIGH);
    }
    Serial.println("Alarm Activated!");
    // initialDistance = getDistance();
    initialDistance = 10;
    activateAlarm = false;
    alarmActivated = true;
  }

  if(alarmActivated == true) {
    currentDistance = getDistance();
    // Serial.println(currentDistance);
    if(currentDistance < initialDistance) {
      // tone(buzzer, 1000);
      // Serial.print("ALARM");
      digitalWrite(buzzer, LOW);
      enterPassword(specialAlarmActivated);
    }
  }

  if(!alarmActivated) {
    if(screenOffMsg == 0) {
      Serial.println("A - Activate");
      Serial.println("B - Change Password");
      screenOffMsg = 1;
    }
    keypressed = myKeypad.getKey();
    Serial.print(keypressed);
    if(keypressed == 'A') {
      // tone(buzzer, 1000, 200);
      digitalWrite(buzzer, LOW);
      delay(200);
      digitalWrite(buzzer, HIGH);
      activateAlarm = true;
    }
    else if(keypressed == 'B') {
      int i = 1;
      // tone(buzzer, 2000, 100);
      digitalWrite(buzzer, LOW);
      delay(100);
      digitalWrite(buzzer, HIGH);
      tempPassword = "";
      Serial.println("Current Password");
      Serial.println(">");
      passChangeMode = true;
      passChanged = true;
      while(passChanged) {
        keypressed = myKeypad.getKey();
        if(keypressed != NO_KEY) {
          if(keypressed == '0' || keypressed == '1' || keypressed == '2' || keypressed == '3' || keypressed == '4' || keypressed == '5' || keypressed == '6' || keypressed == '7' || keypressed == '8' || keypressed == '9') {
            tempPassword += keypressed;
            Serial.print("*");
            i++;
            // tone(buzzer, 2000, 100);
            digitalWrite(buzzer, LOW);
            delay(100);
            digitalWrite(buzzer, HIGH);
          }
        }
        
        if(i > 5 || keypressed == '#') {
          tempPassword = "";
          i = 1;
          Serial.println("Current Password: ");
          Serial.println(">");
        }

        if(keypressed == '*') {
          i = 1;
          // tone(buzzer, 2000, 100);
          digitalWrite(buzzer, LOW);
          delay(100);
          digitalWrite(buzzer, HIGH);
          if(password == tempPassword) {
            tempPassword = "";
            Serial.println("Set New Password: ");
            Serial.println('>');
            while(passChangeMode) {
              keypressed = myKeypad.getKey();
              if(keypressed != NO_KEY) {
                if(keypressed == '0' || keypressed == '1' || keypressed == '2' || keypressed == '3' || keypressed == '4' || keypressed == '5' || keypressed == '6' || keypressed == '7' || keypressed == '8' || keypressed == '9') {
                  tempPassword += keypressed;
                  Serial.print("*");
                  i++;
                  // tone(buzzer, 2000, 100);
                  digitalWrite(buzzer, LOW);
                  delay(100);
                  digitalWrite(buzzer, HIGH);
                }
              }

              if(i > 5 || keypressed == '#') {
                tempPassword = "";
                i = 1;
                // tone(buzzer, 2000, 100);
                digitalWrite(buzzer, LOW);
                delay(100);
                digitalWrite(buzzer, HIGH);
                Serial.println("Set New Password: ");
                Serial.println(">");
              }

              if(keypressed == '*') {
                i = 1;
                // tone(buzzer, 2000, 100);
                digitalWrite(buzzer, LOW);
                delay(100);
                digitalWrite(buzzer, HIGH);
                password = tempPassword;
                passChangeMode = false;
                passChanged = false;
                screenOffMsg = 0;
              }
            }
          }
        }
      }
    }
  }
}


The enterPassword function in the Arduino program for the Smart Home Security System is responsible for handling the process of password entry through the keypad. This function is activated when there is a need to disarm the alarm, typically after it has been triggered. It prompts the user to enter the correct password, reading the input from the keypad. The function checks if the entered password matches the predefined one. If the correct password is entered, it deactivates the alarm and resets relevant system states. If an incorrect password is entered, it prompts the user to try again, maintaining the alarm's active state. This function is crucial for ensuring that only authorized individuals can disarm the system.

void enterPassword(bool specialAlarmActivated) {
  int k = 5;
  tempPassword = "";
  activated = true;
  Serial.println("*** ALARM ***");
  Serial.println("Password >");
  if(specialAlarmActivated == false) {
    activated = false;
    alarmActivated = false;
    // noTone(buzzer);
    digitalWrite(buzzer, HIGH);
    screenOffMsg = 0;
    return;
  }
  while(activated) {
    keypressed = myKeypad.getKey();
    if(keypressed != NO_KEY) {
      if(keypressed == '0' || keypressed == '1' || keypressed == '2' || keypressed == '3' || keypressed == '4' || keypressed == '5' || keypressed == '6' || keypressed == '7' || keypressed == '8' || keypressed == '9') {
        tempPassword += keypressed;
        Serial.print("*");
        digitalWrite(buzzer, LOW);
        delay(500);
        digitalWrite(buzzer, HIGH);
        k++;
      }
    }

    if(k > 9 || keypressed == '#') {
      tempPassword = "";
      k = 5;
      Serial.println("Try Again Please!");
      Serial.println("*** ALARM ***");
      Serial.println("Password >");
    }

    if(keypressed == '*') {
      if(tempPassword == password) {
        activated = false;
        alarmActivated = false;
        // noTone(buzzer);
        digitalWrite(buzzer, HIGH);
        screenOffMsg = 0;
      }
      else if(tempPassword != password) {
        Serial.println("Wrong! Try Again!");
        delay(2000);
        Serial.println("*** ALARM ***");
        Serial.println("Password >");
      }
    }
  }
}


The getDistance function in the Arduino code is a critical part of the Smart Home Security System, specifically designed to work with the PIR sensor. This function calculates the distance of an object from the sensor, which is crucial for detecting movement in the system's vicinity. It sends a pulse from the sensor, waits for it to bounce back, and then calculates the distance based on the time taken for the pulse to return. This distance measurement is used to determine whether an object is within a predefined range, which can trigger the alarm if the system is armed. This functionality is key for motion detection in security applications.

long getDistance() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);

  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  duration = pulseIn(echoPin, HIGH);

  distance = (duration / 29) / 2;

  return distance;
}


The provided ESP32 code integrates several functionalities for a smart home security system. It starts by including necessary libraries for WiFi and server capabilities. The code establishes a WiFi connection using predefined SSID and password and sets up an asynchronous web server.

The server listens for HTTP GET requests on root (”/”) and handles ARM/DISARM actions. When either ARM or DISARM is triggered via the web interface, the ESP32 logs this event over serial communication and sends an email notification. The email functionality is achieved using the ESP_Mail_Client library, which allows the ESP32 to send emails via an SMTP server.

For the email part, SMTP server details, sender, and recipient information are defined. When ARM/DISARM actions are activated, the ESP32 composes and sends an email indicating the system's status (armed or disarmed). This feature is essential for remote monitoring and notification.

The server begins listening for incoming connections after the initial setup, and the loop function remains empty as the primary functionality is handled within the web server's routes and callbacks.

This combination of web server and email notifications offers a robust approach for remote security system management.

#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <ESP_Mail_Client.h>

#define SMTP_server "smtp.gmail.com"
#define SMTP_Port 465

#define sender_email "esp32.test.iot.2024@gmail.com"
#define sender_password "hvzyfnpqlvfozkzx"

#define Recipient_email "nanurobert8@gmail.com"
#define Recipient_name "Robert"
SMTPSession smtp;

const char* ssid = "Robert 2,4";      // Replace with your WiFi SSID
const char* password = "robert2000";  // Replace with your WiFi Password

AsyncWebServer server(80);

void setup() {
  Serial.begin(9600);

  // Connect to Wi-Fi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi...");
  }
  Serial.println("Connected to WiFi");

  // Print the IP address
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());

  smtp.debug(1);

  ESP_Mail_Session session;
  session.server.host_name = SMTP_server ;
  session.server.port = SMTP_Port;
  session.login.email = sender_email;
  session.login.password = sender_password;
  session.login.user_domain = "";

  SMTP_Message message;
  /* Declare the message class */
  message.sender.name = "ESP 32";
  message.sender.email = sender_email;
  message.subject = "ESP32 Testing Email";
  message.addRecipient(Recipient_name,Recipient_email);

  String textMsg = "The alarm system application is on.";
  message.text.content = textMsg.c_str();
  message.text.charSet = "us-ascii";
  message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit;

  // Route for root / web page
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    String html = "<html><body><h1>Alarm Control</h1>"
                  "<button onclick=\"location.href='/arm'\">Arm Alarm</button>"
                  "<button onclick=\"location.href='/disarm'\">Disarm Alarm</button>"
                  "</body></html>";
    request->send(200, "text/html", html);
  });

  // Handler for the ARM action
  server.on("/arm", HTTP_GET, [](AsyncWebServerRequest *request){
    Serial.println("ARM"); // Send ARM command to Arduino
    ESP_Mail_Session session;
    session.server.host_name = SMTP_server ;
    session.server.port = SMTP_Port;
    session.login.email = sender_email;
    session.login.password = sender_password;
    session.login.user_domain = "";

    SMTP_Message message;
    /* Declare the message class */
    message.sender.name = "ESP 32";
    message.sender.email = sender_email;
    message.subject = "ESP32 Testing Email";
    message.addRecipient(Recipient_name,Recipient_email);

    String textMsg = "The alarm system application is on.";
    message.text.content = textMsg.c_str();
    message.text.charSet = "us-ascii";
    message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit;
    if (!MailClient.sendMail(&smtp, &message))
      Serial.println("Error sending Email, " + smtp.errorReason());
    request->redirect("/"); // Redirect back to the main page
  });

  // Handler for the DISARM action
  server.on("/disarm", HTTP_GET, [](AsyncWebServerRequest *request){
    Serial.println("DISARM"); // Send DISARM command to Arduino
    ESP_Mail_Session session;
    session.server.host_name = SMTP_server ;
    session.server.port = SMTP_Port;
    session.login.email = sender_email;
    session.login.password = sender_password;
    session.login.user_domain = "";

    SMTP_Message message;
    /* Declare the message class */
    message.sender.name = "ESP 32";
    message.sender.email = sender_email;
    message.subject = "ESP32 Testing Email";
    message.addRecipient(Recipient_name,Recipient_email);

    String textMsg = "The alarm system application is on.";
    message.text.content = textMsg.c_str();
    message.text.charSet = "us-ascii";
    message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit;

    if (!MailClient.sendMail(&smtp, &message))
      Serial.println("Error sending Email, " + smtp.errorReason());
    request->redirect("/"); // Redirect back to the main page
  });

  

 /* //Send simple text message

  String textMsg = "Hello";

  message.text.content = textMsg.c_str();

  message.text.charSet = "us-ascii";

  message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit;*/

  if (!smtp.connect(&session))
    return;

  if (!MailClient.sendMail(&smtp, &message))
    Serial.println("Error sending Email, " + smtp.errorReason());

  // Start server
  server.begin();
}

void loop() {
  // Nothing needed here for now
}


Web Application
The smart alarm comes with a web application in order to arm and disarm the alarm, including a login system.

After you login with your credentials you will see the two buttons used for arming and disarming the alarm system.

The application also has a web server on which you are presented with two buttons for arming and disarming.

The buttons pressed will send an email with the information regarding that action.

Conclusion

Working on the Smart Home Security System project has been an enlightening journey into the world of IoT. This experience taught me the intricacies of integrating hardware and software to create a functional, real-world application. I've gained valuable insights into how IoT technologies can simplify and enhance our daily lives, especially in terms of home security. The project not only honed my technical skills but also demonstrated the practical impact of IoT in making our homes safer and more connected. It's a testament to how technology can be leveraged to create solutions that are both innovative and highly relevant to modern living.

Resources

iothings/proiecte/2023/homesecuritysystem.txt · Last modified: 2024/01/16 03:29 by robert_ionut.nanu
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