My parents needed a Security Camera at their workplace after a string of thefts and they were looking at old school analog CCTV cameras which operate at 480i resolution and record to a DVR. In this day and age, 480i is unacceptable but since those cameras are cheap (~5000Rs per camera), people tend to go for them although the cost of DVR and LCD is additional. So I thought I’d make an HD Security Camera myself as a project. My goals were to record at least 720p footage, have a footage backup of 7 days, have power consumption low enough so it could run 24/7 on UPS and have minimal amount of wires exiting the camera (just 1 Power Cable, no LAN cable).
I settled on using Raspberry Pi board for all my processing needs. If you don’t know about Raspberry Pi, its a wonderful project that manufactures this tiny board (slightly bigger than a credit card) that works as a full fledged computer which can run a full Linux OS. People have used it to build a host of wonderful projects, all the way from robots to flying drones!
Among a list of accessories for Raspberry Pi is a Camera module (sold separately) which takes 1080p videos and pictures. Perfect for my Security Cam!
Here’s the list of all of the equipment I used for making the Security Camera (along with price). I live in Gujranwala and all of the stuff listed was bought online or from local shops:
Raspberry Pi Model B+ (Price: Rs 5,500)
I bought the latest Raspberry Pi Model B+ online from Unique Gadgets (uniquegadgets.com.pk). The website offers “Cash-on-Delivery” payment so you don’t need to own a credit card to purchase from them. Their customer support is also pretty friendly. I bought the wrong type of SD Card for my Raspberry Pi. The guy called and suggested I order the correct type instead of shipping me the wrong type.
You can check the Hardware Specs for the board here: http://www.raspberrypi.org/products/model-b-plus/
Raspberry Pi Camera Module (Price: Rs 4,500)
I also bought this online from Unique Gadgets.
The Raspberry Pi Camera Module Features:
- Fully Compatible with Both the Model A/Model B/Model B+ Raspberry Pi
- 5MP Omnivision 5647 Camera Module
- Still Picture Resolution: 2592 x 1944
- Video: Supports 1080p @ 30fps, 720p @ 60fps and 640x480p 60/90 Recording
- 15-pin MIPI Camera Serial Interface – Plugs Directly into the Raspberry Pi Board
- Size: 20 x 25 x 9mm
- Weight 3g
Transcend 8GB Micro SDHC Class 10 (Price: Rs 1,150)
This acts as the onboard Hard Drive for Raspberry Pi. It carries the OS (Raspbian which is based on Debian) and the remaining space can be used to store data. Also bought online from Unique Gadgets.
Power supply (Price: Rs 450)
The Raspberry computer does not come with any power supply, you have to get one on our own. Any 5V power supply with a micro-USB plug can do the job as long as it supplies at least 1A of power. I bought a cheap one from a local computer market. But get a good quality one if you can as low/unstable power is the no.1 problem that can ruin your project.
TP-Link WNL-722N USB WiFi Adapter (Price: Rs 950)
The Raspberry Pi board has a LAN port on-board and can be connected to a network via a LAN Cable. But since I want to mount the Security Camera on a wall, I don’t want a LAN Cable snaking all the way to a Router. Instead we’ll use a TP-Link WNL-722N USB WiFi adapter that can plug into any of Raspberry Pi’s 4 USB 2.0 ports. This particular model is supported by Raspbian (Raspberry Pi’s OS) and has a bandwidth capacity of 150 Mbps. I bought it from the local computer market.
Toshiba 320GB External Hard Drive (Price: Rs 4,500)
We need ample amount of storage for the footage that our Security Cam records. I had a spare Toshiba 320GB External Hard Drive lying around, which can hold around a week’s worth of 720p footage. You can buy according to your needs. We are going to open the casing for the External Hard Drive because its too large for our camera housing.
Powered USB Hub (Price: Rs 950)
Our External Hard Drive takes a lot of juice, something the Raspberry Pi can’t supply considering it itself is running on a 5V/1A power source. So I bought a Powered USB Hub from the local computer market that takes a seperate 5V/1A charger. That will take care of the power needs for our Hard Drive, WiFi adapter plus any peripherals we might want to add in the future like a 3G USB Modem (PTCL EVO Wingle). The Hub also needs to be disassembled to fit into our camera housing.
Casing/Housing for Security Camera (Price: Rs 1,500)
We need an empty casing to house all of our equipment. There are “dummy” casings available in the market that fit our needs perfectly. Look for shops that work with security equipment, they usually have spare dummies lying around. I bought an unused piece with mounting stand from Trust Plaza in Gujranwala.
Custom Iron Plate with screw holes (Price: Rs 400)
My specific casing has screws which are too wide to mount the Pi on them. I needed a custom plate with screw holes according to dimensions of the casing, that I could securely mount in the casing. The plate also needed screw holes according to dimensions of Pi, so that the board could be mounted on the plate.
Luckily I live near an entire market full of Iron merchants and their associated works. I bought a plain iron plate, had it cut to my casing’s specifications. I had the front end molded to stand at right angles in a press where they mold pipes and stuff. They did it for free! I took it to a welder who used a gas flame torch to cut the front end into a nice curved shape so that it would fit into my casing. Next I took it to an acquaintance who works as a die manufacturer. He machine tooled nice screw holes on the plate according to design specifications (2.5mm +- 0.05mm): 4 for the casing, 4 for the Raspberry Pi on the base and 2 on the front end for the Camera Module. All of it cost 400 Rs and took around 4 hours.
Miscellaneous Items
- Screws with nuts
- Rubber Bands
- Reflective Paper
- Plastic sheets
The entire cost came around to Rs 20,000. For comparison: a Wireless HD IP Camera + Storage + Router starts above Rs 40,000.
This was my first time working with Raspberry Pi, although I have a decent level of experience working with Linux. Setting up the Raspberry Pi is extremely easy. Here is an excellent guide to setting up the Pi: http://neil-black.co.uk/the-updated-raspberry-pi-beginners-guide
I connected the Raspberry Pi to my home router via LAN cable and SSH’d into it. I connected my External Hard Disk and USB WiFi Adapter to the USB Hub and connected the Hub to the Pi via USB. The OS recognized the WiFi adapter immediately but the External Hard Drive was giving me problems. It would make a weird clicking noise and sometimes show up and some times it wouldn’t get recognized. After a lot of troubleshooting, I found out that my charger for the USB Hub was 4.5V/1A. Switching to 5V/1A solved the HDD issues but they would crop up again from time to time. So I went back a got a 5V/1.5A charger but that had the wrong connector. Replacing the connector with the one from the old charger was an easy fix and then onward the Hard Drive worked smoothly.
With all the equipment connected and working smoothly, I wanted Pi to work as a WiFi Access Point (AP). I wanted to be able to connect to the Pi directly without using any router. After a lot of searching and trial-and-error, I found these two guides that allowed me to set up the Pi as an AP: http://itsacleanmachine.blogspot.com/2013/02/wifi-access-point-with-raspberry-pi.html and https://learn.adafruit.com/setting-up-a-raspberry-pi-as-a-wifi-access-point/overview
They use hostapd
to setup a WiFi AP and isc-dhcp-server
to hand out IP addresses. I tried many other programs but these two worked the best. Both of these guides have detailed, step-by-step instructions that do not require any special skills to follow. For reference, here are my working configuration files:
/etc/hostapd/hostapd.conf
interface=wlan0 driver=nl80211 ssid=[enter the WiFi AP name you want] hw_mode=g channel=6 auth_algs=1 #wme_enabled=1 #ieee80211n=1 #ht_capab=[HT40+][SHORT-GI-40][DSSS_CCK-40] wpa=2 wpa_passphrase=[enter the passphrase you want] wpa_key_mgmt=WPA-PSK wpa_pairwise=TKIP rsn_pairwise=CCMP wpa_ptk_rekey=600 macaddr_acl=0
/etc/dhcp/dhcpd.conf
# # Sample configuration file for ISC dhcpd for Debian # # # The ddns-updates-style parameter controls whether or not the server will # attempt to do a DNS update when a lease is confirmed. We default to the # behavior of the version 2 packages ('none', since DHCP v2 didn't # have support for DDNS.) ddns-update-style none; # option definitions common to all supported networks... #option domain-name "example.org"; #option domain-name-servers ns1.example.org, ns2.example.org; default-lease-time 600; max-lease-time 7200; # If this DHCP server is the official DHCP server for the local # network, the authoritative directive should be uncommented. authoritative; # Use this to send dhcp log messages to a different log file (you also # have to hack syslog.conf to complete the redirection). log-facility local7; # No service will be given on this subnet, but declaring it helps the # DHCP server to understand the network topology. #subnet 10.152.187.0 netmask 255.255.255.0 { #} # This is a very basic subnet declaration. #subnet 10.254.239.0 netmask 255.255.255.224 { # range 10.254.239.10 10.254.239.20; # option routers rtr-239-0-1.example.org, rtr-239-0-2.example.org; #} # This declaration allows BOOTP clients to get dynamic addresses, # which we don't really recommend. #subnet 10.254.239.32 netmask 255.255.255.224 { # range dynamic-bootp 10.254.239.40 10.254.239.60; # option broadcast-address 10.254.239.31; # option routers rtr-239-32-1.example.org; #} # A slightly different configuration for an internal subnet. #subnet 10.5.5.0 netmask 255.255.255.224 { # range 10.5.5.26 10.5.5.30; # option domain-name-servers ns1.internal.example.org; # option domain-name "internal.example.org"; # option routers 10.5.5.1; # option broadcast-address 10.5.5.31; # default-lease-time 600; # max-lease-time 7200; #} # Hosts which require special configuration options can be listed in # host statements. If no address is specified, the address will be # allocated dynamically (if possible), but the host-specific information # will still come from the host declaration. #host passacaglia { # hardware ethernet 0:0:c0:5d:bd:95; # filename "vmunix.passacaglia"; # server-name "toccata.fugue.com"; #} # Fixed IP addresses can also be specified for hosts. These addresses # should not also be listed as being available for dynamic assignment. # Hosts for which fixed IP addresses have been specified can boot using # BOOTP or DHCP. Hosts for which no fixed address is specified can only # be booted with DHCP, unless there is an address range on the subnet # to which a BOOTP client is connected which has the dynamic-bootp flag # set. #host fantasia { # hardware ethernet 08:00:07:26:c0:a5; # fixed-address fantasia.fugue.com; #} # You can declare a class of clients and then do address allocation # based on that. The example below shows a case where all clients # in a certain class get addresses on the 10.17.224/24 subnet, and all # other clients get addresses on the 10.0.29/24 subnet. #class "foo" { # match if substring (option vendor-class-identifier, 0, 4) = "SUNW"; #} #shared-network 224-29 { # subnet 10.17.224.0 netmask 255.255.255.0 { # option routers rtr-224.example.org; # } # subnet 10.0.29.0 netmask 255.255.255.0 { # option routers rtr-29.example.org; # } # pool { # allow members of "foo"; # range 10.17.224.10 10.17.224.250; # } # pool { # deny members of "foo"; # range 10.0.29.10 10.0.29.230; # } #} subnet 10.10.0.0 netmask 255.255.255.0 { range 10.10.0.25 10.10.0.50; option domain-name-servers 8.8.4.4; option routers 10.10.0.1; #interface wlan0; option domain-name "local"; }
/etc/default/isc-dhcp-server
# Defaults for isc-dhcp-server initscript # sourced by /etc/init.d/isc-dhcp-server # installed at /etc/default/isc-dhcp-server by the maintainer scripts # # This is a POSIX shell fragment # # Path to dhcpd's config file (default: /etc/dhcp/dhcpd.conf). DHCPD_CONF=/etc/dhcp/dhcpd.conf # Path to dhcpd's PID file (default: /var/run/dhcpd.pid). DHCPD_PID=/var/run/dhcpd.pid # Additional options to start dhcpd with. # Don't use options -cf or -pf here; use DHCPD_CONF/ DHCPD_PID instead #OPTIONS="" # On what interfaces should the DHCP server (dhcpd) serve DHCP requests? # Separate multiple interfaces with spaces, e.g. "eth0 eth1". INTERFACES="wlan0"
/etc/network/interfaces
auto lo iface lo inet loopback iface eth0 inet dhcp auto wlan0 #allow-hotplug wlan0 iface wlan0 inet static address 10.10.0.1 netmask 255.255.255.0 #iface default inet dhcp up iptables-restore < /etc/iptables.ipv4.nat
After setting up Pi as an AP, I tested the Camera Module. Installing it is pretty simple: take the camera ribbon pin and insert it in Pi’s Serial Interface with the silver pins facing the HDMI port. In the terminal running SSH connection to the Pi, type sudo raspi-config
. Enable Camera in the options. Now take a still image with raspistill -o img.jpg
You can check the still by copying the still to your computer over ssh using scp pi@[pi's IP address]:/home/pi/img.jpg Downloads
Time to setup recording. We are going to use the built-in python picamera
module to capture 720p raw footage and convert it to mp4. The script cam.py
is given below. For the conversion we need to install gpac
.
sudo apt-get install gpac
Our script records raw footage in h264 codec. We need to convert it into something that most players can play such as mp4. Here’s command to convert .h264
into .mp4
:
MP4Box -add output.h264 output.mp4
Zabardast! Now we have a playable mp4 file.
Now we need to automate this process so that it starts on its own without need for manual interaction. We need the footage to be converted and stored in a folder structure. And finally we need to be removing footage after 7 days so that our Hard Drive does not fill up with old footage.
For all that we are going to use scripts. We are going to write a script in python that stores footage for 17 hours in one hour increments.
cam.py
#!/usr/bin/env python # cam.py import os import picamera import subprocess with picamera.PiCamera() as camera: camera.resolution = (1920, 1080) camera.framerate = 25 camera.vflip = True for filename in camera.record_sequence(['/media/toshiba/motion/hour%02d.h264' % (h + 1) for h in range(17)], quality=20, bitrate=6000000): camera.wait_recording(60 * 60)
And another script that encodes our raw footage into mp4 files and removes the raw footage.
encode.py
#!/usr/bin/env python #encode.py import os import subprocess for item in os.listdir('/media/toshiba/raw'): fname = item[:-5] try: subprocess.call("MP4Box -add /media/toshiba/raw/%s, /media/toshiba/video/%s.mp4" %(item, fname), shell=True) except Exception as e: print e break os.remove('/media/toshiba/motion/%s' %item)
Now we are going to set a cron job that runs recording script at 6am and encoding script at 11pm. To edit cron
, we need the command crontab -e
. Here’s my cron file:
0 6 * * * /usr/bin/python /home/pi/Code/cam.py 0 23 * * * /usr/bin/python /home/pi/Code/encode.py @daily find /media/toshiba/Footage -type f -mtime +7 -delete @daily find /media/toshiba/Footage -type d -empty -delete
We have the recording script running from 6am to 11pm and the encoding script running after 11pm. We have another entry that daily deletes files older than 7 days and another one that deletes folders that are empty.
One last thing to do is disable the camera LED, because the light reflects in our screen covering the casing.
Add disable_led_camera=1
to /boot/config.txt
Now that we have setup the Pi to our liking, lets assemble our equipment together.
We cut the plastic sheet to the size of our plate to provide insulation between the Hard Drive, the plate and the USB Hub underneath and fixed it to both sides of the plate with rubber bands. Then we cut the reflective paper into the shape of the front end and pasted it in front of the plate with UHU.
Next we placed the Hard Drive on the sheet and anchored it rubber bands as well.
Then we screwed our Raspberry Pi with long screws onto the plate and tightened the nuts at the other end.
Next we placed the USB Hub on the floor of the camera casing and anchored it with a rubber band passing through one of the vents. Since our plate was going to cover most of the Hub, we needed to make sure that we had at least two USB ports visible. We also had to make a hole in the back of the casing to let the charger for the Hub through because there wasn’t enough room in the casing for it to come through the main opening and fit into the charging port. It ended up nice and tight! We plugged in the Hub’s USB cable into the Pi.
Then we plugged in the USB WiFi Adapter in the USB Hub along with the Hard Drive’s USB cable. We snaked the power cord to the Pi alongside of the Hard Drive and powered it ON! The Pi has no switch, you just plug in the adapter and it turns on and starts booting. Looks beautiful!
Thats it folks! Your own Raspberry Pi based Security Cam that stores 720p HD footage for a week and acts as its own WiFi hostspot (so you don’t need any LAN cable or extra router to connect to it). It has only 1 wire for Power coming out of it and its power requirements are so low that if you connect it to a UPS, it will not put any load on your battery and run 24/7. You can add a PTCL EVO Wingle to give it internet access and use the internet by connecting to its Wifi network or watch the footage stored from a remote location by running a Samba Server on it (which we are running). The possibilities are endless 🙂