Posted by Armin on Wednesday, March 25, 2015
Summary of features
This Raspberry Pi camera runs "Motion", a software motion detector to capture high-quality images twice a second when something moves in the field of view. To increase sensitivity at night, I'm using a PiNoir camera, which doesn't have an infrared filter. When motion is detected, two arrays of infrared LEDs are switched on for the duration of the motion event. (LEDs are only turned on when it's dark and when motion is detected.) Images are sent wirelessly to a shared SMB drive on an old PC running Linux Mint, where a time-lapse mp4 movie is created automatically at the end of the day.Images
Motion detection software
I installed "Motion" for the Raspberry Pi camera via the instructions on the UV4L site here: http://www.linux-projects.org/modules/sections/index.php?op=viewarticle&.... The maximum resolution I was able to get without weird things happening was 1280 x 1024 pixels, which gives plenty of detail for this purpose. "Motion" also includes a live webcam server, which is useful for checking who's at the door from upstairs without having to run down. I'm using a mask file to avoid triggering motion events from areas outside our property. All of these features are easy to install, and are described in detail elsewhere.Python programs to switch lights on and off for a motion event
The installed "Motion" software includes the ability to call scripts at the beginning and end of motion events. I wrote two simple Python programs to communicate with "motion" and control the state of GPIO pins on the Raspberry Pi, which are used to switch on two IR LED arrays. One script is a TCP/IP server I called "eventResponderServer" that runs on the Raspberry Pi and waits for messages on a certain port. If that message is the word "on", the program switches a particular digital pin to HIGH; if the message says "off", it sets the pin to LOW. (If the message is "quit" the server program shuts itself off.) Another small Python program, the "eventResponderClient", is called when "Motion" determines an event has started or ended. It then sends the "on" or "off" messages to the port (on localhost) on which the eventResponderServer is listening. The commands called for a motion event can be set in the "/etc/motion/motion.conf" file by modifying the lines starting with "on_motion_start" and "on_motion_end":
# Command to be executed when an event starts. (default: none) # An event starts at first motion detected after a period of no motion defined by gap on_event_start /home/pi/bin/eventResponderClient.py on # Command to be executed when an event ends after a period of no motion # (default: none). The period of no motion is defined by option gap. on_event_end /home/pi/bin/eventResponderClient.py off
# Ignore sudden massive light intensity changes given as a percentage of the picture # area that changed intensity. Valid range: 0 - 100 , default: 0 = disabled lightswitch 40 # Picture frames must contain motion at least the specified number of frames # in a row before they are detected as true motion. At the default of 1, all # motion is detected. Valid range: 1 to thousands, recommended 1-5 minimum_motion_frames 3 # Specifies the number of pre-captured (buffered) pictures from before motion # was detected that will be output at motion detection. # Recommended range: 0 to 5 (default: 0) # Do not use large values! Large values will cause Motion to skip video frames and # cause unsmooth mpegs. To smooth mpegs use larger values of post_capture instead. pre_capture 3
Python source code for "eventResponderClient.py" and "eventResponderServer.py"
The full code for the Python helper programs can be found on my BitBucket account here:
https://bitbucket.org/amphioxus/eventresponder/overview
Creating a daily movie with avconv
Instead of having "motion" create videos on the RPi, I'm using a shell script on a larger Linux box that runs every night to produce a time-lapse MP4 movie from the image sequence. The script uses a modified version of the Perl "rename" command that allows the use of an incremental counter. The renaming step changes the time-stamped file names coming from the camera into sorted file names with a zero-padded counter at the end, allowing "avconv" to create a correctly composed movie file from the image sequence. (The modified rename program can be found here: http://www.volkerschatz.com/unix/uware/rename.html. I called it "renum" on my system.)
#!/bin/sh # Shell script to create a movie of security camera footage (front porch camera) # Needs a modified rename script from here: <a href="http://www.volkerschatz.com/unix/uware/rename.html #">http://www.volkerschatz.com/unix/uware/rename.html #</a> Armin Hinterwirth, 2014-2015 # Get current date and time to create file name: TIMESTAMP=$(date +"%Y-%m-%dT%H-%M-%S") FILE="daily_movie_frontcam.${TIMESTAMP}.mp4" # Specify directories: ARCHIVEDIR="/home/armin/Videos/security_cameras/front_porch_cam/" TARGETDIR="/home/raspi/cam_upload" LOGFILE="/tmp/mysecam.log" # Start the action... # Switch to directory supplied as first argument: cd $TARGETDIR # Spit out some debugging info: echo "-----------------------------------------------------" >> $LOGFILE echo "Date start: $(date)" >> $LOGFILE echo "Creating nightly time-lapse movie from image sequence" >> $LOGFILE # Rename files renum -v 's/(\d+)-(\d+)-(\d+)/sprintf("image_%05d",${i})/e' *.jpg echo "Renamed jpg files" >> $LOGFILE # Create movie from images MOVIECREATED=$? # Check whether last command returned a zero (i.e. succeeded). Only then, proceed: if [ $MOVIECREATED -eq 0 ]; then echo "Created mp4 movie file" >> $LOGFILE # Move new movie file to permanent location: mv $FILE $ARCHIVEDIR echo "Moved file ${FILE} to archive directory: ${ARCHIVEDIR}" >> $LOGFILE echo "Nightly time-lapse movie created successfully" >> $LOGFILE # Delete image files when done (using find in case argument list is too long for simple rm) find . -name "image_*.jpg" -print0 | xargs -0 rm # echo "Image files deleted." else echo "Movie creation failed. $(date)" >> $LOGFILE fi echo "Done: $(date)" >> $LOGFILE
Switch circuit
Lights obviously draw too much current to be powered directly by the Raspberry Pi's GPIO pins. Therefore, I'm using an opto-coupled transistor switch circuit to protect the RPi, and switch the LED arrays running off a 12V supply. Here is a schematic of the circuit:The switch circuit uses a 4N25 optocoupler to electrically isolate the Raspberry Pi from the rest of the circuit. A TIP122 found in my box of random electronics parts does the switching. LED1 is an indicator that lights up during a motion event. (R4 is a 1.5K Ohm resistor.) To the right of the image is a header, to which the LED arrays are attached.
I placed the small breadboard in a weather-tight plastic box (see picture in gallery below) to protect it a bit more than the wood enclosure I built underneath our porch already does.
Parts list
Here's a list of the more important parts used for my camera system:
- Raspberry Pi, model B+
- PiNoir camera
- Edimax wireless dongle: http://amzn.com/B003MTTJOY
- CMVision IR30 WideAngle IR Illuminator http://amzn.com/B001P2E4U4
- 2N24 optocoupler that I bought a long time ago from Jameco
- TIP122 transistor, various resistors, low-power LED
Comments
Dror replied on Permalink
IR led circuit
You write that the IR led array is connected to the header. It will be always ON as it gets 12V all the time.
According to the schematic the optocoupler only switches on the LED1 indicator.
Armin replied on Permalink
oh, you're right