Raspberry Pi Motion Detector with Photo Capture

This project shows how to take photos with a Raspberry Pi when motion is detected. It can be used as a burglar detector, to take wildlife photos or in other applications. We’ll be using a Raspberry Pi V2 camera and the code will be written in Python programming language.

Note: this project is an excerpt from our “20 Easy Raspberry Pi Projects” book. If you want to build electronics projects with the Raspberry Pi using Python, we recommend reading our Raspberry Pi Projects book. It’s available in digital and paperback version. 

Prerequisites

You might also like: What’s the Best Raspberry Pi Camera For Your Project?

Parts Required

Project Overview

The circuit for this project consists of a PIR motion sensor, a pushbutton, and a camera module you’ll connect to your Pi. The pushbutton is an extra component that allows you to stop the Python script.

To program the Raspberry Pi we’ll be using a Python script and the built-in picamera library, which makes it very simple to control the camera. To control the GPIOs we’ll be using the gpiozero library that contains classes for most popular components like pushbuttons, LEDs, motion sensor, etc.

Enable the Camera

You need to enable your Raspberry Pi’s camera software before you can use the camera module. In the desktop environment, go to the main menu and select Preferences > Raspberry Pi Configuration. Select the Interfaces tab and a window as shown below should open.

Alternatively, in the Terminal window, type the following command:

pi@raspberry:~ $ sudo raspi-config

You should see the Raspberry Pi software configuration tool. Select the Interfacing Options:

Enable the camera and reboot your Pi:

Connect the Camera

With the camera software enabled, shut down your Pi and then connect the camera to the CSI port. Make sure the camera is connected with the blue letters facing up and oriented as shown in the following figure. Then start up your Pi again.

Build the Circuit

With the camera connected, follow the next  schematic diagram to wire the rest of the circuit.

  • Pushbutton: GPIO 2
  • PIR motion sensor: GPIO 4

Note: the PIR motion sensor we’re using in this project should be powered using the 5V pin. Other sensors required 3.3V to operate. Read your sensor’s specifications before wiring the circuit.

Writing the Script

To control the camera, you’ll use the built-in picamera library. Here’s an overview of what the code should do:

  1. Initialize the camera.
  2. Take a photo when the PIR motion sensor detects movement.
  3. Save the photos in your Desktop folder.
  4. Name the photos incrementally so you know what order they were taken in—for example, image_1.jpg, image_2.jpg, and so on.
  5. Stop the camera when the pushbutton is pressed. If you don’t include this feature, you won’t be able to exit the camera preview that pops up on your screen.

Entering the script

Create a new file using Python 3 (IDLE) and copy the following code. Then, save the code in the Desktop folder with the following name: burglar_detector.py.

#Project 13 - Burglar Detector With Photo Capture
#latest code updates available at: https://github.com/RuiSantosdotme/RaspberryPiProject
#project updates at: https://nostarch.com/RaspberryPiProject

#import the necessary packages
from gpiozero import Button, MotionSensor
from picamera import PiCamera
from time import sleep
from signal import pause

#create objects that refer to a button,
#a motion sensor and the PiCamera
button = Button(2)
pir = MotionSensor(4)
camera = PiCamera()

#start the camera
camera.rotation = 180
camera.start_preview()

#image image names
i = 0

#stop the camera when the pushbutton is pressed
def stop_camera():
    camera.stop_preview()
    #exit the program
    exit()

#take photo when motion is detected
def take_photo():
    global i
    i = i + 1
    camera.capture('/home/pi/Desktop/image_%s.jpg' % i)
    print('A photo has been taken')
    sleep(10)

#assign a function that runs when the button is pressed
button.when_pressed = stop_camera
#assign a function that runs when motion is detected
pir.when_motion = take_photo

pause()

View raw code

How the code works

First you import the necessary libraries; as we’ve said, the program uses the picamera library to control the camera. The gpiozero library contains classes to control the pushbutton and the motion sensor: Button and MotionSensor. The sleep method allows us to deal with delays, and the pause method is used to handle interrupts.

from gpiozero import Button, MotionSensor
from picamera import PiCamera
from time import sleep
from signal import pause

Then, you create objects to refer to the pushbutton, the PIR motion sensor, and the camera. The pushbutton is on GPIO 2 and the motion sensor on GPIO 4.

button = Button(2)
pir = MotionSensor(4)
camera = PiCamera()

Then, initialize the camera with camera.start_preview().

camera.start_preview()

Depending on how your camera is oriented, you might also need to rotate it 180 degrees so that it doesn’t take the photos upside down.

camera.rotation = 180

Next, you initialize an i variable that starts at 0.

i = 0

Then, we create the stop_camera() and the take_photo() functions that will be called later in the code.

The take_photo() function, will use the i variable to count and number the images, incrementing the number in the filename by one with each picture taken.

def take_photo():
  global i
  i = i + 1
  camera.capture('/home/pi/Desktop/image_%s.jpg' % i)
  print('A photo has been taken')
  sleep(10)

To take and save a photo you use the camera.capture() method, specifying the directory you want to save the image to inside the parentheses. In this case, we’re saving the images in the Desktop folder and naming the images image_%s.jpg, where %s is replaced with the number we incremented earlier in i.

If you want to save your files to a different folder, replace this directory with the path to your chosen folder. You then impose a 10-second delay, meaning the camera takes photos at 10-second intervals for as long as the PIR sensor detects movement. Feel free to increase or decrease the delay time, but be careful to not overload the Pi with tons of images by making the delay time too small.

The stop_camera() function stops the camera with the camera.stop_preview() method.

def stop_camera():
  camera.stop_preview()
  #exit the program
  exit()

This function stops the camera preview and exits the program. The exit() function pops up a window asking if you want to close the program; to close it, just click OK.

Finally, you define that when the pushbutton is pressed, the cameras stops.

button.when_pressed = stop_camera

Finally, you tell the camera to take a photo by triggering the take_photo() function when motion is detected.

pir.when_motion = take_photo

The pause() at the end of the code keeps your program running so that interrupts can be detected.

Demonstration

If your’re using Python IDLE to write your code, press F5 or go to Run > Run Module to run the script. While the script is running, you should see a preview of what the camera sees on your screen. To shut down the camera preview, press the pushbutton and click OK in the window that pops up.

Alternatively, in the Terminal window you can type:

pi@raspberrypi:~ $ python3 burglar_detector.py

Congratulations, you project is ready to detect motion and take some photos. You can place this project in a strategic place and come back later to check any saved photos. The following figure shows a photo taken by this project.

Wrapping Up

Using cameras with the Raspberry Pi is an easy task and can be applied to a wide variety of projects. The picamera and gpiozero libraries give you an easy way to control the camera and GPIOs with the Raspberry Pi.

We have other projects with cameras and Raspberry Pi that you may like:

This is an excerpt from our book “20 Easy Raspberry Pi Projects“. For an overview of our book, you can watch the video below.

» Get a copy (paperback version) of our Raspberry Pi book »

We hope you’ve found this project useful.

Thank you for reading!



Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »

Recommended Resources

Build a Home Automation System from Scratch » With Raspberry Pi, ESP8266, Arduino, and Node-RED.

Home Automation using ESP8266 eBook and video course » Build IoT and home automation projects.

Arduino Step-by-Step Projects » Build 25 Arduino projects with our course, even with no prior experience!

What to Read Next…


Enjoyed this project? Stay updated by subscribing our newsletter!

11 thoughts on “Raspberry Pi Motion Detector with Photo Capture”

  1. Only one slight mistake for me – I’d change the word “Burglar” to “Squirrel” – that’s what I’m after photographing! (Trees right outside my apartnent, and the lil’ buggers don’t know they’re supposed to hibernate about now-ish! ). 🙂

    Reply
  2. Naive question: If the motion sensor were placed in front of a computer screen, could I detect a change in the screen and then take a picture? Example: RPi on front of external monitor attached to windows machine, screen changes, picture is taken?

    Reply
    • Andrew, PIR sensor recognises infrared (p – I – r), not screen picture changing. Computer screen can show moving object but this living pictures don’t generate infrared or changing infrared.

      Reply
  3. The author forgot to mention that this script only works if the RPI is connected to internet. Probably it is a requirement of gpizero library but I did not find it out jet.
    Hence, useless if you want to use it in the nature for bird watching, for instance.

    Reply
  4. I’ve used the PIR sensor before and its not very sensative to smaller animals like squirrels. Has anyone tried this sensor, “RCWL-0516 Microwave Radar Motion Sensor” it looks like it’s much more sensative and can be modified to have a much shorter range (1.5meters). Works on RF not body heat.

    Reply
  5. The code did not work. Error reprt: Camera is not enabled. Testing camera with othe codes it works fine. Is this due to the new set up for raspebbry pi with python since the configuration tool does not have the camera enable option any longer. This should be included in the set up now.

    Reply

Leave a Comment

Download Our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.