Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

How to Build a Surveillance System With Raspberry Pi 3

DZone's Guide to

How to Build a Surveillance System With Raspberry Pi 3

Building your own surveillance system has never been easier or more fun! Join us as we take a look at how to make one using a Rapsberry Pi.

· IoT Zone ·
Free Resource

Before proceeding to code, you need to install the Node.js on your Raspberry Pi 3. Log in via SSH and update your Raspberry Pi system packages to their latest versions. Here is how to update your system package list:

pi@w3demopi:~ $ sudo apt-get update


Next, upgrade all your installed packages to their latest version:

pi@w3demopi:~ $ sudo apt-get dist-upgrade


To download and install the latest version of Node.js, use the following command:

pi@w3demopi:~ $ curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -


Now, install it by running the following command:

pi@w3demopi:~ $ sudo apt-get install -y nodejs


Check the version number and whether the installation was successful with the following command:

pi@w3demopi:~ $ node -v


Now that Node.js has been installed on your Raspberry Pi, you can now start with the coding.

Coding the Raspberry Pi Camera Module

To use the camera, you need to include a library from npm. You will use the pi-camera library to install it and run the command in the terminal, as shown below. Check out the official link for the pi-camera npm module at https://www.npmjs.com/package/pi-camera:

Now, create a file with the name CameraModule.js and include the  pi-camera  module in it:

const PiCamera = require('pi-camera');


As per the documentation of the pi-camera module, you need to set the configuration of the camera. You have to define two configurations — one for taking still pictures and one for taking videos:

const myCameraPhoto = new PiCamera({
      mode: 'photo',
      output: `/home/pi/Node_Programs/photos/photo.jpg`,
      width: 640,
      height: 480
});

const myCameraVideo = new PiCamera({
     mode: 'video',
     output: `/home/pi/Node_Programs/videos/video.h264`,
     width: 1920,
     height: 1080,
     timeout: 5000
});


In both the configurations, the following aspects are defined:

  • A mode that defines whether the camera takes still photographs or a video. Note that the video is created in the h246 format, which is the raw format, and can be played on quite a few popular video players, including the VLC media player.
  • The output, which defines the path where the photo or video will be saved in local storage
  • The height and width, which defines the resolution
  • Timeout (only in case of videos) defines the length of the video that will be recorded.

Define a cameraInUse flag and set it to false by default. This flag ensures that the camera doesn't accept any further requests when taking pictures or recording a video. This is to prevent any consequent errors while loading the camera:

var camerInUse = false;


Now, define a function that will take a picture when called upon. This function takes callback as an argument and returns a success message when the picture is properly selected.

Note that module.exports   is used to define the function, which will make this function available when CameraModule.js is included ( or imported) in other modules.

module.exports.takePicture = function (callback){
   if (camerInUse == false) {
    camerInUse = true;
    myCameraPhoto.snap()
   .then((result) => {
       console.log('Your picture was captured')
       callback('success')
       camerInUse = false;
    })
    .catch((error) => {
     console.log(error.toString());
     callback(error.toString());
    });
  }
  else {
   console.log('camera in use..')
  }
}


Before taking a picture, the code checks the value of the cameraInUse   lag and starts the camera only if the flag is set to false. Once the camera starts taking photos, the flag is set to true so that no further requests are accepted for the camera until it is done clicking pictures.

Similarly, you will need to define a function that will record the video when called:

module.exports.takeVideo = function (callback) {
   if(camerInUse == false){
     camerInUse = true;
     myCameraVideo.record()
    .then((result) => {
      console.log('recording completed...!!');
      callback('success')
      camerInUse = false;
   })
   .catch((error) => {
     console.log(error.toString());
   });
 }
 else{
    console.log('camera in use..')
  }
}


Coding the Raspberry Pi Email Module

The email module is used to send email notifications whenever a trespasser enters the premises, along with evidence in the form of a video or photograph. To accomplish this task, use the npm module  nodemailer. Download this by running the npm and installing the nodemailer   command in the terminal as shown below. Check out the the nodemailer npm module here.

Create a file with the name EmailModule.js and include the  nodemailer  module in it:

var nodemailer = require('nodemailer');


Now, set the transport configuration for the email module by providing the details of the email service provider. The email ID from the email will be sent, along with its username and password:

var transporter = nodemailer.createTransport({
   service: 'gmail',
   auth: {
     user: 'YOUR_EMAIL_ADDRESS',
     pass: 'PASSWORD'
   }
});


Next, set the email options for sending the email with the video and photo as attachments:

  •   from :  This is the email address of the sender of the email
  •   to :  This is the email address of the email recipient
  •  subject:  This is the subject line of the email being sent
  •  Html:  This is the content of the email
  •  attachments:  This includes the following elements:
    •  filename:  Here, you can set the name of the file that is sent as an attachment
    •  path:  This is the local file storage path from where the file will be picked for attachment

Here, the following are defined:

const videoMailOptions = {
   from: YOUR_EMAIL_ADDRESS',
   to: 'RECEPIENT_EMAIL_ADDRESS',
   subject: 'Intruder in your Castle...!!',
   html: 'Some one is trying to steal your gold...!!',
   attachments: [{
    filename: 'IntruderVideo.h264',
    path: '/home/pi/Node_Programs/videos/video.h264'
   }]
};


Similarly, you will need to define the email option for sending still photos, as shown in the following block of code:

const photoMailOptions = {
  from: YOUR_EMAIL_ADDRESS',
  to: 'RECEPIENT_EMAIL_ADDRESS',
  subject: 'Intruder in your Castle...!!',
  html: 'Someone is trying to steal your gold...!!',
  attachments: [{
    filename: 'IntruderImage.jpg',
    path: '/home/pi/Node_Programs/photos/photo.jpg'
   }]
};


Now, you will write functions that send the email whenever triggered:

module.exports.sendMailVideo = function () {
   transporter.sendMail(videoMailOptions, function (err, info) {
      if(err){
        console.log(err.toString());
      }
      else{
        console.log('Video email success..!!');
      }
   });
}

module.exports.sendMailPhoto = function (){
   transporter.sendMail(photoMailOptions, function (err, info) {
   if(err){
     console.log(err.toString())
   }
   else{
    console.log('Photo email success..!!');
   }
  });
}


Coding the Raspberry Pi Sensor Module

Now, it's time to write the code for sensor modules, which will govern the functioning of all the sensors and LEDs. To accomplish this task, you need an npm module called  pigpio , which gives access to the GPIO of the Raspberry Pi. To install the pigpio module, run the sudo npm, and install the pigpio command, check out the terminal shown below:

Check out the official npm link at https://www.npmjs.com/package/pigpio for more details about the pigpio   module.

Create a file with the name  Survillance.js  and include the pigpio   module. Also, you will want to include CameraModule.js   and  EmailModule.js , which you developed just now. This will give access to the functions of each module for taking pictures, videos, and sending emails:

var GPIO = require('pigpio').Gpio,
cameraModule = require('./CameraModule'),
emailModule = require('./EmailModule');


Make sure that  Survillance.js ,  EmailModule.js , and CameraModule.js are placed in the same directory. Initialize the Raspberry Pi's pins for reading out and sending signals to sensors and LEDs:

var PIR_out= new GPIO(19,{mode: GPIO.INPUT,alert: true}),
red_LED= new GPIO(17,{mode: GPIO.OUTPUT}),
buzzer= new GPIO(26,{mode: GPIO.OUTPUT}),
IR_out= new GPIO(5,{mode: GPIO.INPUT,alert: true}),
trigger = new GPIO(16, {mode: GPIO.OUTPUT}),
echo = new GPIO(21, {mode: GPIO.INPUT, alert: true});


The PIR sensor's output ( PIR_out ) is connected to GPIO 19, so declare GPIO 19 as the input and set the alert event flag to true. The alert event indicates that an alert event will be raised whenever the value at the GPIO changes from low (0) to high (1) or vice versa. You can listen to the alert event and take action accordingly.

The positive terminal of LED ( red_LED ) is connected to GPIO 17. The LED will work as an indicator. Whenever a trespasser is detected, the LED will glow. GPIO 17 is set as the OUTPUT   pin.

The buzzer is connected to the Pi with one of its terminals connected to GPIO 26 and the other connected to the ground. The buzzer is used to raise an alarm when an intruder is detected, so set GPIO 26 as  OUTPUT .

The infrared sensor's output ( IR_out ) is connected to GPIO 5, which is declared as the INPUT   pin, and the alert event flag is set to true.

The trigger terminal of the ultrasonic sensor is used to generate high frequency ultrasonic waves. The trigger pin is connected to GPIO 16, so declare it as the OUTPUT   pin.

The echo pin of the ultrasonic sensor is connected to GPIO 21. The echo pin is used to get the output of the ultrasonic sensor, so it is declared as INPUT and the alert event flag is set to true.

Make sure you initialize the LED to the low level (0):

red_LED.digitalWrite(0);


First, write the code block to read the data of the PIR sensor:

PIR_out.on('alert', function(level, tick){
  if(level==1) {
    cameraModule.takePicture(function (callback) {
    var result = callback;

    if (result == 'success') {
      emailModule.sendMailPhoto()
   }
  })
  console.log('PIR : Intruder Alert..!!')
  red_LED.digitalWrite(level);
  buzzer.digitalWrite(level);
}
else {
  red_LED.digitalWrite(level);
  buzzer.digitalWrite(level);
 }
})


Here, listen to the alert event for the PIR sensor. As soon as the PIR sensor detects any trespasser in the house, the output goes high from the initial low state, which causes an alert event to fire. The alert function returns a callback with two parameters — one is level and the other one is tick. The level parameter indicates the state of the GPIO at that moment and tick is the timestamp at which the change in state is observed at the GPIO. So, the alert event is checked, and if the level is high (1), then the takePicture function of the camera module is called to click a photo of the trespasser immediately.

Then, the output of the buzzer and LED indicator are set to high and raise the alarm. Once the success callback is received from the camera module's takePicture function, the sendMailPhoto  function of the email module is called. This sends the alert email along with the photo of the trespasser to the owner of the house.

Now, write the code for the  IR  sensor, which is very similar to the PIR sensor code:

IR_out.on('alert', function(level, tick){
  if(level==1){
    cameraModule.takeVideo(function (callback) {
      var result = callback;
      if(result == 'success'){
        emailModule.sendMailVideo() ;
      }
   })
   console.log('IR : Intruder Alert..!!'
   red_LED.digitalWrite(level);
   buzzer.digitalWrite(level);
}
else {
  red_LED.digitalWrite(level);
  buzzer.digitalWrite(level);
}
})


An IR sensor works in the exact same way as the PIR   sensor. The only difference is that it records a video instead of taking a still photo.

Lastly, it's time to write the code block for the ultrasonic sensor module:

trigger.digitalWrite(0);
var MICROSECDONDS_PER_CM = 1000000/33000;
// Trigger a distance measurement once per second
setInterval(function () {
   trigger.trigger(10, 1); // Set trigger high for 10 microseconds
}, 5000);

//The number of microseconds it takes sound to travel 1cm at 20 degrees celcius
var startTick;
echo.on('alert', function (level, tick) {
var endTick,
diff;

if (level == 1) {
  startTick = tick;
}
else {
  endTick = tick;
  diff = (endTick >> 0) - (startTick >> 0); //Unsigned 32-bit arithmetic
  var actualDist = (diff / 2 / MICROSECDONDS_PER_CM) ;
  if (actualDist < 10){
    console.log('Ultrasonic : Intruder Detected...!!')
    red_LED.digitalWrite(1);
    buzzer.digitalWrite(level);
    cameraModule.takePicture(function (callback) {
       var result = callback;
       if (result == 'success'){
         emailModule.sendMailPhoto() 
       }
   })
  }
  else {
   red_LED.digitalWrite(0);
   buzzer.digitalWrite(0);
  }
 }
});


Making use of the trigger function of the pigpiomodule, a high-pulse is sent to the trigger pin of the ultrasonic sensor for 10 microseconds, which causes the sensor transmitter to emit a burst 8 high-frequency pulse that makes the output at the echo pin high.

The output of the ultrasonic sensor is taken from the echopin on which you are listening for the alert event. As soon as the ultrasonic wave is transmitted, the state of the echo pin changes to high and the alert event is fired, which returns a callback with two parameters. The first is the level that is used to check whether the state of echo is high (1) or low (0). The other is tick, which is used to check the timestamp when the state changed.

The state of the echo is changed from low to high and this timestamp is saved as  startTick . When the waves get reflected from obstruction and fall on the receiver, the state of the echo   pin is changed from high to low. This timestamp is saved as  endTick . Now, to get the distance of the obstruction from the sensor, you need to record the time taken by the ultrasonic waves to travel to and from the sensor-subtract startTick from  endTick . The tick is the number of microseconds since the system boot. Its value is an unsigned 32-bit quantity. So, to get the correct value after subtraction, you need to use the right shift operator. Once you have the travel time, you can, then, calculate the distance.

Once you have the distance, check whether the distance is less than 10 cm. If it is, raise an alert by lighting the LED, beeping the Buzzer, taking a picture, and, finally, sending the alert through email.

The code part is finally completed. Now, execute the code by running the following command in the terminal:

sudo node Survillance.js


This is the output for the  PIR  sensor:


This is the output of the IR   sensor:


This is the output of the ultrasonic sensor:


The following is a snapshot of the email notification received as an alert:

Topics:
raspberry pi 3 ,surveillance ,how-to ,tutorial ,javascript ,iot

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}