Infrared is a kind of light we can’t see without special equipment, but we sometimes feel as heat. It’s called “infrared” because it occurs beyond the red edge of the visible light spectrum.
This interests device builders partly because people, animals, and objects always broadcast infrared light.
While that might sound odd, you’re likely already familiar with something similar: fire, which gets so hot it casts heat and visible light.
Though fire reaches a high enough heat that it will visibly give out light, our bodies don’t, and the light we give out – infrared – can’t be seen by the human eye.
By using a component that’s wonderfully cheap, available, durable, reliable, and economical with power, we can do just that!
It’s called a “passive infrared motion sensor,” more commonly called a ‘passive infrared sensor” or even just “PIR sensor.”
A PIR motion sensor consists of a lens over a pair of pyroelectric sensors: a crystal material that produces a voltage when it receives infrared light.
But objects that contain any amount of heat emit some infrared. That means a single pyroelectric sensor would always produce a voltage, even when everything in view is totally still.
So how do you turn that into a motion sensor? It’s simple yet clever. The two pyroelectric sensors are connected in such a way that the signals from the ambient infrared cancel each other out.
When something large enough and warm enough moves in front of the lens, the two signals stop canceling out, and the sensor reports that something’s moving.
When you connect a PIR motion sensor to power, it needs 30 to 60 seconds to stabilize. Otherwise, it can fire false positives in this time, and this can be a headache in some circuits. With a Raspberry Pi project, it’s easy to write software that tells it to wait a short while after booting.
The greater problem is with false positives from animals, insects, or even gusts of wind triggering the sensor.
You can usually calibrate the component to be less sensitive, and this will stop your cat or small dog from triggering it. It’s less useful for insects flying directly in front of it
Don’t let these false positives be a dealbreaker, though; just think about how to handle them gracefully.
There are many ways to interface a PIR motion sensor with your Raspberry Pi, from visual programming tools like Scratch down to close-to-the-metal code like C.
Here, we’ll use Python with the GPIO Zero library, which sorts out most of the small details for us.
If you’ve never written a line of Python before, you might want to try a few tutorials from Automate the Boring Stuff With Python. If you don’t, the code below will still work; you’ll just get more out of this if you can follow along.
This project also assumes a basic understanding of the GPIO pins. If they’re brand new to you, check out the past guides. Otherwise, there’s a diagram below that should remind you of the basics.
To get started building your Raspberry Pi Motion sensor, you’ll need:
|A Raspberry Pi with power supply and an SD card with Raspbian installed|
|A GPIO extension board (optional, but recommended)|
|A PIR motion sensor
(I’m using an XC-4444)
You’ll also need something that will let you type, such as a USB keyboard or an SSH connection.
Viewing this XC-4444 from the back, with the pins on the bottom, the pins are as follows:
• the left is for 5-volt power
• the middle is the digital output
• the right is for ground
While PIR motion sensors tend to be much the same, these pins may be ordered differently on another model. Check your component’s specifications if you’re unsure.
Connect the Raspberry Pi’s 5-volt power pin to the positive power rail of your breadboard, then the ground pin to the negative rail.
Then, with the lens facing away from you, connect the motion sensor’s power pin to the positive power rail, the ground pin to the negative rail, and the digital output somewhere in the middle of the breadboard.
Finally, connect that breadboard row to a GPIO pin; I’m using pin 13.
It’s time to write a quick script. Head to the command prompt and open a text editor by typing:
GPIO Zero has a class for our motion sensor already built, so let’s import that, along with the sleep function from the time module.
from time import sleep
from gpiozero import MotionSensor
Now let’s write a function to print a message to the screen when the sensor detects motion.
The sleep command says to wait 5 seconds after printing our message. Without this, our script will fill the whole screen with messages for the duration of the pulse, which makes it harder to follow along with what’s going on.
This detectIntruders() function won’t work if we don’t initialise the MotionSensor object, so let’s set it to pin 13:
pir = MotionSensor(13)
Can you believe we’re almost done? We just need a loop to run our function.
Press Ctrl+O to save the script, and Ctrl+X to exit the text editor. To run it, type:
Now get up and walk past the sensor. Did it print a message?
If it didn’t work, check that all the pins are correctly connected. It’s really easy to get the ground and power pins of a PIR motion sensor mixed up.
To stop this script, press Ctrl+C.
There are two pots on this XC-4444: one marked Tx for pulse length, another market Sx for sensitivity.
It might be useful to adjust the pulse length for some projects, though I tend to leave it short and instead write code to handle how the Raspberry Pi responds to the signal.
The sensitivity pot is more interesting. You use this to adjust how much motion the sensor needs to detect to emit a signal.
Some PIR motion sensors have more controls. These often vary whether the pulse continues for as long as motion is detected or whether the module sends repeated pulses.
The simple principles we just explored are useful for much more than alarms.
They’re handy for all kinds of home automation projects: lighting, climate control, opening doors, or even some professional wrestling style entrance music when you come home from work.
If you want to know when someone’s there, it’s your friend.