Saturday, November 12, 2016

IOT: Java + Raspberry Pi + Pi4j+ PIR Motion Sensor + Buzzer + LED + Camera Module


Objective: The Objective of this exercise is to make the LED glow, active Buzzer to buzz and Camera module to take two snaps - when the PIR Motion Sensor configured on Raspberry Pi detects any movement (or intruder) and displays a message in the console saying “Intruder Detected!, LED is ON and Buzzer is ON”, with the snap location details. If no movement is detected, it will print “All is quiet, LED is OFF and Buzzer is OFF”.
YouTube Video:
The YouTube Video for this tutorial is available at this link.
GitHub Source:
https://github.com/agilerules/IOT/tree/master/iot-pi4j-sensors
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.
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.
Dependencies:

Software:
  • Pi4j
  • Java
  • Maven (Please find my blog here on how to install Maven on Raspberry Pi)

Hardware:
  • Raspberry Pi (installed with Java, Maven)
  • 3 Jumper wires
  • LED
  • 220 Ohm Resistor
  • PIR Motion Sensor
  • Active Buzzer
  • RaspiCam (Camera Module)
  • Breadboard
  • GPIO Ribbon Cable
Steps:
1.  Complete the following Wiring process of Raspberry Pi, LED, Resistor, PIR Motion Sensor, Active Buzzer and with few jumper wires as shown in the below diagram.
Wiring Diagram:
Breadboard Diagram:

  1. A wire from Pin 6 to Ground ( - on Breadboard)
  2. A wire from Pin 12 (GPIO_1) to + line on Breadboard
  3. Fix the LED and the long end of LED Anode (+) to be connected to Resistor (Yellow side on top of Resistor)
  4. Other end of Resistor (i.e the red colour on top) to the + line of Breadboard
  5. LED Cathode (-) to – line of Breadboard
  6. PIR Motion Sensor Power pin to Pin 2 (+5V Vc Power)
  7. PIR Motion Sensor Middle pin to Pin 16 (GPIO 4)
  8. PIR Motion Sensor GND (Ground) Pin to – line of Breadboard
  9. Active Buzzer – to GND (Ground) Pin to – line of Breadboard
  10. Active Buzzer S (Signal) to Pin 22 (GPIO 6)
  11. Active Buzzer Middle pin to Pin 2 (+5V Vc Power)
  12. Camera to be connected to the black slot in Raspberry Pi which is located between Ethernet port slot and HDMI slot




2.  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-sensors inside this folder IOT.
6.  Move to this iot-pi4j-sensors folder (using the command cd iot-pi4j-sensors)
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 PirMotionDetectionBuzzerAndCamera.java in standalone mode. 
mvn exec:java -Dexec.mainClass="com.agilerrules.pi4j.sensors.PirMotionDetectionBuzzerAndCamera" -Dexec.classpathScope=runtime

9. If there is any movement before the sensor, you will see the message “Intruder Detected!, LED is ON and Buzzer is ON”, along with the following logs from Camera module:
Raspberry Camera is going to take 2 snaps, be ready...
Snapshot Take #1 is complete in 4207 ms. You can view the snap snap_20160722144107.jpg in the project root folder i.e inside \iot-pi4j-sensors
Snapshot Take #2 is complete in 764 ms. You can view the snap snap_20160722144111.jpg in the project root folder i.e inside \iot-pi4j-sensors
Completed taking the snaps..
If there is no movement then you will see the message “All is quiet, LED is OFF and Buzzer is OFF
10. Incase if you need to terminate the program, press Ctrl+C.
11. 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.
<dependencies>
            <dependency>
                  <groupId>com.pi4j</groupId>
                  <artifactId>pi4j-core</artifactId>
                  <version>1.1-SNAPSHOT</version>
            </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)  PirMotionDetectionAndBuzzer.java:

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.  Create gpio controller for PIR Motion Sensor listening on the pin GPIO_04 using the following Pi4j Libraries.
final GpioController gpioPIRMotionSensor = GpioFactory.getInstance();
final GpioPinDigitalInput pirMotionsensor =      gpioPIRMotionSensor.provisionDigitalInputPin(RaspiPin.GPIO_04, PinPullResistance.PULL_DOWN);

3.   Now create gpio controller for LED listening on the pin GPIO_01 with default PinState as LOW.
//Create gpio controller for LED listening on the pin GPIO_01 with default PinState as LOW                   
         final GpioController gpioLED = GpioFactory.getInstance();          
final GpioPinDigitalOutput led = gpioLED.provisionDigitalOutputPin(RaspiPin.GPIO_01,"LED",PinState.LOW);
led.low();

4.   Now create gpio controller for Buzzer listening on the pin GPIO_06 with default PinState as LOW.
    
   //Create gpio controller for Buzzer listening on the pin GPIO_06 with default PinState as LOW                   
   final GpioController gpioBuzzer = GpioFactory.getInstance();         final GpioPinDigitalOutput buzzer = gpioBuzzer.provisionDigitalOutputPin(RaspiPin.GPIO_06,"Buzzer",PinState.LOW);
   buzzer.low();

5.  Now create and register gpio pin listener on PIRMotion Sensor GPIO Input instance to listen for pin state changes and perform the following action:
     a) If the event state of PIR Motion Sensor is high then print the message “Intruder Detected!, LED is ON and Buzzer is ON” and turn the LED ON, make the buzzer ON  by invoking the high() method on their respective variables and finally call the takeSnap() method to take the snap using Camera module.
      b) If the event state is Low then print " All is quiet, LED is OFF and Buzzer is OFF" and make the LED OFF and make the buzzer OFF by invoking the low() method on their respective variables.
//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 LED ON by invoking the high() method
                        if(event.getState().isHigh()){ 
                        System.out.println("Intruder Detected! LED is ON and                              Buzzer is ON");
                        led.high();

buzzer.high();
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 LED OFF by invoking the low() method
                    if(event.getState().isLow()){  
                        System.out.println("All is quiet, LED is OFF and                                   Buzzer is OFF");
                        led.low();

buzzer.low();
                    }
                  }
        });

      c)  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.
      /**
  *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();
          System.out.println("Raspberry Camera is going to take 2 snaps, be        ready...");
          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());
            Process snap = rt.exec("raspistill --timeout 5 --output snap_" + dateTime + ".jpg --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-sensors ");
          }
          System.out.println("Completed taking the snaps..");
  }


5.   Now loop the program until the user aborts with CTRL+C
   try {          
                // keep program running until user aborts
                for (;;) {     
                    //Thread.sleep(500); 
                }      
            }          
            catch (final Exception e) {        
                System.out.println(e.getMessage());    
            }
6.   That’s the end of the tutorial. Hope it was useful.

1 comment: