Creating a motion-detecting security cam with a Raspberry Pi – Part 2
In the first post in this series, we took a look at some fundamentals related to building your own motion-detecting security camera using a Raspberry Pi. In this post, we’re going to look at very specific steps to get one working.
The first major step I took after the last post was to drop the Raspbian “wheezy” OS distribution in favour of Arch Linux ARM. This was an important change, as it increased the stability of the system significantly, and even allowed me to increase the capture resolution of the webcam back up to 960 x 720. Where “wheezy” would frequently crash – or the webcam itself would stop working, even at really low resolutions – Arch Linux ARM has shown itself to be rock solid and just keeps on working away. I’ve now left it running for days at a time without any issues.
There are a few differences when working with Arch Linux ARM: it doesn’t come with the very handy raspi-config script that alows “wheezy” users to perform common start-up operations – such as resizing the root partition, which we’ll perform manually, below – and there are various other bells & whistles missing, but at the end of the day most Raspberry Pi usage is likely to be to create embedded systems that clearly need leanness and a high level of stability.
That’s not to say that “wheezy” won’t get more stable prior to its official release (it is still in Beta, after all), but Arch Linux ARM was absolutely the way to go for this project.
Installing the OS to an SD card was straightforward: as mentioned previously, I used Win32DiskImager to burn it to a 16 GB Class 10 SDHC card (which has way more beef that I need for this project, but hey :-). This tool can also be used to back up your OS, which is a good thing to do from time to time.
It should now be a simple matter of plugging in the LAN cable via the RJ45 socket and plugging in the Micro-USB power supply to see the device boot up. I personally no longer bother with keyboards and direct display connections: I just log in using ssh (which is native on OS X and Linux, and usable via PuTTY on Windows) to access the device remotely. It’s even possible to use X11 Windowing to pipe graphics back down to a compatible system (such as OS X), but that’s beyond the scope of this post.
In an OS X Terminal session, then, I use this command to connect to the Pi (when on my home network, where I’ve configured my router to dedicate the IP address of 192.168.1.110 to the device):
The default machine name is “alarmpi” (Arch Linux ARM Pi), so when in the office I use this, instead (it’s simpler to use DNS to resolve the IP rather than hunting around for it):
[The default password is “root” on the standard install.]
Once you have an ssh session running, you can take care of some initial tasks, first of which is to increase the root OS partition to the full size of the SD card. Here is the most elegant method I’ve found to do this (while those knowing what it does may find it a little scary, it worked perfectly for me :-). It’s worth bearing in mind that expanding the size of your root partition will increase the size of the image file when you back up your OS, but then that’s the choice you make.
I’ve added some comments that start with the # sign – you don’t need to type those lines in:
# As root:
# Delete the second partition /dev/mmcblk0p2
# Create a new primary partition and use default sizes prompted.
# This will then create a partition that fills the disk.
# Save and exit fdisk:
# Now reboot:
# Once rebooted:
# Your main / partition should now be the full size of the disk.
As you’ve rebooted during this process, you’ll clearly need to reconnect via ssh to the device to complete it.
Depending on the size of the card, this resize2fs operation may take some time.
Now it’s worth changing the root password and setting up a new user (which I’ll name “pi”):
# Add a user named pi - accept default options
We’ll stay logged in as root, for now, as we still have some work to do to get things ready to have effective use of the device as a standard user.
Linux distributions have different command-line tools for installing approved component packages – much as some of you may be used to with NuGet in recent versions of Visual Studio. Raspbian has apt-get, Arch Linux ARM has pacman. To make sure pacman is installed and (along with the OS itself) up-to-date, run these operations:
Now you can use pacman to install the various packages we want to use. We’ll start with sudo (which stands for “super-user do” rather than being a mis-spelling of “pseudo” :-), which will allow our pi user to perform operations as root.
pacman -S sudo
It’s one thing to have sudo installed, it’s another to be able to use it. You can edit the sudo privileges directly using this command, which unfortunately uses the vi editor to open the file (I’ve mostly switched over to the much more intuitive nano editor, at this stage):
# Scroll down to "root ALL=(ALL) ALL", i to insert:
pi ALL=(ALL) ALL
Esc ZZ # (to quite & save)
At this stage it’s worth logging out (you can type exit or logout to do so) and logging back in via a new ssh session as the “pi” user:
One last step is helpful but not strictly necessary, in that it enables command-completion via the Tab key when executing commands using sudo:
sudo pacman -S bash-completion
Now we basically have our OS up and ready. If we were on “wheezy” we’d now be thinking about installing (or building) a webcam driver. That happens to be built into Arch Linux ARM, so we can skip on ahead to installing Motion:
sudo pacman -S motion
At this stage we have most of the packaged components in place that we need to run our motion-detecting security cam. Now we’ll start configuring Motion.
We’re going to ask Motion to save it's running process ID in a file in the /var/run/motion folder. First, though, we need to create that folder:
sudo mkdir -p /var/run/motion
[As mentioned last time, it’s helpful – but not necessary – to set up a killmotion script that uses this ID to kill the motion process (which is really only for when you’re running in daemon mode). That said, it’s also simple enough to run the “pstree –p” command to see the running process tree with the IDs at each node, and then just use “kill 1234” (assuming the process ID is 1234).]
Next we’re going to install Python and the GData component we need to access GMail and Google Drive.
sudo pacman -S python2 python2-pip
sudo pip2 install gdata
We’re going to ask Motion to save one frame per event – that we can use as an email attachment in our email, to help recipients – especially those on a mobile device – decide whether it’s worth watching the uploaded video. Both the capture frame and the video will be stored to /home/pi/motion, which we need to create:
We might also have kept the default location – which I believe is under /var/tmp – but that’s a folder that gets cleared between sessions (when the device is rebooted). When my device was regularly being reset – back when I was using “wheezy” – I moved across to this folder, so I could see when images/videos were captured successfully. So far I haven’t seen the need to switch back.
Now we can download and install the Uploader.py file, which I’ve adapted from the one in this post (with the help of the information in this page). You might download the file and FTP it across, or you could use the following approach to download it directly using the Pi (and then make it executable):
sudo wget "http://through-the-interface.typepad.com/files/uploader.py"
sudo chmod +x uploader.py
You’ll also need an uploader.cfg file in the same location. The simplest approach is to run “sudo nano uploader.cfg” and paste the contents in (after having modified them with your login information, of course):
# GMail account credentials
name = Kean Walmsley
user = email@example.com
password = this_is_not_really_my_password
sender = firstname.lastname@example.org
# Recipient email address (could be same as from_addr)
recipient = email@example.com
# Subject line for email
subject = You have a visitor
# First line of email message
message = See attachment. Video of visitor uploaded to:
# Folder (or collection) in Docs where you want the videos to go
folder = motion
# Delete the local video file after the upload
delete-after-upload = true
# Send an email after the upload
send-email = true
You should now be able to test the script, to see that it works:
/etc/motion/uploader.py /etc/motion/uploader.cfg ./VidTest.avi
[I had previously thought to post instructions to use fswebcam to capture a still and ffmpeg to capture a video, but the former involved installing an additional component and the latter didn’t actually work when called directly on my Pi (even though Motion uses it successfully to encode video, as far as I can tell)].
Once you’ve executed the uploader script, you should receive an email with a link to the video on Google Drive (assuming it’s enabled for your Gmail account) and the image as an attachment:
sudo wget "http://through-the-interface.typepad.com/files/motion.conf"
Motion has a lot of settings that you may want to adjust – it’s a really flexible, powerful component – but I won’t go into the details on that, here.
To run Motion simply type “sudo motion” at the command-line. The configuration I’ve provided will run it in daemon (i.e. as a background service) mode, but if you hit problems you may want to run it in interactive mode, or even with the –s flag. A couple of handy features provide the ability to change configuration options at runtime via a URL (in my case this is http://192.168.1.110:7071) and to view the live webcam output via another (http://192.168.1.110:7070).
If all is working well, you should start to get emails with detected motion events:
Once you’re ready to have it enter daemon mode on boot, you can edit the /etc/rc.conf file (using sudo nano …) to add it to the list of startup daemons on the very last line of the file.
One thing to note about this particular configuration: as mentioned, we save a single .jpg to accompany the .avi file that gets recorded (both files will appear in the same /home/pi/motion folder with the same name). The uploader script gets called when the .avi gets saved but assumes the .jpg will be there.
These files get created once motion has fully stopped (and there’s a configurable 60 delay to make sure that’s the case) which means that at some point we’ll want to change the configuration to have Motion take more regular snapshots – and use a different naming convention, as we’ll have more .jpg files per .avi – as that will allow us to run them through the facial recognition system and present the results without waiting for 60 seconds after the person has left. A change will also be needed for the uploader module, of course. But all that’s for another day and another series of posts. :-)
Alex Fielder reminded me that the uploader will look for a folder called "motion" in your Google Drive - be sure to make that folder before you try uploading. Thanks, Alex! :-)