Security of one’s home is one of the biggest concerns for the majority of people out there. Not everyone can afford the expansive and sophisticated home security available out there in the market. So in this tutorial, we are going to learn how to build an IoT based Home Security system using the NodeMCU ESP8266 module and Adafruit IO.
In this project, we will learn about how to use the Adafruit IO platform to record, analyze, and control the live data on the cloud. You can upload, display, and monitor your data over the internet and make your project IoT enabled. You can even control motors, buzzers, and sensors using it.
Components Required
- NodeMCU ESP8266
- USB B type Data Cable
- PIR (Passive Infrared) Sensor
- Piezo buzzer
- Jumper Wires
- Breadboard
NodeMCU ESP8266
NodeMCU is an open-source firmware and development kit that helps you to prototype or builds IoT products. It includes firmware that runs on the ESP8266 Wi-Fi SoC from Espressif Systems, and hardware which is based on the ESP-12 module. The firmware uses the Lua scripting language. It is based on the eLua project and built on the Espressif Non-OS SDK for ESP8266.
There’s also 128 KB RAM and 4MB of Flash memory (for program and data storage) just enough to cope with the large strings that make up web pages, JSON/XML data, and everything we throw at IoT devices nowadays.
The ESP8266 Integrates 802.11b/g/n HT40 Wi-Fi transceiver, so it can not only connect to a WiFi network and interact with the Internet, but it can also set up a network of its own, allowing other devices to connect directly to it. This makes the ESP8266 NodeMCU even more versatile. The operating voltage is 3.3 V, you must take care of the fact that all GPIO pins are not 5V tolerant, so if you want to connect with 5V systems, then you have to do the logic level shifting.
PIR Sensor
A passive infrared sensor is an electronic sensor that measures infrared light radiating from objects in its field of view. They are most often used in PIR-based motion detectors. PIR sensors are commonly used in security alarms and automatic lighting applications.
Technically, PIR is made of a pyroelectric sensor, which is able to detect different levels of infrared radiation. If the human infrared radiation is directly irradiated on the detector, it will, of course, cause a temperature change to output a signal, but in doing so, the detection distance will not be far. In order to lengthen the detection distance of the detector, an optical system must be added to collect the infrared radiation, usually using a plastic optical reflection system or a Fresnel lens made of plastic as a focusing system for infrared radiation.
Circuit Diagram
Adafruit IO Setup
1. To use Adafruit IO, first, you have to create an account on Adafruit IO. To do this, go to the Adafruit IO website and click on ‘Get started for Free’ on the top right of the screen.
2. After creating the account, login and click on “AIO Key” which is on the top right corner.
3. Now you get your Adafruit IO Username and AIO Key and note it down, it will be needed later in the project.
4. Now we need to create a feed to get your data to the platform. Click on Create a new feed and then fill up the name and the description and then click on create. For this project, we created two feeds, pirsensor and LED.
5. Now we have to create an IO Dashboard to show all the feeds on one page. To create a dashboard, click on the Dashboard option and then click on the ‘Action,’ and after this, click on ‘Create a New Dashboard.’ In the next window, enter the name for your dashboard and click on ‘Create.’
6. Now using the add button on the dashboard, add an On-Off Toggle switch for the warning LED and a Line Chart for the PIR Sensor Data. While selecting the Toggle Switch In the next window, it will ask you to select the feed, click on LED feed there. Similarly, do it for the Line Chart and select pirsensor feed there.
The project after completion will somewhat look like shown in the picture above. Choose your own layout and play with the stuff.
Setting up the NodeMCU for Arduino
To program the NodeMCU, you have to connect to your PC with a Micro USB B type cable and open Arduino IDE. To program the NodeMCU, you first need to go to File-> Preferences->Settings.
Enter https://arduino.esp8266.com/stable/package_esp8266com_index.json into the ‘Additional Board Manager URL’ field and click on ‘Ok’.
Now go to Tools->Board->Boards Manager and type esp in the search bar, there ESP8266 will be listed, select the latest version of the board and download it.
After installation is complete, go to Tools >Board > and select NodeMCU 1.0 (ESP-12E Module). Now you can program NodeMCU with Arduino IDE.
You need to download the Library from the link and put it into the library folder. https://github.com/adafruit/Adafruit_MQTT_Library
You can get the full code at the end of the tutorial. Here is a detailed explanation of some sections of the code.
First, we start by including all the necessary header files.
#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
Then include the WiFi and Adafruit IO credentials that you copied from the Adafruit IO server. These will include the MQTT server, Port No, User Name, and AIO Key
#define MQTT_SERV "io.adafruit.com"
#define MQTT_PORT 1883
#define MQTT_NAME "IO USERNAME"
#define MQTT_PASS "AIO KEY "
Set up the feeds you are publishing to. In this case, “pirsensor” is the feed name.
Adafruit_MQTT_Publish pirsensor = Adafruit_MQTT_Publish(&mqtt,MQTT_NAME "/f/pirsensor");
Set up the feeds you are subscribing to. In this case, it is the feed “LED”.
Adafruit_MQTT_Subscribe LED = Adafruit_MQTT_Subscribe(&mqtt, MQTT_NAME "/f/LED");
Now coming to the setup part, it will declare the buzzer pin and led pin as output and the sensor pin as an input. Now connect to the wifi.
pinMode(buzzer, OUTPUT);
pinMode(ledPin, OUTPUT);
Serial.println(ssid);
WiFi.begin(ssid, pass);
Now we are going to read the sensor value and if it reads that the movement is present, then it will buzz the alarm and light up the LED.
if(state == HIGH) {
digitalWrite(ledPin, LOW);
digitalWrite(buzzer,HIGH);
Serial.println("Motion detected!");
delay(1000);
}
else{
digitalWrite(ledPin, HIGH);
digitalWrite(buzzer,LOW);
Serial.println("Motion Absent");
delay(1000);
}
Now Publish the data every second.
if (! pirsensor.publish(state))
{
delay(1000);
}
Now read the subscribed feed. If the LED is turned on from the IO platform
Adafruit_MQTT_Subscribe * subscription;
while ((subscription = mqtt.readSubscription(5000)))
{
if (subscription == &LED)
{
//Print the new value to the serial monitor
Serial.println((char*) LED.lastread);
if (!strcmp((char*) LED.lastread, "OFF"))
{
digitalWrite(ledPin, HIGH);
}
if (!strcmp((char*) LED.lastread, "ON"))
{
digitalWrite(ledPin, LOW);
}
}
This is how the NodeMCU based Motion detector IoT project works, you can add killer lasers, zapper, and all kinds of cool stuff with it (kidding! don’t do that). But you can add a notification option or emergency call feature if the alarm gets triggered at a certain time.
Code
#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
const char *ssid = "Redmi"; // Enter your WiFi Name
const char *pass = "12345678"; // Enter your WiFi Password
WiFiClient client;
#define MQTT_SERV "io.adafruit.com"
#define MQTT_PORT 1883
#define MQTT_NAME "shhivam_K_upadhyaya" // Your Adafruit IO Username
#define MQTT_PASS "aio_atGe56uefmWthO1yMpDwjWvbMbCI" // Adafruit IO AIO key
const int ledPin = D0;
const int sensor = D2;
const int buzzer = D6; // Here we are defining the pins which we will use to connect our sensors, LED and Buzzer
//Set up the feed you're publishing to
Adafruit_MQTT_Client mqtt(&client, MQTT_SERV, MQTT_PORT, MQTT_NAME, MQTT_PASS);
Adafruit_MQTT_Publish pirsensor = Adafruit_MQTT_Publish(&mqtt,MQTT_NAME "/f/pirsensor"); // pirsensor is the Adafruit IO feed name where you will publish your data
Adafruit_MQTT_Subscribe LED = Adafruit_MQTT_Subscribe(&mqtt, MQTT_NAME "/f/LED"); //Set up the feed you're subscribing to from Adafruit IO
void setup()
{
Serial.begin(115200);
delay(10);
mqtt.subscribe(&LED); //To start the communication between the NodeMCU and Adafruit IO
pinMode(buzzer, OUTPUT);
pinMode(ledPin, OUTPUT); // The declaration of PinMode of the NodeMCu
Serial.println("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, pass); // Here the NodeMCU ESP8266 will try to connect to the wifi with the ID and Password you have provided
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print("."); // this piece will print "....." till not connected
}
Serial.println("");
Serial.println("WiFi connected"); // this will be printed when wifi connection is made
}
void loop()
{
MQTT_connect(); // This code utilizes MQQT transfer Protocol. MQTT stands for MQ Telemetry Transport. It is a publish/subscribe, extremely simple and lightweight messaging protocol, designed for constrained devices and low-bandwidth, high-latency or unreliable networks.
int state = digitalRead(sensor);
if(state == ) {
digitalWrite(ledPin, LOW); // Turn the LED on (Note that LOW is the voltage level
digitalWrite(buzzer,HIGH);
Serial.println("Motion detected!");
delay(100);
}
else{
digitalWrite(ledPin, HIGH); // Turn the LED off by making the voltage HIGH
digitalWrite(buzzer,LOW);
Serial.println("Motion Absent");
delay(100); // Wait for two seconds (to demonstrate the active low LED)
}
if (! pirsensor.publish(state)) //This condition is used to publish the Variable state on adafruit IO. Change thevariable according to yours.
{
delay(1000);
}
Adafruit_MQTT_Subscribe * subscription;
while ((subscription = mqtt.readSubscription(5000))) //Dont use this one until you are conrolling something or getting data from Adafruit IO. Here we are only controlling the LED from the toggle switch of Adfruit IO Dashboard
{
if (subscription == &LED)
{
//Print the new value to the serial monitor
Serial.println((char*) LED.lastread);
if (!strcmp((char*) LED.lastread, "OFF"))
{
digitalWrite(ledPin, HIGH);
}
if (!strcmp((char*) LED.lastread, "ON"))
{
digitalWrite(ledPin, LOW);
}
}
}
}
void MQTT_connect() // This little section of code here is how MQQT Protocol sends the data to the server.
{
int8_t ret;
// Stop if already connected.
if (mqtt.connected())
{
return;
}
uint8_t retries = 3;
while ((ret = mqtt.connect()) != 0) // connect will return 0 for connected
{
mqtt.disconnect();
delay(5000); // wait 5 seconds
retries--;
if (retries == 0)
{
// basically die and wait for WDT to reset me
while (1);
}
}
}