Here I will outline my adventures in learning how to connect a PIR (passive inftared) sensor to my raspberry pi 3 in order to sense motion and turn off the monitor / display to my magic mirror when nobody is around and automatically turn on when someone stands in front of it.

Major Components

First, let’s dive through the items you will need (with links to them on amazon):

1) Raspberry Pi 3 (I used Model B)
I am not going to go through the install process of the raspberry pi. I am going to assume you have it running the latest raspbian already.

2) PIR Sensor
I did some research and it looks like the Adafruit PIR sensor was the way to go.  You can purchase any kind you like.

3) Pin Connectors
I am new to this, so I bought this cheap little kit.

4) Crimping Tool
Again, I am new to this, so I bought the cheapest option available.  I don’t expect to be using this often.

Again, I am new to this, so I bought the cheapest option available.  I don’t expect to be using this often.

Understanding Pin & Wiring Configuration

The hardest part for me was figuring out the pins and wiring.  So let’s tackle that first.  Let’s gather the parts we need and assemble the pir sensor and connectors.

Parts Needed to Complete Wiring Assembly

NOTE: The cable in the photo is the finished product, it should have bare cable at the end with the black pieces when you start.

  1. PIR Sensor
  2. 3x 2.54mm 1P Dupont Connector Housing
  3. 3x Dupont Female Pin Connector
  4. PIR Sensor Cable
Passive infrared sensor parts laid out on a table and labeled.
PIR Sensor and Parts

Crimp the ends of the wires into the female pin connectors then slide them into the connector housing.  When you are done the cable should look like it does above.

Connecting the PIR sensor to the GPIO Pins

Now that your cable is ready to go, let’s see what these cables do.
If you look at the bottom of the PIR sensor, you will see 3 pins (pictured above).  If you look really hard at the board (base of the pins) you will see they are labeled.  I am old, so I use a jewelers loop or magnify glass to read them.

Passive Infrared Sensor Pin Labels magnified

As you can see they are labeled:

  • GRD (Ground)
  • OUT (Control Channel)
  • +5V (5 Volt Power)

The “Control Channel” is probably called something else.  What the PIR sensor does is send a small change in voltage to this pin to tell it something has changed.  This is how the board knows when there is motion, by sensing this small change in voltage.

For more expert information on how PIR sensors work, there is a great resource on the adafruit website here.

When you connect your three pin connect (white on cable) to the board, you want to ensure the black cable is on the GRD (Ground) side and red is on the 5V (power side).
Now we have to connect the cables to the corresponding pins on the board of the Pi.  Before we do, it is a good idea to understanding the pin numbering scheme and the pinout (which pin does what).

Here is an image I found somewhere explaining the pin numbering.

Raspberry Pi GPIO Pin diagram
Raspberry Pi 3 GPIO Pin Numbers

Here is an image I found on the interwebs showing the pinout.  The numbers on this chart are the “GPIO Numbers” which are different from the pin numbers.

Raspberry Pi GPIO Pin diagram
Raspberry Pi GPIO Diagram

You can find more information about GPIO from the raspberry pi GPIO documentation.So we need to connect the red cable to a 5 Volt power pin, the black cable to a ground, and the yellow cable to a control pin.  This is how I chose to connect to the board:

  • Red to Pin 2 (5v)
  • Block to Pin 6 (Ground)
  • Yellow to Pin 11 (Control)

NOTE: I am using the small numbers aligning with the inside of the pins on the diagram.

Now that we have the PIR sensor all cabled up and connected to the Pi board, we need some software to test it.

Create Script to Test Connectivity

Open a terminal or ssh into your Raspberry Pi.  We are going to create a python script so open your favorite editor (I use VIM, again, because I am old) but you can use nano or anything your comfortable with.  I called the file test.py.

Add the following lines to the file:

import RPi.GPIO as GPIO
import time
import subprocess

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(11, GPIO.IN)
while True:
i=GPIO.input(11)
if i==0:
print "Not Sensing Motion",i
time.sleep(0.1)
elif i==1:
print "Motion Detected",i
time.sleep(0.1)

Make sure you keep the indents, python is pretty picky about those sorts of things.  Also, if you chose to use a different pin that I did, you will need to change the GPIO.setup and GPIO.input lines to reflect your pin number.

Now we have all the pieces we need to run our first test.

Ensure the PIR sensor is facing away from you so you do not trigger it.  Then on the command line and in the same directory that you made the above file, type the following to run the script:

$ python test.py

It should start scrolling either “Not Sensing Motion” or “Motion Detected”.  If it is saying “Not sensing motion” that means the PIR sensor is sending a low output to the board because it doesn’t “see” anything.  If you wave your hand in front of it, it should raise the output to the board and print out “Motion Detected”.

NOTE: There is sleep in the script so it might take a very short time to change.

If this worked, your PIR sensor is now setup and ready to be used by the Raspberry Pi. If it didn’t work, you will have to try some troubleshooting. Make sure the pins are in the correct place, make sure all your wire connections are good, check the connector to the PR sensor is on correct, etc…  Feel free to comment below and I will try to chime in and help if I can.

Creating the Code to Allow the PIR Sensor to Interface with Raspberry Pi

Now that I have my PIR sensor working, I need a script to constantly run and look for motion.  When it see’s motion, it will turn the monitor on, after a short delay, it will turn the monitor off and wait to see motion again.

I found a website that was doing something similar but for a photo frame.  We will be adjusting his script to work for our needs.

For this to work, we need two bash scripts, one to turn the monitor on, and on to turn the monitor off.
NOTE: There are several ways to turn the monitor off from the command line, I chose the vcgencmd command because it was the quickest and least destructive.

Create a file called monitor_on.sh and add the following lines:

vcgencmd display_power 1 > /dev/null

Now create a file called monitor_off.sh and add the following lines:

vcgencmd display_power 0 > /dev/null

Set both of these files to be executable:

chmod +x monitor_o*

You can test these by running the commands or the scripts, but do it via SSH so your display doesn’t turn off and leave you typing in the dark.
Running this command:

./monitor_off.sh

Should turn off your monitor, and running:

./monitor_on.sh

Should turn it back on.

Now we make the python script a new file, I called mine pir.py, with the following lines:
NOTE: You might have to change the paths to the scripts.

 
#!/usr/bin/env python

import sys
import time
import RPi.GPIO as io 
import subprocess

io.setmode(io.BOARD)
SHUTOFF_DELAY = 3 # seconds
PIR_PIN=11

def main():
    io.setup(PIR_PIN, io.IN)
    turned_off = False
    last_motion_time = time.time()
    while True:
        if io.input(PIR_PIN):
            last_motion_time = time.time()
            sys.stdout.flush()
            if turned_off:
                turned_off = False
                turn_on()
        else:
if not turned_off and time.time() > (last_motion_time + SHUTOFF_DELAY):
                turned_off = True
                turn_off()
            if not turned_off and time.time() > (last_motion_time + 1):
        time.sleep(.1)
def turn_on():
    subprocess.call("sh /home/pi/MagicMirror/monitor_on.sh", shell=True)

def turn_off():
    subprocess.call("sh /home/pi/MagicMirror/monitor_off.sh", shell=True)

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        io.cleanup()

This sets the shutoff delay to 3 seconds for testing.  Once I am sure it works as intended I will change the line:

SHUTOFF_DELAY = 3 # seconds

to

SHUTOFF_DELAY = 600 # seconds is 10 minutes

So the device stays on for a while.

Enabling Script to Run Automatically on Boot

I would like to make this script run automatically in the background and start on boot.  In order to do that I am adding it to the autostart file location in ~/.config/lxsession/LXDE-pi.

I just add the following line:

@sudo /usr/bin/python /home/pi/MagicMirror/pir.py

That’s it.. Make some adjustments to suite your neeeds and have fun!