5.4 Unit-V Developing Sensor Based Application Through Embedded Platform Part II

You might also like

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 9

Connecting to a Sensor to Detect

Motion
To demonstrate how to use the GPIO to connect to an external sensor, we'll now use
a PIR motion sensor to detect motion. For this, I used the Parallax PIR Motion
Sensor (see Figure 9). The PIR Sensor detects motion by measuring changes in the infrared
(heat) levels emitted by surrounding objects of up to three meters.

Figure 9: The Parallax PIR Motion Sensor


The Parallax Motion sensor has three pins (see Figure 10):
 GND: The ground pin. Connect this pin to the GND on the GPIO.
 VCC: The voltage pin. Connect this pin to one of the 5V pins on the GPIO.
 OUT: The output pin. Connect this to one of the Input/Output pins on the GPIO.

Figure 10: The layout of the various pins on the PIR Motion Sensor
When the PIR Motion sensor detects motion, it outputs a high signal on its output pin. You
need to write an application to read the value of this output pin. Figure 11 shows a PIR
Motion sensor connected to the T-Cobbler Plus.
Depending on the PIR Motion Sensor that you're using, the arrangement of the various
pins isn't always in the same order as described. It's important to verify and connect
the correct pins to the correct GPIO pins. Connecting the wrong pins to the Raspberry
Pi can permanently damage the PIR Motion Sensor.
In the figure, the red line is the VCC and should be connected to the 5V pin on the GPIO. The
yellow line is the OUTPUT and is connected to pin #4 on the GPIO. The black line is the
GND and should be connected to GND on the GPIO.
Figure 11: A PIR Motion sensor connected to the Raspberry Pi

Bonding the Raspberry Pi and the


Sensors: The Python Programming
Language
Now that the Raspberry Pi is connected to the PIR Motion Sensor, it's time to write the code
to make things work. In the Raspbian OS, Python is a first-class citizen, and the support for
Python comes right out of the box. With its clean syntax and ease of learning, Python is a first
choice for hobbyists and beginners to foray into the world of the Raspberry Pi. Coupled with
the huge community support for Python, it's no wonder that it's the language of choice for
developers.

Open a Terminal window in the Raspbian OS and create a text file by typing the following
command:

$ nano motiondetection.py
The above command uses the NANO text editor and creates a file
named  motiondetection.py . Enter the statements as shown in Listing 1.
Listing 1. Source code for using a PIR Motion Sensor
import RPi.GPIO as GPIO #1

import time #2

pirsensor = 4 #3

GPIO.setmode(GPIO.BCM) #4
GPIO.setup(pirsensor, GPIO.IN, GPIO.PUD_DOWN) #5

previous_state = False #6

current_state = False

while True: #7

time.sleep(0.1) #8

previous_state = current_state #9

current_state = GPIO.input(pirsensor) #10

if current_state != previous_state: #11

if current_state: #12

print("Motion Detected!") #13

When you are finished typing in the code, exit the NANO editor by pressing Ctrl-X and then
pressing  Y  to save the file. Press Enter to save it to the current directory. To run the Python
script, type the following command in Terminal:

$ python motiondetection.py
Wave your hand in front of the PIR Motion Sensor. You should see the following output on
Terminal:

Motion Detected!

Dissecting the Code


Now that you've written your first Python code, it's useful to understand what it does and how
it works. We'll dissect the code line-by-line:

The RPI.GPIO is a library that allows your Python application to easily access the
GPIO pins on your Raspberry Pi.
 #1: The latest version of Raspbian includes the RPI.GPIO Python library pre-installed,
so you can simply import that into your Python code. The RPI.GPIO library allows your
Python application to easily access the GPIO pins on your Raspberry Pi. The  as  keyword
in Python allows you to refer to the RPI.GPIO library using the shorter name of GPIO.
 #2: The application is going to insert some delays in the execution, so you need to import
the time module.
 #3: You declare a variable named  pirsensor  to indicate the pin number for which the
Output pin on the PIR sensor is connected to the GPIO pin. In this example, it's GPIO pin
#4.
 #4: There are two ways to refer to the pins on the GPIO: either by physical pin numbers
(starting from pin 1 to 40 on the Raspberry Pi 2/3), or Broadcom GPIO numbers (BCM).
Using BCM is very useful with a ribbon cable (such as the Adafruit T-Cobbler Plus) to
connect the Raspberry Pi to the breadboard. The BCM numbers refer to the labels printed
on the T-Cobbler Plus (see Figure 8). For this example, we're using the BCM numbering
scheme. That means that when we say we're getting the input from pin 4, we're referring
to the pin printed as #4 on the T-Cobbler Plus.
 #5: Initialize the pin represented by the variable  pinsensor  as an input pin. Also, we use
a pull-down resistor (GPIO.PUD_DOWN) for this pin.
 #6: There are two variables to keep track of the state of the sensor.
 #7: We use an infinite loop to check the state of the sensor repeatedly.
 #8: Inserts a slight delay of 0.1 second to the execution of the program
 #9: Save the current state of the sensor.
 #10: The  GPIO.input()  function reads the value of the GPIO pin (#4 in this case).
When motion is detected, it returns a value of  true .
 #11: Compare the previous state and the current state to see if the motion sensor has a
change in state. If there's a change, it means that either the sensor has just detected
motion (when the state changes from  false  to  true ), or that the sensor is resetting itself
(when the state changes from  true  to  false ) a few seconds after motion has been
detected.
 #12: If the current state is  true , it means that motion has been detected.
 #13: Print out the string “Motion Detected!”
When the PIR Motion Sensor detects motion, its output will be 1 ( true ), and a few
seconds later, it's automatically reset to 0 ( false ).

Acting on the Sensor Data


Now that the PIR Motion sensor is sensing motion, let's put it to good use. A good
application of this project is to install the Raspberry Pi and the motion sensor at home to
monitor for unexpected movement. You could mount the sensor near your door to detect
movement outside the house when there's no one at home.

Once motion is detected, the Raspberry Pi could send a push notification to an Android
device via the Google Cloud Messaging (GCM). A detailed description of Android and GCM
is beyond the scope of this article, but here's what's required for an Android app to receive a
push notification:

 The developer of the Android application needs to apply for an API key
at https://console.developers.google.com.
 Once the Android application is installed on the device, it needs to register with Google
programmatically to obtain a registration ID. This registration ID uniquely identifies the
application on a particular device so that GCM can push a message to it.
Figure 12: How Google Push Notification works using Google Cloud Messaging (GCM)
Figure 12 summarizes the interaction between the various parties in a push notification
system. In particular, it shows how you can use the Raspberry Pi to send push notifications:
1. The Android app sends an activation request to Google's GCM Server.
2. When the registration is successful, the GCM Server returns a Registration ID to the app.
3. In the real world, the Registration ID should be sent to a server maintained by the
developer, who will then save it into a database.
4. The developer also needs to write another application to communicate with the GCM
server to send the push notification to a particular user(s). In this project, we'll use the
Raspberry Pi to send the message to a user via the GCM Server.
5. Once the GCM server receives the message, it sends the push notification to the app.
To send a push message via Google's GCM server, you can use a variety of programming
languages, such as C#, Python, Node.js, etc. Because Python is already supported in
Raspbian, it's natural to use it.

Open a  Terminal  window in the Raspbian OS and create a text file by typing the following
command:

$ nano pushgcm.py
Enter the statements as shown in Listing 2. Be sure to replace the <API_KEY> with that of
your own and the <Registration_ID> with that of the registration ID of the Android app
installed on a device.
Listing 2. Sending a Push Notification Message using Google Cloud Messaging (GCM)
import requests #1

import json #2
gcm_url = "https://android.googleapis.com/gcm/send"; #3

api_key = "<API_KEY>" #4

#replace <reg_id> with your own

reg_id = ["<Registration_ID>"] #5

headers = {'content-type':'application/json', #6

'authorization':'key=' + api_key}

#notification payload

data = { #7

"sender" : "Raspberry Pi",

"event" : "Motion Detected!"

#create a dictionary to store the data to post

post_data = {} #8

post_data['data'] = data #9

post_data['registration_ids'] = reg_id #10

#convert dictionary to JSON

post_data_json = json.dumps(post_data) #11

print

print "Data to post to GCM Server"

print "--------------------------"

print post_data_json

print "--------------------------"

print

#post the data to GCM Server


r = requests.post(gcm_url, data=post_data_json, #12

headers=headers)

print "Response from GCM Server"

print "------------------------"

print "Header : ", r.headers['content-type'] #13

print "Status : ", r.status_code

print "Text : ", r.text

print "--------------------------"

Dissecting the Code


As usual, it's useful to understand what the code is doing:

 #1: Import the Requests Python library that helps you to send HTTP requests to a server
easily without worrying about query strings, form-encoding your POST data, etc.
 #2: Import the JSON library so that you can print out the data that was sent to the GCM
server in JSON format.
 #3: The end point for Google's GCM server.
 #4: The API Key that you've obtained from Google. This identifies the application
developer sending the push notification.
 #5: The Registration ID(s) of the application receiving the notification. You get this
Registration ID from the application after it has registered with Google. In the real world,
this Registration ID should be sent to the server maintained by the developer to provide a
complete list of Registration IDs of the app installed on the users' devices. If you want to
send a push message to multiple recipients, separate the Registration IDs with commas
(,).
 #6: The HTTP header to sent to the GCM server to authenticate the identity of the sender.
 #7: The content of the push message. Here, you're sending two key/value pairs, indicating
who's sending the message and the event. For GCM push messages, you can send
multiple key/value pairs. The Android application receiving the push message simply
specifies the key(s) to extract the value(s).
 #8: You create a dictionary to store the content of the push message together with the
registration ID(s) of the recipient(s).
 #9: You set the content of the push message in the dictionary.
 #10: You set the recipient(s) of the push message.
 #11: You use the  json.dumps()  function to convert the  dictionary  object into a
JSON string so that you can print it out to examine its content.
 #12: You use the  requests.post()  function to post the push message to the GCM
server.
 #13: After the message was sent to the GCM server, it responds with the status. Here, you
print out the content type of the response, followed by the status of the HTTP request, as
well as the details of the sending (such as if the message was successfully sent or failed to
send, the ID of the message, etc.).
Before you can run the Python code to send a push notification to the Android device, you
need to download and install the Requests Python library. To do that, type the following
command in  Terminal :

$ sudo pip install requests


Once  Requests  is installed, type the following command to execute the  pushgcm.py  script:

$ sudo python pushgcm.py


If the push message is delivered successfully to the GCM server, you should create an output
similar to the following:

Data to post to GCM Server


--------------------------
{
"registration_ids": ["<Registration_ID>"],
"data": {
"event": "Motion Detected!",
"sender": "Raspberry Pi"
}
}
--------------------------
Response from GCM Server
------------------------
Header : application/json; charset=UTF-8
Status : 200
Text : {
"multicast_id":8838766867169688347,
"success":1,
"failure":0,
"canonical_ids":0,
"results": [
{
"message_id":"0:1461392749167691%62851a86f9fd7ecd"
}
]
}
--------------------------
To complete this project, you need to modify the  motiondetection.py  script so that when a
motion is detected, the  pushgcm.py  script is called to send a push notification to the Android
application. Listing 3 shows the addition.
Listing 3. Calling the pushgcm.py from motiondetection.py
import RPi.GPIO as GPIO

import time

import os #1

pirsensor = 4

GPIO.setmode(GPIO.BCM)
GPIO.setup(pirsensor, GPIO.IN, GPIO.PUD_DOWN)

previous_state = False

current_state = False

while True:

time.sleep(0.1)

previous_state = current_state

current_state = GPIO.input(pirsensor)

if current_state != previous_state:

if current_state:

print("Motion Detected!")

os.system("python pushgcm.py") #2

In line #1, you need to import the  os  module so that when motion is detected you can use
the  os.system()  function (in line #2) to perform a shell operation - specifically, to execute
the  pushgcm.py  script.

You might also like