Thank you for being here for today's tutorial of our in-depth Raspberry Pi programming tutorial. The previous tutorial taught us how to construct a heart rate monitor based on the Raspberry Pi and display the data in the Processing IDE to keep tabs on a patient's heart rate. In this guide, you'll learn how to install a PIR sensor on a Raspberry Pi to create a motion detector. A passive infrared (PIR) sensor is a straightforward yet effective tool for monitoring motion. These sensors saw heavy use in traditional, older-generation security systems.
In contrast, video is used in the vast majority of today's systems. At the bottom of this page, I discuss the sensor further. As a bonus, a piezo speaker will play an audio clip whenever motion is detected. GPIO pins are required for both of these accessories. This tutorial is a great starting point for those who have never worked with electronic components and circuits. If you want to build courses, getting a breadboard is a must.
Components
An infrared proximity sensor for Raspberry Pi and a piezo speaker are required tools for this project.
Raspberry Pi
PIR Sensor
Piezo Speaker
100-ohm resistor
PIR sensor
Infrared motion detectors, also known as passive infrared (PIR) sensors, are a type of motion sensor that makes use of IR light to identify and locate sources of motion.
Anything, alive or otherwise, having a temperature greater than zero degrees Celsius emits infrared radiation. The wavelength of infrared radiation is far greater than that of visible light, making it invisible to the human eye.
That's why there are things called passive infrared (PIR) sensors, which are specifically made to detect heat signatures. As their name implies, passive motion sensors don't put out any rays of their own but instead pick up on them when other objects emit infrared radiation, making them ideal for use in intruder alarm devices. However, active detectors may produce and detect infrared light at the same time.
How it works
Using the PIR Sensor with the Raspberry Pi is easy. When the infrared detector detects movement, it sends a signal to the computer through the data input, which goes HIGH. The RPI will trigger the alarm if it detects a 1 on the corresponding input pin. The infrared sensor, BISS0001 IC, and other components of a motion detector were employed in this experiment.
The motion sensor has three pins: one for power, one for data, and one for ground. The Motion Sensor features two potentiometers that may be adjusted to fine-tune the PIR sensitivity and the amount of time its output signal stays high after detecting motion. Important infrared light is focused onto the Pyroelectric Sensor by a Fresnel lens mounted on top of the sensor. The PIR sensor's incredible field of view of 1200 degrees is made possible by this lens. The sensor can detect human movement within an 8-meter radius around it.
Crystals sensitive to infrared light are used as sensor. The sensing component consists of two subassemblies, A and B.
When there is no motion, the two detectors pick up identical infrared readings, which cancel out one another. To begin with, sensing element A will pick up on the presence of infrared light when an infrared-emitting object, such as a dog, enters the sensor's field of vision. Since the intensity of the infrared light striking sensing element B is still relatively low, the resulting differential change is positive.
As the object moves past the sensor, the intensity of the infrared light falling on sensing element B will be greater than that falling on sensing element A, resulting in a negative differential change. The BISS0001 logic chip onboard detects and amplifies this potential difference before outputting it as a digital signal that the Raspberry Pi can read.
PIR Sensor Adjustments
The sensor and the output's timing can be adjusted with two separate potentiometers. Potentiometers allow you to adjust the sensor's sensitivity. Distances between 3 and 8 meters are adjustable. The Potentiometer can be turned clockwise to enhance the detection range and counterclockwise to decrease it.
The second Potentiometer controls the duration of the motion sensor's HIGH output. Times might be anything from 0.3s to 600s. The POT can be adjusted by turning it clockwise (to add time) or counterclockwise (to subtract time).
How to Install a PIR Sensor on a Raspberry Pi
A passive infrared (PIR) sensor and a piezo speaker will be the basis for the primary circuit we'll be building.
You'll typically find a PIR sensor in a security system, where it will detect motion and then trigger the alarm. When they sense a shift in infrared temperature, they know there's activity around. Time and sensitivity are usually adjusted independently on most PIR sensors through the included screws. Depending on how much time you want to delay the alarm, you can do so (Sending a high signal). (Two to four seconds, roughly) The sensitivity indicates how little motion must occur before the alarm sounds.
A piezo buzzer is an easy-to-use speaker that makes noise whenever an electric current passes through it. The buzzer will sound an audible alert when the motion detection circuit is activated. If you still need a breadboard, I recommend getting one for this project. A breadboard simplifies circuit prototyping and construction. Connect them directly to the Pi 4 without using a breadboard as I am.
Just follow these steps to build the circuit.
Connect a pin to the breadboard's ground rail.
Connect the breadboard's positive rail with the 5v pin.
Pin 7 and the ground pin are where you should attach the piezo buzzer (Black wire).
Connect pin 11 to the circuit breadboard with a wire. Connect a resistor of 100 ohms to the wire's terminal. The PIR sensor's yellow wire should be connected to this.
The PIR sensor's red wire must be connected to the breadboard's 5v line, while the black wire must be connected to the ground rail.
Code Explanation
We'll need programming to make our Pi 4 Motion sensor circuit work. This is a great way to get started with Python, and the programming is as simple as our primer on the Raspberry Pi's GPIO pins. This section will provide a high-level overview of the code and describe what it does.
We begin by importing the GPIO and time Python libraries, allowing us to communicate with the GPIO rail and halt the script. For our first two variables, which I have aptly dubbed "pins," we provide a reference to our physical ports. Our sensors' states will be kept in the now-valued state variable. If this value is zero, it is not turned on; if it is one, it is turned on. We'll change our GPIO mode to use the real PINs rather than the physical ones. Since each pin is given a unique number, this system is a tad simpler. We also configured our GPIO pins as inputs or outputs. To do things like detect motion, we'll plug in a PIR sensor. On the flip side, we need our piezo buzzer to function as an output.
import RPi.GPIO as GPIO
import time
pir_sensor = 11
piezo = 7
GPIO.setmode(GPIO.BOARD)
GPIO.setup(piezo,GPIO.OUT)
GPIO.setup(pir_sensor, GPIO.IN)
current_state = 0
A while loop that never ends appears below. Due to the inherent permanence of the conditional statement, this loop can always be maintained. (You can still hit ctrl + c on the terminal to abort the script). To begin, we'll pause the script for 0.1 seconds. The next step is to retrieve the sensor's current state; if that state is 1 (for instance, the motion has been detected), the code within the if statement will be executed. If the value is not 1, we enter an infinite loop in which the sensor is repeatedly checked.
The if statement executes code that sets the piezo buzzer's output high, causing it to sound. This will occur for a split second before the script silences the buzzer. As soon as that timer expires, the if statement will leave, and the sensor will be rechecked after another five seconds. We have also used a try, except, finally, block with a nested outer block. Since stopping the script will require using the keyboard, we have included this. Finally, we must verify our script is tidy by calling GPIO.cleanup(). With the help of the try, except finally, coding construct, we can accomplish this.
try:
while True:
time.sleep(0.1)
current_state = GPIO.input(pir_sensor)
if current_state == 1:
print("GPIO pin %s is %s" % (pir_sensor, current_state))
GPIO.output(piezo,True)
time.sleep(1)
GPIO.output(piezo,False)
time.sleep(5)
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()
Running the Script
After you have completed all of your changes to the script, you may run it and see how it performs. Put the following command into your keyboard to accomplish this.
sudo python motion_sensor.py
The piezo buzzer should activate and make a noise if the PIR sensor detects motion in its field of view. If it doesn't, it's probably because you connected wires to the incorrect pins or because of a bug in the program. The Raspberry Pi's terminal will show an error message if it's a coding mistake.
Complete code
#!/usr/bin/env python
import RPi.GPIO as GPIO
import time
pir_sensor = 11
piezo = 7
GPIO.setmode(GPIO.BOARD)
GPIO.setup(piezo,GPIO.OUT)
GPIO.setup(pir_sensor, GPIO.IN)
current_state = 0
try:
while True:
time.sleep(0.1)
current_state = GPIO.input(pir_sensor)
if current_state == 1:
print("GPIO pin %s is %s" % (pir_sensor, current_state))
GPIO.output(piezo,True)
time.sleep(1)
GPIO.output(piezo,False)
time.sleep(5)
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()
Output
Quiz: Send data to your phone using an LTE modem
This section is meant to test your understanding of this article, so I am leaving it as some homework for you. Build the circuit and comment below what the output will be. I will give an idea of the circuit and python code.
The LTE modem
Based on the success of GSM/EDGE and UMTS/HSPA, the Long-Term Evolution (LTE) standard was developed to ensure the continued development of wireless broadband communication. My LTE modem is a USB add-on for the Raspberry PI, giving it 3G or 4G (LTE) cellular data access. The modem is not used for cellular access in this project; instead, it is used to notify my phone of motion through text messages. The AT commands and serial connectivity allow me to command the modem and relay messages to my phone.
Connection
Step 1: Install the software
Begin by loading the required software onto your Raspberry Pi. Enter the terminal of the Raspberry Pi:
sudo apt install python3 python3-gpiozero python-serial -y
Step 2: Set up the modem
The TRM240 LTE modem requires a SIM card, which can be inserted here. To improve the modem's signal, attach the antenna to the top of the device.
Third, link the cellular modem to the Pi.
Plug the LTE modem into a free USB port on the Raspberry Pi and power it on. The /dev directory should now list four additional USB ports. Just type this into the terminal to verify:
ls /dev/ttyUSB*
These gadgets should now be visible to you.
Sending AT commands to the device will be done through the ttyUSB2 port.
Fourth, link up the sensor with the Pi.
The sensor output pin should be connected to the 8-pin to the Raspberry Pi, and the VCC and GND pins should be connected to the appropriate pins on the Pi.
Connect the LED lights:
The cathode of the LED should be connected to a ground pin, the anode (longer leg) should be connected to a current-limiting resistor, and the other portion of the resistor should be connected to a GPIO pin to cause the indicator LEDs to illuminate when motion is detected. Input the green LED into the 40-pin connector and the red LED into the 38-pin connector on the board. This is a discretionary procedure. You can disable the LED sections in the sample code below if you don't want them to light up in response to the motion.
Launch the program below
from gpiozero import MotionSensor, LED
from time import sleep, time
from sys import exit
import serial
import threading
# Raspberry Pi GPIO pin config
sensor = MotionSensor(14)
green = LED(21)
red = LED(20)
# Modem configuration
device = '/dev/ttyUSB2'
message = '<message>'
phone_number = '<phone_number>'
sms_timeout = 120 # min seconds between SMS messages
def setup():
port.close()
try:
port.open()
except serial.SerialException as e:
print('Error opening device: ' + str(e))
return False
# Turn off echo mode
port.write(b'ATE0 \r')
if not check_response('OK', 10):
print('Failed on ATE0')
return False
# Enter SMS text mode
port.write(b'AT+CMGF=1 \r')
if not check_response('OK', 6):
print('Failed on CMGF')
return False
# Switch character set to 'international reference alphabet'
# Note: this still doesn't support all characters
port.write(b'AT+CSCS="IRA" \r')
if not check_response('OK', 6):
print('Failed on CSCS')
return False
return True
def check_response(string, amount):
result = ''
try:
result = port.read(amount).decode()
except:
return False
if not string in result:
try:
# Write 'ESC' to exit SMS input mode, just in case
port.write(b'\x1B \r')
except:
return False
return string in result
def send_sms():
global currently_sending, last_msg_time
currently_sending = True
try:
port.write('AT+CMGS="{}" \r'.format(phone_number).encode())
if not check_response('>', 6):
print('Failed on CMGS')
currently_sending = False
return
# Write the message terminated by 'Ctrl+Z' or '1A' in ASCII
port.write('{}\x1A \r'.format(message).encode())
while True:
result = port.readline().decode()
if 'OK' in result:
print('> SMS sent successfully')
last_msg_time = time()
currently_sending = False
return
if 'ERROR' in result:
print('> Failed to send SMS [{}]'.format(result.rstrip()))
currently_sending = False
return
except:
# Initiate setup if the got while the program was running
setup()
currently_sending = False
def on_motion():
print('Motion detected!')
green.off()
red.on()
if time() - last_msg_time > sms_timeout and not currently_sending:
print('> Sending SMS...')
threading.Thread(target=send_sms).start()
def no_motion():
green.on()
red.off()
print('* Setting up...')
green.on()
red.on()
port = serial.Serial()
port.port = device
port.baudrate = 115200
port.timeout = 2
last_msg_time = 0
currently_sending = False
if not setup():
print('* Retrying...')
if not setup():
print('* Try restarting the modem')
exit(1)
print('* Do not move, setting up the PIR sensor...')
sensor.wait_for_no_motion()
print('* Device ready! ', end='', flush=True)
green.on()
red.off()
sensor.when_motion = on_motion
sensor.when_no_motion = no_motion
input('Press Enter or Ctrl+C to exit\n\n')
As mentioned above, I will not give the output for this program; instead, let me know if you were successful.
Conclusion
This is a basic introduction to the PIR sensor and merely scratches the surface of its potential uses. Simple things like a counter (which adds up as people, cars, or other objects pass by) can trigger far more complex actions, such as turning on a Pi camera or running a new script. I'm hoping you've learned a lot from this Pi 4 motion sensor tutorial and that you've been able to put together a beautiful circuit and make it work with some code. Feel free to leave a remark below with your views, questions, or complaints. In the subsequent tutorial, we'll learn how to connect a 7-segment display to a Raspberry Pi 4.