Introduction: Easy Raspberry Pi Security Cam With Automatic Web Upload
This is a project that I put together super quick in under a week or so. The reason I needed to set this up the way I did was to get a basic security system in place as soon as possible to monitor my garage via my mobile device ,especially when I was away from home.
In its first version here, the security camera is controlled by a simple Python program that performs the following functions:
- Activate camera and capture a still image
- Check connection to the internet
- Upload the picture automatically to a WebAPI service
- If the connection fails, the image is cached to the local file system
- The saved image is uploaded the next time the program activates
Remote Web API Service:
I have my own ASP.NET based website where I host and test my code. As urgency was the key to this project, I started with a tutorial from Microsoft and modified the basic kit to upload the files using a secret key . I then added my own page that will need a personal secret key to view the most recently uploaded images first.
The Microsoft tutorial is located here. Readers who are comfortable working with ASP.NET technology stack can use this as a starting point. If not, you can build one using your favorite technology stack and modify the Python program accordingly.
The tutorial also comes with a basic styling that was not very appealing. Therefore, I decided to replace it with some quick bootstrap styling, which in its most basic form is quite easy on the eyes!
Step 1: Things You Would Need to Be Familiar With...
This instructable presumes that you're familiar with the following common knowledge from the countless resources accessible online:
- A Raspberry Pi (or simply referred to as the "Pi")
- Set up the Pi from a cold brick and turn it into an operational computer as it's supposed to be
- Configure the Pi to work with a USB Wireless Adapter to access the internet
- Modify the configuration settings of the Pi to enable the camera functionality
- Familiarity with Python, the IDLE environment , running Python programs
- Download and install Python modules/libraries
If you aren't or would like to revisit the Pi, this pocket book should come in handy to get you started.
Step 2: What You Need...
- The Raspberry Pi (Model B at least) from amazon or your favorite electronics retailer
- A qualifying SD Memory Card such as this one with at least 8 GB capacity
- An Edimax EW-7811Un Wi-Fi USB Adapter or equivalent that works well with a Pi
- A Waveshare Raspberry Pi Camera with Night vision also from amazon
- All the usual peripherals - monitor, keyboard and mouse
- A Raspberry Pi case (optional) - I decided to use one for obvious reasons
VERY IMPORTANT!
- A 5V 3A power supply - Don't skimp on this piece of hardware!
- Anything less than 3 amps will either shutdown your Pi, or like in my case, disable all other wireless equipment namely the keyboard and wireless access when the camera starts capturing images
- I got one from KFDtech because in addition to the micro USB adapter, it came with a host of other ones that I could use in different projects or with other chargers in the parts bin
- You will also need to install the Python PiCamera module to work with the camera using Python 2.7
PYTHON VERSION COMPLIANCE:
This project uses Python 2.7.x. A different version of the PiCamera module may have to to be installed to get the camera working with Python 3.x
The instructions to install the PiCamera module is detailed in the user manual for the Pi Camera
Step 3: Plug in and Orient the Camera Right Side Up
Spending some time here will save you some trouble down the road.
Most issues arise from the fact that the camera is not plugged in correctly
When plugging in the camera, make sure that the Blue stripe on the ribbon faces the USB ports of the Pi
Ensure that the ribbon is plugged in uniformly - the blue stripe must appear as a straight band without noticeable taper on the opposite end once you are plugged in
Just so that the images are not captured upside down, the camera must be positioned in a way that the blue strip on the camera ribbon appears below the lens
Here I've used a couple of slack rubber bands to position the camera during testing - don't use uber-tight and beefy rubber bands or straps as you may risk damaging the photo-sensors on the face of the camera!
NOTE
Given the tiny size, this one's easy to miss - remember to uncover the camera lens by taking off its cover!
Step 4: Enable the Raspberry Pi Camera Function
The Python program will be pretty much useless if the Camera function isn't enabled in the Raspberry Pi configuration file.
To do so, login to your pi using the default password raspberry (although it's recommended you change it to something more secure once tests have been completed).
- At the LX terminal prompt type in:
sudo raspi-config
- In the colorful screen that follows, scroll down to option 5 - Enable Camera
- Tab to move cursor to the "Select" position and hit Enter
- In the next screen, select "Enable" and hit Enter
- With your settings saved, you will be back to the previous screen
- Tab to the "Finish" position and hit Enter to complete the configuration
NOTE
- The Rapsberry Pi Foundation has stopped supporting camera modules in recent days
- Therefore, when you open the Raspberry Pi Configuration Manager from the Desktop mode you will not find the Camera feature listed in the Interface tab
- The only way to enable support for the camera module is to run raspi-config and enable legacy camera support
- You will see a warning stating that this interface is not supported any more, but you can click OK to save your changes and reboot the Pi
Step 5: Writing the Python Code
The Python code is pretty straight forward.
The Watcher.py program file attached to this step contains as much documentation as sensibly possible to make it easily understandable.
As for the web service part of the equation, the code is pretty simple and is located on Microsoft's site
I have not published the Web API code here for the following reasons:
The Microsoft sample has been hosted with a code browser that makes it easy to read through the code better than if I hosted it here (not to mention content reproduction licensing terms!)
You may not be working with the Microsoft stack and would want to build your web service using another stack such as LAMP or Ruby
NOTE
If you notice that the camera is capturing absolutely dark images after nightfall, you will have to update the script as follows:
# warm up camera
camera.start_preview()
# allow at least 5 seconds for the sensors to capture the surrounding light
time.sleep(6)
# now capture image
camera.capture(imgFileNm)
camera.stop_preview()
camera.close()
Attachments
Step 6: Night Vision Runs Hot - Keep Your Camera Cool!
The camera does a great job of capturing images in the dark, but that comes with considerable heat. Literally!
I got a sense of it after putting the camera to work overnight in the living room and next day I found that the camera, and the Pi case had warmed up pretty good!
For initial tests I had used a couple of 3D printed pieces from another project for spacers, but they got pretty warm too!
In my case, the set up would be located in my unheated garage, but despite that, I decided to provide a basic heat sink between the camera and the Pi case.
For this, I set up a couple of metal washers lying around in the garage (and pretty cold by the way) by sandwiching them between the Pi case and the back of the camera (which is pretty flat, and gets pretty warm!)
This way there would be ample air circulation around the gap created by the spacers, and metal being conductive would cool down much faster than the plastic spacers or the Pi case.
NOTE:
The camera will operate in a cold dark corner of my garage most of the time. Therefore, I haven't choked the rubber bands around the setup because the more I stretch the rubber, the faster it will deteriorate at lower temperatures!
Step 7: Scheduling the Python Program Using Cron
Cron is a super scheduling utility that comes with most Linux flavors and the Raspbian flavor is one of them.
In my application, I want my Python program to be executed once every 30 minutes.
The program Watcher.py is saved at the location /home/pi/Watcher
Therefore, this schedule has to be added to the Cron table (or crontab) like so:
- At the LX terminal, open the cron table in edit mode by typing this command:
- sudo crontab -e
- Use the cursor-down key to make your way to past the last line in the table
- Add a useful comment beginning with a # to identify and understand your schedule in the distant future
- # 12.12.2015 - - Run Watcher.py every 30 minutes using python
- Just below the line, type the actual schedule like so:
- */30 * * * * python /home/pi/Watcher/Watcher.py
where, */30 in the first position indicates a recurring schedule every 30 minutes
- Now add another comment and schedule to clean out the cron logs every 24 hours
- # 12.13.2015 - Clear cron logs every 24 hours
- * */24 * * * echo '' > /var/log/httpd/access_log
- # 12.13.2015 - Clear cron logs every 24 hours
In this case, the */24 is defined in the second position which is the place holder for the hour specification
- To save changes, hit Ctrl + X and when prompted hit Y on your keyboard
- Cron will confirm that you want to overwrite changes - simply hit Enter to return back to the LX command prompt
The comments I added to Crontab file pretty much describe the intent of what needs to be accomplished.
NOTE
Cron logs get pretty exhaustive and with the limited storage on the SD card, these logs can prove to be problematic real quick!
For more information on Cron an Crontab, refer to this documentation
Before mounting the Camera, leave the Pi running to make sure that Cron is running the program as intended
Step 8: Mounting the Camera in Position
- I happen to get lucky because in my case I have a stretch of wiring that runs through an external channel on the wall that is bang opposite to the garage door
- By looping a wire tie around the channel I was able to mount the Pi and the camera pretty easily
- The wire tie is snug enough to hold the Pi at the set height, but flexible enough for me to adjust the height of the camera to capture the garage scene to suit my requirements
- The charger came with its own Velcro strap that helped secure the power chord
- Finally, I plugged in the charger to the wall socket and secured it using masking tape - duct tape is a bit too much!
With the camera mounted, all I had to do was wait for the Cron schedule to execute the Watcher.py Python program every 30 minutes.
Watcher.py would:
- Trigger the camera to capture the image in the garage
- Check for the internet connection and beam the image up to my hosted Web API service
- If the internet connection failed, Watcher.py would stop capturing images and wait until service becomes available and then uploads the last image captured
NOTE
This is the first version - Some of the nice to have features that I would like to add (if and when I get the time) would be:
- Add a motion sensor and capture an image each time the motion sensor is tripped
- Continue to capture images even in the absence of the internet connection or API service and add them to a queue
- Upload images in the queue once the internet connection and/or service becomes available
- Mount the unit on a Servo and have it auto rotate and follow the target!
Step 9: So, What's My Watcher.py Watching?
This!
I really would like to keep tabs on my custom street rod when I'm away from home!
With a constant stream of images beamed up to my web API service, all I have to do is enter my access key on the Web gallery home page and select the number of images (starting with the most recent, and going back in time)
The gallery displays thumbnails of images along with their capture date and time stamp
These images from my live web gallery show the the contrast between the images captured when the lights are on and when there's near darkness . I say "near darkness" because the only lights I see in the garage are the ones that are blinking off of the Pi Board.
Regardless, they speak for themselves about the night vision capability of the tiny camera!
Hope you enjoyed my very first instructable!