Let's set up our Raspberry Pi with the necessary operating system and software so we can detect motion and record videos.

This guide is now a couple of years old and although it is still valid, new software and hardware has been released that supersedes what follows. Read the updated version of this guide.

Just joining in? Head over to How to Build a Raspberry Pi Trail Cam - Part 1 to get started.

Download and install the operating system

Just like any modern day computer, the Raspberry Pi needs an operating system installed so we can interact with it. There are various operating systems available to use, each with their own benefits, however, I chose a recently released minimal version of Raspian called Jessie Lite. The reason for choosing this was because it doesn't include all the desktop software which means it runs faster and is 'lighter' overall. The upshot of this is that you can only use the command line to issue instructions (there is no GUI). Of course, a full desktop version of Raspbian Jessie is available should you need it but for the rest of this series, I'll be working on the assumption that we're using Jessie Lite. All the steps and commands we use should be the same for both versions of the operating system.

Head over to the Raspberry Pi website and download your operating system. While you're there, check out the instructions on how to write the OS image to your SD card.

Boot up the Raspberry Pi for the first time

Ok, you should now have your SD with your OS installed on it. Go ahead and insert it into the Raspberry Pi.

If you have a keyboard, mouse and monitor, you can attach all of these peripherals and poweer up your Raspberry Pi. After a couple of minutes, you should end up with a command prompt. If you don't have any of these peripherals don't worry, with a few more steps we can access the Raspberry Pi headlessly. Just follow the next section.

Accessing the Raspberry Pi without a monitor

To access your Raspberry Pi without connecting a monitor and keyboard, we need to use something called a Secure SHell (SSH). We do this be connecting the Pi to the same network as our other computer, then once we've found the Pi's address, we can access it using an SSH client. It's a little bit like remotely controlling another computer but it will all be done from the command line. So go ahead and connect your ethernet cable to the Raspberry Pi and plug it into your network (router). Power up the Pi and while it's booting up, lets work out what IP address it's using.

Find the Raspberry Pi's IP address

There are several ways to find the IP address of a machine on your local netowrk. For Windows users, I recommend Advanced IP Scanner (Mac users can use AngryIP Scanner). Once installed, just click scan and it will return all the devices connected to your local network. It should be obvious which one the Raspberry PI is. Note down the IP address of the Pi - it'll probably be something like 192.168.x.x.

Connect to the Raspberry Pi

I mentioned that we'll need an SSH client to talk our Pi. If you're using a Mac, good news, you can use the built in Terminal app. Once open, type

ssh 192.168.x.x

Replacing the numbers with your Pi's IP address.

If you're using Windows, download PuTTY (putty.exe - usually the top link). Once the app is open, type the IP address of your Pi into the box and make sure the SSH option is selected. Click Open.

PuTTY Configuration screenshot

You'll be prompted to login as a user. The default username is pi and the password is raspberry.

PuTTY login screenshot

You should now be successfully logged into the Raspberry Pi - excellent. Now we need to run a few commands to set up the Pi. One of the first things to do is make sure everything is up to date.

sudo apt-get update

And then

sudo apt-get upgrade -y

These two commands bring all the exisiting software up to date. The -y flag in the second command will bypass many of the prompts you would get asking you to confirm the upgrade. The upgrade can take several minutes so you can go away and make a coffee while this goes on.

Now we need to install a few libraries to allow us to write the program that will do the video capturing:

sudo apt-get install python3 python3-dev git i2c-tools python3-pip python3-gpiozero python-gpiozero python-picamera -y

sudo pip3 install gpiozero picamera RPi.GPIO spidev

sudo apt-get install gpac -y

Thanks to Richard Hayler for compiling these commands

Once complete, let's ensure our camera will work by enabling the interface:

sudo raspi-config

Then using the keyboard, select the Enable Camera option and select Yes.

Raspi-config screenshot

Let's also make sure we're using all of our SD card's capacity and Expand the Filesystem by selecting the top option. Once done, you can select Finish. You don't need to reboot just yet (but if you do you'll have to connect to the Pi again as above).


Quick Recap

We're now at a point where we have installed the operating system, updated and upgraded all the software on the Pi, installed some extra packages to help with the video capture and enabled our camera interface. Now is a good time to shut down the Pi and connect some of the other peripherals such as the camera and the PIR sensor.

sudo halt

After a minute or so, disconnect the power from the Raspberry Pi.

Attaching the camera and PIR sensor

Now that your Pi is powered down disconnect it from any ethernet and power cables.

To attach the camera, follow these instructions from the Pi Hut. Make sure the ribbon is firmly housed. If you are using a Raspberry Pi Zero, you'll need a slightly different camera ribbon that fits the camera port on the Pi. 

Raspberry Pi with camera module attached

To attach the PIR, you will need three jumper wires. The PIR should have three pins, power, signal and ground. Orienting the PIR so the pins are on the top edge, from left to right the pins read ground (purple), signal (yellow) then power (white).

The pins connect to the Raspberry Pi as follows:

Power (white): Pin 2

Signal (yellow): Pin 11

Ground (purple): Pin 14

See this diagram for a details illustration of the Pi's GPIO pins. It's important that these are wired correctly because doing it wrong can have cause problems!

Re-attach the network cable and power cable and log into the Pi again.

Set up the motion detection software

Now we're going to write a program to capture video from the camera when motion is detected by the PIR. We do this using a simple text editor called Nano, save the file and make set up the Raspberry Pi to run the program every time the Pi starts.

Once logged in, create a file called trailcam.py.

nano trailcam.py

You'll be presented with a blank document so paste in the following (if you right-click the mouse in PuTTY, this will paste the code).


from gpiozero import MotionSensor
import logging
from datetime import datetime
from subprocess import call
import picamera
import time
import os

if not os.path.exists('/home/pi/trailcam_log'):

if not os.path.exists('/home/pi/videos'):

logfile = "/home/pi/trailcam_log/trailcam_log-"+str(datetime.now().strftime("%Y%m%d-%H%M"))+".csv"
logging.basicConfig(filename=logfile, level=logging.DEBUG,
    format='%(asctime)s %(message)s',
    datefmt='%Y-%m-%d, %H:%M:%S,')

pir = MotionSensor(17)


# Wait an initial duration to allow PIR to settle

while True:
    logging.info('Motion detected')
    print('Motion detected')
    while pir.motion_detected:
        print('Beginning capture')
        ts = '{:%Y%m%d-%H%M%S}'.format(datetime.now())
        logging.info('Beginning capture: '+ str(ts)+'.jpg')
        with picamera.PiCamera() as cam:
            cam.annotate_background = picamera.Color('black')

            start = datetime.now()
            while (datetime.now() - start).seconds < 30:
                cam.annotate_text = "Peak Nature "+datetime.now().strftime('%d-%m-%y %H:%M:%S')
        timestamp = datetime.now().strftime('%d-%m-%y_%H-%M-%S')
        input_video = "/home/pi/video.h264"

        logging.info('Attempting to save capture')

        if os.path.isdir('mnt/usb/videos'):
            logging.info('Saving to /mnt/usb/videos/')
            output_video = "/mnt/usb/videos/{}.mp4".format(timestamp)
        elif os.path.isdir('mnt/usb1/videos'):
            logging.info('Saving to /mnt/usb1/videos/')
            output_video = "/mnt/usb1/videos/{}.mp4".format(timestamp)
        elif os.path.isdir('mnt/usb2/videos'):
            logging.info('Saving to /mnt/usb2/videos/') 
            output_video = "/mnt/usb2/videos/{}.mp4".format(timestamp)
            logging.info('Saving to /home/pi/videos/')
            output_video = "/home/pi/videos/{}.mp4".format(timestamp)

        call(["MP4Box", "-add", input_video, output_video])
    print('Motion Ended')
    logging.info('Motion Ended')

Edit: Recently, I had been noticing the camera had started recording videos resulting in 0kb (i.e. empty files). In the comments, YM A pointed out that this may be due to the PIR firing too soon after the recording had ended. So I've changed the line: time.sleep(0.5) to time.sleep(5) to leave a longer interval between recordings.

Save the file CTRL+X then Y.

Saving the video to a USB stick

Before we can test the program, we need to set up the location of where the videos are going to be saved. I'm intending to use 2 separate USB sticks to save the videos to. This way, I can leave the camera in position and simply swap the USB sticks so I can take them home and view the videos. To make this work, I'm going to make sure I use the same USB port (if your Pi has more than one) each time I swap out a USB stick. When we power on the Pi we want to make sure the USB stick is automatically recognised and 'mounted' so that when we save a video, it's saved to the USB stick.

Insert a USB stick into one of the ports and make sure you note which one you use.

Type the command:

sudo blkid

This should show you the devices attached to your Pi. In my case, I was looking for /dev/sda1 which was labelled Kingston (the brand of my memory stick).

Create a directory or 'mount point' for the videos to be saved. There is mileage in doing this for each USB port on your Pi so that if you attach the USB drive to a different port, it will still be mounted. Depending on the model you have the number of USB ports will be 1-4, therefore replace  with the port number accordingly.

sudo mkdir /mnt/usb/videos

And set the permissions for it

sudo chown -R pi:pi /mnt/usb

And to auto-mount it

sudo nano /etc/fstab

Add the following line to the bottom of the file replacing /dev/sda1 with the location your USB stick was attached to (it might be the same as mine)

/dev/sda1 /mnt/usb vfat auto,users,rw,uid=1000,gid=100,umask=0002 0 0

CTRL+X and Y to save and exit.

Restart your Pi for good measure

sudo reboot


Once logged in again, test your program with. You might have to do this as sudo.

python trailcam.py

If all goes well, you should see some messages being printed on the screen. Move your hand over the PIR sensor and the LED on the camera should come on for about 30 seconds which is the duration of the recording. This can be altered in the program if required.

Once recording is complete the video should be saved to the specified mount point and the screen should print the message Motion Ended. If you see this, hit CTRL+Z to stop the program. You can unplug the USB stick and plug it into another computer to check whether the recording worked.


Of course, there is a possibility that things didn't go as expected. If so, let me know in the comments and I'll try and help as best I can. A couple of things I ran into are detailed below:

If you are receiving errors telling you there is no module called gpiozero try 

sudo apt-get remove python3-gpiozero python-gpiozero


sudo apt-get install python3-gpiozero python-gpiozero

Similarly, if you the error mentions the picamera module, try:

sudo apt-get install python-picamera

Start the program automatically

When the trail cam is deployed in the field, it won't be possible to log in and start the trailcam.py program so we need to configure the Raspberry Pi to do this automatically. We can edit out rc.local file to start the program when the Pi boots up:

sudo nano /etc/rc.local

At the bottom of the file (before the exit 0 line) add the following line

/usr/bin/python3 /home/pi/trailcam.py &

Save the file with CTRL+X then Y.

Round up

Hopefully you now have a working trail camera - if somewhat unfinished. Well done so far! In Part 3 I'll be looking at adding a Real Time Clock (RTC) to the trail cam and then making an enclosure for it.