I Bouvet er vi flere hundre teknologer som brenner for å programmere og utforme gode, digitale løsninger. I denne bloggen utforsker vi teknologien og deler det vi finner med dere.

Building a Motion Activated Security Camera with the Raspberry Pi Zero

Introduction and Motivation for Project

Recently my wife and I suspected that some unwanted guests had been visiting our garden.  After a discussion we decided that we needed a motion activated camera that could send us emails once it detected movement.  We also wanted the ability to view the live video stream from the camera on demand.

As a fully fledged Raspberry Pi geek I knew right away that I wanted to build my own solution.  My wife was not so convinced, and starting listing the dozens of unfinished projects I currently have on my backlog.  After promising her that I would see this project through to the bitter end I finally got permission to build a proof of concept 🙂

This project required no coding, but quite a bit of configuration. It took about 6-7 hours to complete once I had the parts in place.  I spent most of this time wrestling with Linux and this blog will hopefully help anyone attempting a similar project.


To reduce the projects overall complexity I decided that the camera would be mounted inside our living room.  This meant that the unit could be powered from the mains, and would be protected from the harsh Norwegian weather.

Below is a full list of the parts I used, along with current prices.  I already had some of these parts laying around from previous projects, so my total project cost came up to about $40.  If you need to purchase all of the below parts then I would suggest shopping around and looking into Pi Zero starter kits to keep your costs low.

Some notes about some of the specific parts:

  • The Combined WiFi Dongle and USB Hub has two USB ports, allowing me to connect a keyboard and optionally a mouse when setting up the Pi Zero for the first time.  The Pi Zero has only one mini USB port available, so this dongle is a worthwhile investment for the most Pi Zero projects.
  • I chose the Raspberry Pi NoIR Camera rather than the standard model as the NoIR can work in low light conditions (you’ll add need to add infrared lighting for this camera to perform well at night time).
  • The ZeroView Camera Mount allowed for easy mounting of the camera and Pi Zero on the inside of my terrace window.  It is a mount, not a case, and is not suitable for outside usage.
  • If you struggle to pick up the Raspberry Pi Zero you can always use a Raspberry Pi Model 2 or 3.  Both have CSI and USB ports and the Model 3 even has built-in WiFi.  If you choose to do this you will want to reevaluate using the ZeroView Camera Mount.

Once I had all the pieces in place it took less than 10 minutes to put my prototype together.

Assembled prototype mounted on the ZeroView with the USB Hub / WiFi dongle attached

Rear view of the assembled prototype – missing only the power cable

Configuring the Pi Zero

After assembling the parts I connected a keyboard and monitor to the USB Hub and switched on the Pi Zero.  After booting I installed Raspian Jessie 4.4 from NOOBS.

I configured the Pi Zero as follows, with frequent reboots underway…

From the terminal window run the command:

This will open the Raspberry Pi Configuration tool, from which you should do the following:

  • Enable the Camera.
  • Enable the ssh server (you’ll need this later on to connect to Pi Zero in headless mode – i.e. without a monitor and keyboard attached).
  • Enable boot to command line without manual login.

At the terminal prompt type enter:

to change your password from the default.  This will prevent tech savvy intruders from connecting to your Pi Zero using ssh and the default login and password.

Next you should set up a static IP address for your Pi Zero.  This will make it easier for you to connect to your Pi Zero and to expose it outside of your home network via port forwarding.  You can validate that your static IP address is working by connecting to your Pi Zero via ssh.

Now that you are connecting to the web, you can update Raspian Jessie by running:

If you forget to do this then I can promise that you will have problems later on!

Finally, Validate that your Raspberry Pi Camera is working.  If you experience any problems, check the ribbon cable between the Pi Zero and camera – it can easily be dislodged.

Once all the above is done you can disconnect the monitor and keyboard and connect to the Pi Zero via ssh to complete the rest of the below steps.

Choosing Motion for the Camera Software

My next step was to choose a software solution for my security camera.  My requirements were as follows:

  • Streaming video – so that I could check the video feed at will.
  • Motion detection and the ability to trigger events – so that I could send myself an email for each motion event.
  • Small footprint – due to the size of the SD card (8GB).
  • Low memory overhead – due to the capacity of the Pi Zero.
  • Linux compatible (well duh).
  • Compatible with the Raspberry Pi Camera (MMAL).
  • Configurable – allowing one to tweak the software to get the most out of the hardware.

I choose Motion as it fulfills the above requirements out of the box with no additional coding.  I also considered using the marvellous OpenCV, but felt that I would have spent more time having to tweak it to fulfill my needs.

Motion monitors an incoming camera stream and detects ‘motion’ by finding the pixel values that have changed from frame to frame.  If a threshold (i.e. total pixels changed) is exceeded then Motion triggers a «motion detected» event and optionally creates a snapshot of the video stream.  Motion includes an inbuilt webserver offering both a video stream and online configuration on the fly.

Installing Motion

Important : before installing Motion you must have updated Raspian Jessie by running the ‘sudo apt-get update‘ and ‘sudo apt-get dist-upgrade‘ commands.

I found that installing Motion from the deb release file worked best, probably because the Raspberry Pi Camera requires a specific release:

  1. First get the deb file with the following command (if this doesn’t work then have a look for the correct release file on the Motion project GitHub):
  2. Install the gdebi tool as follows:
  3. Install Motion using the gdebi tool (allow it to also install the minimal web server):
  4. Create a hidden folder in your home directory:
  5. Copy the original Motion config file to your new .motion directory.  This ensures that the original config file doesn’t get ruined (and can be used to return Motion to it’s ‘factory settings’).

Configuring Motion

Don’t bother trying to run Motion yet as it won’t work until you’ve updated the configuration file 🙂

You can open the configuration file in edit mode by entering:

Nano is a simple Linux text editor allowing you to edit and search text files.  Feel free to use an alternative text editor if you wish.

Below is a list of the parameters that I have tweaked for my setup.  Consult the manual for comprehensive documentation of these and other Motion parameters.  Note that the rest of these blog will assume that you have set these values as I have specified.

  1. Uncomment the mmalcam_name vc.ril.camera parameter.
  2. Uncomment target_dir and change it’s associated value to ’/home/pi/Documents/motion’
  3. Ensure that ffmpeg_output_movies is set to ‘off’
  4. Set stream_localhost to ‘off’
  5. Set webcontrol_localhost to ‘off’
  6. Set width to ‘640’ and height to ‘480’
  7. Set locate_motion_mode to ‘preview’
  8. Set locate_motion_style to ‘redbox’
  9. Set event_gap to ’10’
  10. Set output_pictures to ‘center’
  11. Set quality to ’80’
  12. Set text_changes to ‘on’

Feel free to play around with the configuration parameters to get a feel for what they do.  Be careful to keep a record of the parameters you have changed, in case you mess up and need to start again.  Remember that you always have a clean copy of the config file at  /etc/motion/motion.conf.

Running Motion for the First Time

Now you are finally ready to run Motion for the first time!  Use the following command to run Motion with your configuration file:

While Motion starts up, key an eye out for any error messages that pop up.  Problems can occur if your camera isn’t correctly connected or if Motion lacks permissions to create image files.

Note that Motion occasionally fails to start up due to previous Motion processes that have failed to shut down properly and are running in the background.  If you suspect this, try running the following:

pid refers to the Process ID that you get from the ps aux command.

Once Motion is up and running you’ll want to check out the video stream.  To do this, you’ll need the IP address of the Pi Zero along with the port specified by the stream_port parameter from the Motion config file.  Go to the address:

and you should see your video stream in the browser.

You can also access Motion’s HTML control panel by changing the port to that specified by the webcontrol_port as specified in the Motion config file.  Here you can change configuration options on the fly, stop and start Motion and even take snapshots.

Now you can test the motion detection.  Movement in front of the camera should result in a still image being saved to the directory you specified for the target_dir.  If this is working then your motion activated security camera is almost ready for use!

Adding Email Alerts

Our next job is to ensure that alert emails get sent from our Pi Zero.  As with all things Linux there are many different ways to do this, but I found the following to work without issue.

Installing a Mail Client

For this solution you’ll need a throwaway Gmail account, as you are going to specify your Gmail password in a configuration file.

Start by installing the tools you’ll be using to send emails:

Next, run:

and ensure that file contains the following configuration parameters, making sure that  your Gmail account credentials are in place:

Finally send a test email with an attachment from the target_dir directory:

If this mail arrives you are good to go to the next step.

Configuring Motion to send Email

Here you’ll need to make a small change to your Motion configuration file.

You’ll be updating the on_picture_save parameter.  Uncomment it and change it’s value as follows (updating the recipientEmailAddress to the email at which you want to receive alerts):

What happens here is that Motion will call this command each time a new image snapshot is saved to the target_dir directory.  The %f variable contains the full path to the file.

Save the configuration file, restart Motion and voila!  You should now be receiving email notifications each time Motion detects a motion event.

Housekeeping Functions

Ensuring Motion startups up on Reboot

The easiest way to ensure Motion starts up on reboot is to add it to the rc.local file.  This is a simple as adding the following command – assuming that you have specified the configuration file as outlined in this blogpost:

Removing old files

Over time there is a danger that your SD card will fill up with old images.  Therefore I strongly recommend that you create an automated cronjob to periodically remove all images from the output directory specified in the Motions configuration (the value to the key target_dir).

Evaluating The Result – Did the Security Camera work?

So does my camera do the job it was meant to do?  Definitely!  Here are some examples of the alerts that I have been sent by the camera.

Examples of the camera successfully detecting humans in my garden (click to zoom)

In addition the streaming video works perfectly, making it easy to check the video stream each time I get alerts.  By setting port forwarding in my home router I have exposed the live stream to the web and can now view it from my iPhone.

The Camera is meant to run 24/7, and was recently up for 4 weeks without a single problem while myself and my family where on holiday in England.  In addition to receiving alerts via email, we used the streaming video on a daily basis to see how the weather was in Oslo (and to check that my brother in law was watering the flowers as agreed).

There are many use cases for this kind of project.  It can be used for wildlife watching, pet monitoring or even to tell you when your kids come home from school!

Minor Issues

I have two minor problems with the solution, which are both easily resolved:

  1. The Pi NoIR camera works well in low light, but really needs an IR light source to perform at night. I haven’t got around to picking one up yet, but they are easy to get hold of online.
  2. The camera is mounted inside the house looking outwards.There is a small gap between the lens of the camera and the glass, which allows for reflections to appear when it is dark outside and the living room light is on.  This can be resolved by placing some cardboard or tape around the edges of the ZeroView camera mount, which would stop the light pollution hitting the glass right in front of the camera.

Example of light pollution affecting the pictures from the Camera

Here you can make out the gap between the ZeroView/Camera and the glass window

Other Issues

A more difficult issue to resolve was that of false positives. The Motion software algorithm for detecting movement is based on the amount of pixels changing from frame to frame.  In practice this meant that I received alerts when the neighbours cat paid us a visit, or on partly overcast days when the shadows in the garden quickly moved and changed.  Rain running down the window was also an issue.

Example of false positive due to moving shadows

On some days I received 50 alert emails due to these false positives, which tended to undermine the usefulness of the camera.  Motion allows you to tweak the amount of pixels needed to trigger an alert, but then you run the risk of making the camera less effective.

Conclusion and next steps

Over all I was very happy with the result.  The camera worked as designed and satisfied our original requirements.

The false positives issue was the only real problem.  I therefore decided to find a solution to this!

In my next blog post I show how I solved the problem of false positives by using Image Analysis and Amazon Web Services.

Until then, thanks for reading!  If you have put together a similar project, or have any questions about this blog, or find any errors in the code then feel free to tweet me @markawest or post a comment below.

61 kommentarer om “Building a Motion Activated Security Camera with the Raspberry Pi Zero

    1. Many thanks! There is a problem with false positives but I’ll show how I handled these in my next blog post.

  1. I will be interested to see now you solved false positives. I have used a blog post from pyimagesearch.com which uses opencv and added an email client to send a picture. This uses a weighted average of images to overcome changes in weather. I have had it running for two days with no false positives so far!

  2. I’ve got the same setup but suffering from false positives – especially in summer with the wind moving trees and the net on the tramp.
    Have been looking for image recognition sw that can identify the moving piece as a human and then generate the email, but its hard to get a neural_net based image recognition component to run fast enough on the rPi. Maybe OpenCV….

    1. Maybe a Pi cluster?!?

      My follow up blog will say more about how I handled false positives by outsourcing the job to the cloud. Hopefully it’ll be up by the weekend..

  3. Hey Mark, a very interesting project. Are the outlines in the pictures generated by the software or did you add them. If the software did it, do you know if it is possible to get the coordinates of the rectangle. I’m thinking about some kind of tracking. Or is it better to use OpenCV in this case.

    1. 1. The red box is added by Motion and can be configured to appear both in the live stream and in movies / still images generated by motion (see the locate_motion_mode and locate_motion_style configuration parameters).

      2. As far as I know, Motion can only output movies or still images.

      Thanks for reading by the way 🙂

  4. Nice job, Mark! Thanks for the detailed write-up. A motion-activated camera has been on my backlog for a while, and I think you’ve helped move it up in the queue!

  5. Very nice detailed write, up, best I’ve come across so far, and will help me tremendously to adapt my solution. Would you provide details when you get around to adding infrared LED? Thanks in advance

  6. Hi, struggling a bit with the setup….

    When I type…..

    cp ../../etc/motion/motion.conf ~/.motion/motion.conf

    to attempt to copy the original file I get……

    cp: cannot stat ‘../../etc/motion/motion.conf’: No such file or directory

    Also when I try to run…..

    sudo nano ~/.motion/motion.conf

    I just see a blank/black Nano editor window

    Any advice with this much appreciated, thanks.

    1. This is a typo on my side.

      Try cp /etc/motion/motion.conf ~/.motion/motion.conf instead. I have amended the text above to reflect this. Many apologies for the mistake!

  7. Thanks for your blog post!
    I was looking to do the same as you have an your Part 1 has really helped.
    Reflections were a problem for me too, especially due to double glazing. What sorted it for me was placing a plain background behind the pi.

    I decided to use Ubuntu Mate 16.04 for my RPI os, unfortunately the version of Motion available in the repositories was old so I had to build it from source. Thankfully it was straight forward and worked first time.
    Another difference was that rather than doing email notifications I posted animated mp4 videos to twitter.

    I also get false positives so I’ll be going though your other blog post next …. 😀

  8. Thankyou for the article.
    everything wend without problems until…
    I’m using a Pi Zero W, with the 2017-03-02-raspbrian-jessie image.
    I have the webserver displaying images whenever there is movement detected but no images are stored in /home/pi/Documents/motion. I’ve treble checked the motion.conf I’m running and all appears correct.
    I’ve made the directory /home/pi/Documents/motion just in case it could’nt find where to store.

    1. Two things you could check (from the the top of my head).

      #1 Are you running Motion with the correct configuration file?
      #2 Is Motion attempting to create a snapshot when motion is detected?

      Assuming that you are not running Motion as a daemon you can check these by looking at the output generated from the Motion process.

  9. Hi,

    Great write-up! I’ve got everything to work, up to the rc.local configuration.

    It seems to be starting the process but nothing happens (the process is there but is sleeping (Sl). I assume it shouldn’t be sleeping?

    I use the line: motion -c ~/.motion/motion.conf

    Am I missing something? (noob alert).

    The only difference with my setup is that I’m using a Dropbox script from (https://www.andreafabrizi.it/2016/01/01/Dropbox-Uploader/) – I’ve tried disabling it and get the same results.

    1. I’ve got it to launch at start up via rc.local. It was launching as root which seems to have been causing the problem – so I’m launching it as my user:

      runuser -l -c ‘motion -c ~/.motion/motion.conf’

    2. Hello Adrian,

      I was able to fix this by instead making it a cronjob like this

      open crontab using «crontab -e»

      and write this command at the end

      @reboot sudo motion -c ~/.motion/motion.conf > /home/pi/motion_log.txt

  10. @ Mark.

    Yes! Thanks again – I’m moving onto the object recognition and am thinking about upgrading to a Zero W. 🙂

  11. Hello! I followed every step but unfortunately I keep getting the error message Vid_v41x_start: failed to open video device /dev/video0: no such file or directory. Any suggestions?

    1. Also I am a total noob this is my first project and I would like to know what do you mean by un comment in your first change to the conf file. Do you possible just have a copy of your conf file? I’m struggling to work with them to get it to work.

    2. 3 things I’d double check.

      (1) Is the camera enabled?
      (2) Have you updated your Raspian distribution?
      (3) Are you running motion with the correct config file?

      Check all these and try again. If you still have a problem, send me the output you get when running motion.

  12. sudo motion -c ~/.motion/motion.conf
    [0:motion] [NTC] [ALL] conf_load: Processing thread 0 – config file /home/pi/.motion/motion.conf
    [0:motion] [NTC] [ALL] motion_startup: Motion 4.0.1 Started
    [0:motion] [NTC] [ALL] motion_startup: Logging to syslog
    [0:motion] [NTC] [ALL] motion_startup: Using log type (ALL) log level (NTC)
    [0:motion] [NTC] [ENC] ffmpeg_init: ffmpeg libavcodec version 56.1.0 libavformat version 56.1.0
    [0:motion] [NTC] [ALL] main: Camera 0 is from /home/pi/.motion/motion.conf
    [0:motion] [NTC] [ALL] main: Camera 0 is device: /dev/video0 input -1
    [0:motion] [NTC] [ALL] main: Stream port 8081
    [0:motion] [NTC] [ALL] main: Waiting for threads to finish, pid: 3074
    [0:web_control] [NTC] [STR] http_bindsock: listening on any IPv4 address port 8080
    [0:web_control] [NTC] [STR] httpd_run: Started motion-httpd server on port 8080 (auth Disabled)
    [1:ml1] [NTC] [ALL] motion_init: Camera 0 started: motion detection Enabled
    [1:ml1] [ALR] [VID] mmalcam_start: MMAL Camera thread starting… for camera (vc.ril.camera) of 640 x 480 at 2 fps
    [1:ml1] [NTC] [VID] MMAL camera component created
    [1:ml1] [NTC] [ALL] image_ring_resize: Resizing pre_capture buffer to 1 items
    [1:ml1] [NTC] [STR] http_bindsock: listening on any IPv4 address port 8081
    [1:ml1] [NTC] [ALL] motion_init: Started motion-stream server on port 8081 (auth Disabled)
    [0:web_control] [NTC] [STR] httpd_run: motion-httpd – Read from client
    [0:web_control] [NTC] [STR] httpd_run: motion-httpd – Read from client
    [0:web_control] [NTC] [STR] httpd_run: motion-httpd – Read from client
    [0:web_control] [NTC] [STR] httpd_run: motion-httpd – Read from client
    [0:web_control] [NTC] [STR] httpd_run: motion-httpd – Read from client
    [0:web_control] [NTC] [STR] httpd_run: motion-httpd – Read from client
    [0:web_control] [NTC] [STR] httpd_run: motion-httpd – Read from client
    [0:web_control] [NTC] [STR] httpd_run: motion-httpd – Read from client

    motion itself is now working however my online stream is not. Im not sure how to fix this because my SSH is working fine but everytime i try to access the stream online it says it could not connect to the server.

    1. Can you check that ‘stream_localhost’ is set to ‘off’ in your configuration file? If this is set to ‘on’ (the default) then you will only be able to access the streaming server from the Pi.

      1. If you still encounter problems, check that both the server (your PiZero) and client are connected to the same wifi network.

        1. Hi Mark, so I got motion to run fine, I can see that it is tracking motion events and saving pictures to the pi zero w, however my stream is still not working, I copied word for word your conf file, but every time I try to connect it just says it failed to open the page because it could not establish a secure connection to the server. Any suggestions? Thanks for the help so much!!

          1. Never mind that mark! Just had to mess around and try different streaming ports and it worked! Thank you so much for the detailed walk through and helping me complete my first raspberrypi project!

          2. Congratulations on getting everything working!

            If you want to, you can experiment with the Motion configuration (always keep a back up) to make the camera less or more sensitive, according to your requirements (and your tolerance for false alarms).

  13. Took a while, but works perfect. I expected the images at an higher quality, but is does the job.
    Live video feed is fast and motion detection (indoors) is working perfect. I am running it on an Pi zero with the wifi onboard. Just a power cable and i am up and running.

    Next steps for me:

    – Adding an extra usb webcam that i still have somewhere, so i can film both entries in my house.
    – find a way so i can view the video feed from the internet when i am not at home. I am viewing it locally now. Viewing it from my workplace or when i am on a holiday would be great.

    Thnx for the great guide.

    1. Good to hear that you got the camera working!

      By tweaking the Motion configuration file you might be able to get a higher quality picture.

      As for viewing the stream from outside your local network – I managed this by configuring port forwarding on my router.

  14. Using the rc.local command as shown caused the program to be executed with the wrong settings. Rather than run it with the pi user I just used the full path to the config file and everything seems to work:
    motion -c /home/pi/.motion/motion.conf

    Thanks for an excellent writeup!

  15. Hi Mark,

    many thanks for these blog-entry. God idea und great step-by-step tutorial.
    Works fine!

    Now your next blog – Image Analyses and Amazon Web Services – is on my read list.

    Thanks again,

  16. Just a quick comment on the IR camera and night vision. I believe glass blocks most IR light, so mounting behind a window is probably the cause of failure. I’d try mounting outside of glass and see if you get better results.

    1. Nice point. I’ve experimented with a couple of cheap IR lights, but these tend to be spots, when what I really need is a flood. Flood IR’s cost quite a bit though.

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *

Magic Mirror – version 1

Introduction A while back I discovered the exciting world of “magic mirrors”. I don’t remember how or where it caught my attention, but..

DevOpsDays Oslo 2016

5.-6. september hadde eg gleden av å delta på den første norske DevOpsDays i Oslo. Her er en oppsummering av høydepunktene..

Bouvet at JavaZone 2016

This year JavaZone celebrated it’s 15th year with with 3000 attendees and over 170 sessions. As one of Norway’s premier Java..

IT years are like dogs years

One of the characteristics of the IT industry is that time works differently for us. This is challenging and fun,..

The Future of SharePoint

Den 4. mai holdt Microsoft en virtuell event om fremtiden til SharePoint, jeg fikk heldigvis anledning til å delta de..

SharePoint 2016 er på vei!

Som lovet var Microsoft ferdig med utviklingen av SharePoint Server 2016 (RTM – release to manufacturing) rett før påske, og..

En skybasert integrasjonsplattform

SAP HANA Cloud Integration SAP HANA Cloud Integration (HCI) er en skybasert integrasjonsplattform. Denne kan benyttes i stedet for SAP..

IoT Juleverksted

Tradisjonen tro var det i starten av desember tid for det årlige juleverkstedet hos Bouvet i Sandvika. Dette var tredje..

Bouvet Battle Royale – Rematch

Vår årlige fagdag ble i fjor kjørt som showdown mellom våre avdelinger som jobber med Java- og Microsoft-teknologi. Uten å..

Key takeaways fra JavaOne 2015!

JavaOne er verdens største Java-konferanse og arrangeres hvert høst i San Francisco. Her kan du oppleve foredrag fra noen av de..


I Bouvet er vi flere hundre teknologer som brenner for å programmere og utforme gode, digitale løsninger. I denne bloggen utforsker vi teknologien og deler det vi finner med dere.