Saturday, November 12, 2016

IOT: Security System with PIR Motion Sensor detect possible intruder, take photos using Raspi Cam, send MMS (of the photo) to registered mobile numbers, switch on Electrical bulb and Buzzer to alert every one


Objective: The Objective of this exercise is to implement a simple security system where PIR Motion Sensor (connected to Raspberry Pi) detects a possible intruder, takes photos using Raspi Camera module, send MMS (i.e photo of the intruder) to registered mobile numbers (owner of the house), switch ON the Electrical bulb and enable the buzzer to Buzz to alert every one. 
Note: The electrical bulb is connected to Relay Switch with Raspberry Pi and it will be controlled based on trigger pulse from PIR Motion Sensor. 
YouTube Video:
The YouTube Video for this tutorial is available at this link.

GitHub Source:
https://github.com/agilerules/IOT/tree/master/iot-pi4j-raspi-relay
Task details:
Once the application is successfully setup (as per the instructions below) and once you run the Java program - the PIR Motion sensor will keep looking for any human movements and as and when it encounters a movement, it will trigger a 5V and turn ON the LED in the IN1 Relay (of 4 channel Relay), which in-turn will turn ON the Light bulb connected to Mains. The Raspberry Camera module will take snaps and sends an MMS (using Twilio REST Api’s) to registered Mobile numbers. Also the Buzzer connected to Raspberry Pi should buzz to alert every one. If there is no human movement, the PIR Motion Sensor will not trigger a 5V, which will turn OFF the LED in the IN1 Relay (of 4 channel Relay), which in-turn will turn OFF the light bulb connected to Mains.  Before going in to the details of the project, let’s get some brief overview of the PIR Motion Sensor (for sensing the movements), Relay (to glow an Electric bulb), Buzzer (to buzz), Raspi Cam (to take photos), Twilio (to send MMS to mobile).
Overview about PIR Motion Sensor:
PIR stands for Passive InfraRed. This motion sensor consists of a fresnel lens, a infrared detector and supporting detection circuitry. The lens on the sensor focuses any infrared radiation/wavelengths present around it towards the infrared detector. Our bodies generate infrared heat and as a result this gets picked up by the motion sensor. The sensor outputs a 5V signal for a period of one minute as soon as it detects us. It offers a tentative range of detection of about 6-7 m and is highly sensitive. When the PIR motion sensor detects a person, it outputs a 5V signal to the raspberry pi through its GPIO. And we define what the raspberry pi should do as it detects an intruder through Java Pi4J coding. Here we are just printing: “Intruder detected”.
The PIR Motion Sensor has 3 pins (as shown in the below diagram):
Pin 1: is a +DC Voltage, usually connected to pin 2 of Raspberry Pi.
Pin 2: is an output pin
Pin 3 is the pin connected to Ground
In certain PIR motion sensors you can even adjust the delay at which the sensor outputs a HIGH signal at the expense of compromising the accuracy. You just need to turn the two knobs on the sensor counter clockwise using a screwdriver.
Overview about Relay:
What are relays?
A relay is an electromagnetic switch operated by a relatively small electric current that can turn on or off a much larger electric current. The heart of a relay is an electromagnet (a coil of wire that becomes a temporary magnet when electricity flows through it). You can think of a relay as a kind of electric lever: switch it on with a tiny current and it switches on ("leverages") another appliance using a much bigger current.
Why Relay’s are useful?
As the name suggests, many sensors are incredibly sensitive pieces of electronic equipment and produce only small electric currents. But often we need them to drive bigger pieces of apparatus that use bigger currents. Relays bridge the gap, making it possible for small currents to activate larger ones. That means relays can work either as switches (turning things on and off) or as amplifiers (converting small currents into larger ones).
How Relays work?
Note: The below concept is a extract from http://www.explainthatstuff.com/howrelayswork.html
When power flows through the first circuit (1), it activates the electromagnet (brown), generating a magnetic field (blue) that attracts a contact (red) and activates the second circuit (2). When the power is switched off, a spring pulls the contact back up to its original position, switching the second circuit off again.
This is an example of a "normally open" (NO) relay: the contacts in the second circuit are not connected by default, and switch on only when a current flows through the magnet. Other relays are "normally closed" (NC; the contacts are connected so a current flows through them by default) and switch off only when the magnet is activated, pulling or pushing the contacts apart. Normally open relays are the most common.
Active Buzzer:
Buzzer is an audio signalling device, which is broadly classified into piezoelectric or electromagnetic based on its structure. Additionally, buzzer can be classified into active and passive ones by the signal source. As for the active buzzer, if the rated voltage is put, then the periodic frequency signal can be generated at the inside of oscillator. The periodic signal can drive the buzzer voice. While as for the passive buzzer, it can be viewed as a horn. If and only if a changing electronic signal is added onto the buzzer, it can make a sound.
Difference between Active Buzzer Vs Passive Buzzer:
An Active Buzzer will generate a tone (or sound) using an internal oscillator, so all that is needed is a DC voltage, whereas a Passive Buzzer requires an AC signal to make the sound. Passive Buzzer is like an electromagnetic speaker, where a changing input signal produces the sound, rather than producing a tone automatically (like in Active Buzzer). The sound frequency is fixed in Active Buzzer and can send out the voice of a single frequency, whereas Passive buzzer can make sound under different frequencies.
Here we are going to use Active Buzzer and this how an Active Buzzer will look like:
The Active Buzzer has 3 pins (as shown in the above diagram):
Pin 1: is connected to Ground (marked with – symbol next to it)
Pin 2: is a DC Voltage input pin of +5V, usually connected to pin 2 of Raspberry Pi.
Pin 3: is Signal pin (marked with S Symbol next to it), typically connected to any GPIO pins of Raspberry Pi.
RaspiCam:
The Raspberry Pi Camera Module can be used to take high-definition video, as well as stills photographs. It is a custom designed add-on for Raspberry Pi. It attaches to Raspberry Pi by way of one of the two small sockets on the board upper surface. This interface uses the dedicated CSI interface, which was designed especially for interfacing to cameras. The CSI bus is capable of extremely high data rates, and it exclusively carries pixel data. More details on how to setup the Raspberry Pi Camera module can be found in my other blog (http://agilerule.blogspot.com/2016/07/how-to-setup-raspberry-camera-on.html)
What is Twilio?
Twilio is powering the future of business communications, enabling developers to embed voice, VoIP, and messaging into applications. They virtualize all infrastructure needed in a cloud-based, global environment, exposing it through the Twilio communications API platform. Applications are simple to build and scalable. Enjoy flexibility with pay-as-you go pricing, and benefit from cloud reliability.
Twilio Voice allows your applications to make and receive phone calls. Twilio SMS enables your applications to send and receive SMS messages. Twilio Client allows you to make VoIP calls from any phone, tablet, or browser and supports WebRTC.
Here we are going to Twilio SMS feature to send MMS to registered mobile numbers. For more details, please refer the following links:
https://www.twilio.com/docs/api/rest/sending-messages#post
Dependencies:
Software:
  • Pi4j
  • Java
  • Maven (Please find my blog here on how to install Maven on Raspberry Pi)
  • Twilio Java SDK

Hardware:
  • Raspberry Pi (installed with Java, Maven)
  • 9 Jumper wires
  • PIR Motion Sensor
  • 4 Channel Relay
  • Breadboard
  • GPIO Ribbon Cable
  • Thick Electrical Wire (4Ft) for 3 pin
  • 3 pin plug (to be connected to end of Electrical Wire)
  • 3 pin socket with Switch (to be connected to other end of the Electrical Wire). The Switch here is optional.
  • Wire Cutter
  • Small Screw Driver (to screw the wiring to the Relay)
  • Insulation Tape
  • Knife (or any equivalent device) to cut the thick Electrical Wire
  • Buzzer
  • Rasi Cam


Steps:
1.  Complete the following Wiring process of Raspberry Pi, 4 Channel Relay, PIR Motion Sensor, Buzzer and with few jumper wires as shown in the below diagram. Raspi Cam to be connected to the black slot in Raspberry Pi which is located between Ethernet port slot and HDMI slot. Ensure that the Raspberry Pi is in Power OFF mode, while doing the wiring process.
Wiring Diagram:

Breadboard Diagram:
Relay Connections:
1)  A wire from Pin 12 (GPIO 1) to Relay IN1
2)  A wire from Pin 2 (5 V Power) to Relay VCC (+)
3)  A wire from Pin 6 (Ground) to Relay GND (-)
PIR Motion Sensor Connections:
4)  A wire from Pin 16 (GPIO 4) to PIR Motion Sensor Signal
5)  A wire from Pin 2 (5 V Power) to PIR Motion Sensor Power (+)
6)  A wire from Pin 6 (Ground) to PIR Motion Sensor GND (-)
Active Buzzer Connections:
7)  A wire from Pin 18 (GPIO 5) to Active Buzzer Signal (S)
8)  A wire from Pin 2 (5 V Power) to middle line of Active Buzzer
9)  A wire from Pin 6 (Ground) to Active Buzzer GND (-)
Raspi Cam Connection:
10) Camera to be connected to the black slot in Raspberry Pi which is located between Ethernet port slot and HDMI slot

2.  Once the above connection is complete, Power ON the Raspberry Pi. Now connect to Raspberry Pi using Putty with your Raspberry Pi Credentials and by-default, you will in the path /home/pi. 
3.  For proper organization purpose, I created folders (using mkdir command) \projects. But this is not mandatory. You can even skip this step and move to next step.
mkdir projects
4.  From the \projects folder, execute the following command to Git clone the code to your local raspberry Pi.
git clone https://github.com/agilerules/IOT.git
5.  Once the git clone is complete, you will see IOT folder created in \projects folder. Now go to IOT folder (using the command cd IOT) and you will see the folder iot-pi4j-raspi-relay inside this folder IOT.
6.  Move to this iot-pi4j-raspi-relay folder (using the command cd iot-pi4j-raspi-relay)
7.  Now run the following commands to perform maven clean and maven package. (Incase if mvn command is not recognized then it means that maven is not installed on your Raspberry Pi.  Please follow my blog on how to install Maven on Raspberry Pi.
mvn clean
mvn package
8.  Now execute the following command to start the maven build and run the Java class RelayWithMainsNMotionSensorNBuzzerNCam.java in standalone mode. (Incase if mvn command is not recognized then it means that maven is not installed on your Raspberry Pi.  Please follow my blog on how to install Maven on Raspberry Pi.
mvn exec:java -Dexec.mainClass="relay. RelayWithMainsNMotionSensorNBuzzerNCam" -Dexec.classpathScope=runtime
9.  If all the wiring is done correctly, and once you run the Java program - the PIR Motion sensor will keep looking for any human movements and as and when it encounters a movement, it will trigger a 5V and turn ON the LED in the IN1 Relay (of 4 channel Relay), which in-turn will turn ON the Light bulb connected to Mains. Buzzer will start buzzing, Raspi Cam will take the snaps and send the photos as MMS to registered user as an alert. If there is no movement, the PIR Motion Sensor will not trigger a 5V, which will turn OFF the LED in the IN1 Relay (of 4 channel Relay), which in-turn will turn OFF the light bulb connected to Mains.
10. Here is the source code explanation below:
The complete project structure is available here:
a) pom.xml:
The below is the library dependency that we need for this application:
pi4j-core – This is for Pi4J to communicate with Raspberry Pi GPIO pins.
pi4j-device – This is for Pi4J to communicate with Relay.
twilio-java-sdk  - This is required for using Twilio REST API’s to send the MMS to mobile.
<dependencies>
            <dependency>
                  <groupId>com.pi4j</groupId>
                  <artifactId>pi4j-core</artifactId>
                  <version>1.1-SNAPSHOT</version>
            </dependency>
<dependency>
                  <groupId>com.pi4j</groupId>
                  <artifactId>pi4j-device</artifactId>
                  <version>1.2-SNAPSHOT</version>
            </dependency>
<!--  Twilio is required to SMS/MMS -->
            <dependency>
                  <groupId>com.twilio.sdk</groupId>
                  <artifactId>twilio-java-sdk</artifactId>
                  <version>6.3.0</version>
                  <scope>compile</scope>
            </dependency>
   </dependencies>

Note: 
At the time of wiring this program, the Pi4j 1.1 is available as a SNAPSHOT version and is not available in Maven repository yet. So had to use the OSS Sonatype Repository URL.
<repository>
            <id>oss-snapshots-repo</id>
            <name>Sonatype OSS Maven Repository</name>
            <url>https://oss.sonatype.org/content/groups/public</url>
            <snapshots>
                  <enabled>true</enabled>
                  <updatePolicy>always</updatePolicy>
            </snapshots>
</repository>

b) RelayWithMainsNMotionSensorNBuzzerNCam.java:
This java class has one method named controlRelayCircuit(), which will control the Relay Circuit by switching it ON and OFF. Here are the steps involved:
1.  Pi4j programs can be run with sudo user only. But with version 1.1, it is no more required if the program is enabled to run with Non Privileged Access using the following command.
//This is required to enable Non Privileged Access to avoid applying sudo to run Pi4j programs
GpioUtil.enableNonPrivilegedAccess();

2.  As shown in the wiring diagram section, we are going to use the GPIO pin 1 (GPIO_01) of Raspberry Pi to communicate with IN1 relay of 4 Channel Relay Circuit. Now provision this pin as output pin with Pin State as HIGH (means Relay OFF) while initializing.
System.out.println("LED's on Relay will turn ON..");
GpioPinDigitalOutput relayLED1 = gpioRelayLED1.provisionDigitalOutputPin(RaspiPin.GPIO_01,"RelayLED1",PinState.HIGH); //OFF

3.  Now initialize the PIR Motion Sensor by provisioning the GPIO pin 4 as Input pin with Pin Pull Resistance as PULL_DOWN.
System.out.println("PIR Motion Sensor is looking for any movement!!!..");
//Create gpio controller for PIR Motion Sensor listening on the pin GPIO_04       
final GpioController gpioPIRMotionSensor = GpioFactory.getInstance();
final GpioPinDigitalInput pirMotionsensor = gpioPIRMotionSensor.provisionDigitalInputPin(RaspiPin.GPIO_04, PinPullResistance.PULL_DOWN);

4.  Now initialize the Buzzer by provisioning the GPIO pin 5 as Input pin with Pin Pull Resistance as PULL_DOWN.
//Create gpio controller for Buzzer listening on the pin GPIO_05 with default PinState as LOW                   
           final GpioController gpioBuzzer = GpioFactory.getInstance();          
final GpioPinDigitalOutput buzzer = gpioBuzzer.provisionDigitalOutputPin(RaspiPin.GPIO_05,"Buzzer",PinState.LOW);
   buzzer.low();

5.  Now add event listener to the PIR Motion Sensor and if the PIR Motion Sensor event is High (whenever it encounters a human movement) then it will trigger the Relay as Low (which means it will Power ON to Electrical Light) with a message displaying as "Intruder Detected!, Relay is ON and Light is ON". Also it will take snaps by invoking the takeSnap() method. Similarly if the PIR Motion Sensor event is Low (whenever there is no human movement) then it will trigger the Relay as High (which means it will Power OFF to Electrical Light) with a message displaying as "All is quiet, Relay is OFF and Light is OFF”.
//Create and register gpio pin listener on PIRMotion Sensor GPIO Input instance           
         pirMotionsensor.addListener(new GpioPinListenerDigital() {
                 
public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) {
//if the event state is High then print "Intruder Detected" and turn the Relay and Light ON by invoking the low() method
                        if(event.getState().isHigh()){ 
System.out.println("Intruder Detected!, Relay is ON and Light is ON");
                        relayLED1.low(); //ON
try {
                              //Take two snaps from Camera Module
                                    takeSnap();
                              } catch (Exception e) {
System.out.println("Exception happened while taking the Snap..");
                                    e.printStackTrace();
                              }
                    }  
//if the event state is Low then print "All is quiet.." and make the Relay and Light OFF by invoking the high() method
                    if(event.getState().isLow()){  
System.out.println("All is quiet, Relay is OFF and Light is OFF");
                        relayLED1.high(); //OFF
                    }
                  }
         });
a) takeSnap() method:
This method will take two snaps by invoking the raspistill command and the file name will follow the format snap_<dateformat_in_yyyyMMddHHmmss>.jpg
raspistill --timeout 5 --output snap_" + dateTime + ".jpg –nopreview

The above command can be executed using exec() function of Runtime instance. Once the snap is taken, the method sendMMS() is invoked, which will send the MMS to the mobile number to alert him about possible intruder.
/**
       * Takes two snaps with the file name as "snap_<dateformat_in_yyyyMMddHHmmss>.jpg" with nopreview
       * @throws Exception
       */
      public void takeSnap() throws Exception
        {
        
          Runtime rt = Runtime.getRuntime();
          TwilioMMS twilioMMS = new TwilioMMS();
System.out.println("Raspberry Camera is going to take 2 snaps...");
          System.out.println("Started taking the snaps...");
          for (int i=1; i<=2; i++)
          {
            long before = System.currentTimeMillis();
            //The below raspistill command will take photos with the image name as "snap_<dateformat_in_yyyyMMddHHmmss>.jpg" with nopreview
String dateTime = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
            String fileName="snap_" + dateTime + ".jpg";
            Process snap = rt.exec("raspistill --width 400 --height 300 --timeout 1 --output " + fileName + " --nopreview");
            snap.waitFor(); // Sync
            long after = System.currentTimeMillis();
            System.out.println("Snapshot Take #" + i + " is complete in " + Long.toString(after - before) + " ms. You can view the snap snap_" + dateTime + ".jpg in the project root folder i.e inside \\iot-pi4j-raspi-relay ");
            File snapFile = new File(fileName);
//Move the file to Apache root folder path /var/www/html/images/
if(snapFile.renameTo(new File("/var/www/html/images/" + snapFile.getName()))){
System.out.println("File "+snapFile.getName()+" is moved successfully to /var/www/html/images/");
            }else{
System.out.println("File "+snapFile.getName()+" is failed to move!");
         }
            //Send MMS message using Twilio to the recipient mobile number
            twilioMMS.sendMMS(fileName);
          }
         
          System.out.println("Completed taking the snaps..");
        
}
b) sendMMS(fileName) method:
The method will send the MMS to the mobile number to alert him about possible intruder and for this, it will make use of the Twilio REST API’s.  This method takes the String parameter which is the name of the image that Raspi Cam has taken.
i)   Register TwilioRestClient with the ACCOUNT_SID and AUTH_TOKEN value. These values will be fetched from Twilio console.
// Find your Account Sid and Token at twilio.com/user/account
public static final String ACCOUNT_SID = "<Your_Twilo_Account_SID_Here>";
public static final String AUTH_TOKEN = "Your_Auth_Token_Here";
TwilioRestClient client = new TwilioRestClient(ACCOUNT_SID, AUTH_TOKEN);

ii)  Build the required parameters to send to MMS by populating the List with instance of BasicNameValuePair().
a) To is the number for which the SMS need to be send(i.e country code, followed by number. If US, it is +1 followed by number), 
b) From is the Twilio registered number (i.e country code, followed by number. If US, it is +1 followed by number)
c) Body is the message that need to be send as MMS
d) MediaURL is the image URL, which will be part of the MMS.
// Build the parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
   params.add(new BasicNameValuePair("To", "<Mobile_No_for_which_you_want_to_send_SMS>"));
params.add(new BasicNameValuePair("From", "<Your_Twilio_Registered_Number>"));
params.add(new BasicNameValuePair("Body", "Possible Intruder at home. Please check the snap here."));
params.add(new BasicNameValuePair("MediaUrl", "https://khjdtkbm.p71.weaved.com/images/"+mediaURL));
            //params.add(new BasicNameValuePair("MediaUrl", mediaURL));

Note that https://khjdtkbm.p71.weaved.com/images is the Raspberry Pi ‘s domain address that is created by registering my Raspberry Pi on weaved.com (www.weaved.com). This will help me to get a global address of my Raspberry Pi, which can be accessed anywhere from the internet.  More details on how to register your Raspberry Pi IP address on Weaved.com is available in my other article here.
iii) Create instance of messageFactory and invoke create() method by passing the parameter List created in the above step. This will send the MMS to the mobile number mentioned it the TO parameter in the above step. The image URL mentioned in the MediaURL will be listed in the MMS. Since the Twilio trial account is used, the MMS will have the additional text saying “Sent from your Twilio trial account.”
MessageFactory messageFactory = client.getAccount().getMessageFactory();
      Message message;
            try {
System.out.println("About to send MMS using Twilio to the mobile number..");
                  message = messageFactory.create(params);
System.out.println("MMS is successfully send using Twilio and the SID of the message is: "+message.getSid());
            } catch (TwilioRestException e) {
System.out.println("Error while sending the SMS from Twilio..");
                  e.printStackTrace();
            }

6.  Run this program in loop until the user hits Ctrl+C to exit from the loop.
try {          
                // keep program running until user aborts
                for (;;) {     
                    //Thread.sleep(500); 
                }      
            }          
            catch (final Exception e) {        
                System.out.println(e.getMessage());    
            }finally{
                  System.out.println("LED's on Relay IN1 will turn OFF..");
                  relayLED1.high(); //OFF
         }
7.  That’s the end of the tutorial. Hope it was useful.

1 comment:

  1. I ‘d mention that most of us visitors are endowed to exist in a fabulous place with very many wonderful individuals with very helpful things.
    Surya Informatics

    ReplyDelete