Raspberry Pi Security Camera

After experiencing repeated incidents of theft where a thief would pilfer a carton of milk from the weekly delivery by The Milkman, I made the decision to utilize a Raspberry Pi to set up a simple camera system for monitoring our front porch. (Please note: The Milkman’s business is no longer operational, possibly due to the prevalence of milk thieves.)

Summary of features

To enhance security and surveillance, I have employed a Raspberry Pi camera equipped with “Motion,” a software motion detector. This camera system captures high-quality images at a rate of twice per second whenever movement is detected within its field of view. To enhance sensitivity during nighttime, I have opted for a PiNoir camera, which lacks an infrared filter. Consequently, when motion is detected, two sets of infrared LEDs are activated for the duration of the motion event. The LEDs are exclusively illuminated when it is dark and motion is detected.

The captured images are wirelessly transmitted to a shared SMB drive hosted on an old PC running Linux Mint. On this PC, an automatic process generates a time-lapse MP4 movie at the end of each day, compiling the images captured throughout the day. This setup ensures continuous surveillance and facilitates the convenient review of the day’s activities.

Images

Detail of the optocoupler and TIP122 based switching circuit.
Prototype of the camera system on a breadboard.

 

 

 

 

 

 

A cheap plastic container houses the Raspberry Pi, with the camera peeking out through a whole in the front. The whole assembly is housed in a weather-protected nook I installed above the front porch.
An electrical box houses the switch circuit. The cables dangling out from the front port provide 12V to the LEDs when the switch is on. There’s also a logic input on the side that gets connected to a GPIO pin on the Raspberry Pi. This input side is electrically isolated from the 12V side with the help of an optocoupler.

 

 

 

 

 

 

 

 

Motion detection software

I successfully installed “Motion” on the Raspberry Pi camera by following the provided instructions on the UV4L website (accessible at http://www.linux-projects.org/modules/sections/index.php?op=viewarticle&
). Throughout the installation process, I encountered some peculiar issues when attempting to exceed a resolution of 1280 x 1024 pixels. Nevertheless, this resolution proves to be more than sufficient for the intended purpose, allowing for detailed image capture.

One notable feature of “Motion” is its inclusion of a live webcam server, which enables convenient monitoring of the front porch from an upstairs location without the need for physical presence downstairs. Additionally, I implemented a mask file to exclude areas beyond our property from triggering motion events. These functionalities are straightforward to install and are extensively documented in other resources.

Python programs to switch lights on and off for a motion event

The “Motion” software that I installed comes with a convenient feature that allows the execution of scripts at the beginning and end of motion events. To harness this functionality, I developed two simple Python programs to interact with “Motion” and control the state of GPIO pins on the Raspberry Pi, which are responsible for activating two arrays of infrared (IR) LEDs.

The first program, called “eventResponderServer”, acts as a TCP/IP server running on the Raspberry Pi. It listens for incoming messages on a specific port. If the received message is “on”, the program sets a designated digital pin to a HIGH state. Similarly, if the message is “off”, the pin is set to LOW. The server program can be gracefully terminated by sending the “quit” message.

The second program, named “eventResponderClient”, is triggered by “Motion” when it detects the start or end of a motion event. It sends the corresponding “on” or “off” messages to the localhost port where the “eventResponderServer” is actively listening.

To configure the commands executed during motion events, you can modify the lines beginning with “on_motion_start” and “on_motion_end” in the “/etc/motion/motion.conf” file. These commands determine the actions taken when a motion event begins or ends, respectively.

/etc/motion/motion.conf excerpt
# 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

At the moment, the program is designed to utilize a single GPIO pin for activating the IR lights. However, it can be expanded to control multiple devices with ease. To prevent triggering a motion event when the lights are turned off, I made adjustments to the following parameters in the motion configuration file:

1. `lightswitch`: This parameter was set to 40, ensuring that a sufficient amount of time has passed before considering a new motion event after the lights are switched off.

2. `minimum_motion_frames`: It was set to 3, meaning that at least three consecutive frames with detected motion are required to trigger a motion event.

3. `pre_capture`: This parameter was set to 3, allowing motion to be captured in the pre-event buffer for three frames before the actual motion event is triggered.

By adjusting these parameters, I aimed to fine-tune the behavior of the system and minimize any undesired motion events when the lights are turned off.

/etc/motion/motion.conf excerpt
# 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 complete code for the Python helper programs can be accessed on my BitBucket account by following this link:

https://bitbucket.org/amphioxus/eventresponder/overview

Creating a daily movie with avconv

 

Instead of relying on the “motion” software on the Raspberry Pi to create videos, I have implemented a shell script on a larger Linux machine that runs nightly to generate a time-lapse MP4 movie from the sequence of images. The script utilizes a customized version of the Perl “rename” command that supports an incremental counter. During the renaming step, the original time-stamped file names from the camera are transformed into sorted file names with a zero-padded counter appended at the end. This allows the “avconv” tool to create a properly composed movie file from the sequence of images. You can find the modified “rename” program, which I named “renum” on my system, at the following link: http://www.volkerschatz.com/unix/uware/rename.html.
# 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
{ avconv -r 24 -i image_%05d.jpg -b:v 2080k -r 24 $FILE; } 2>>/tmp/avconv_error.log
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

Due to the high current requirements of the lights, it is not feasible to power them directly from the Raspberry Pi’s GPIO pins. To address this, I have implemented an opto-coupled transistor switch circuit, which serves two purposes: protecting the Raspberry Pi and enabling the control of the LED arrays powered by a separate 12V supply. Below is a schematic representation of the circuit:

[Please note that as a text-based AI, I’m unable to display or generate visual content. It’s recommended to provide a detailed description or seek assistance from a diagramming tool to visualize the circuit.]

Schematic of the opto-coupled circuit used to switch the LED arrays from the Raspberry Pi’s I/O pins. NOTE: “Dror” discovered that there’s an error in the schematic: as shown the LEDs connected to the header would always be on. JP1 on the header should not go to GND, but to the TIP122 transistor.

The switching circuit incorporates a 4N25 optocoupler to provide electrical isolation between the Raspberry Pi and the remaining circuitry. A TIP122 transistor, which was available in my collection of miscellaneous electronic components, is utilized for the switching operation. Additionally, an indicator LED, referred to as LED1, illuminates during a motion event to provide visual feedback. Adjacent to the schematic, there is a header interface where the LED arrays can be connected. A resistor with a value of 1.5K Ohm, denoted as R4, is also present in the circuit.

To enhance protection, I enclosed the small breadboard in a weather-tight plastic box. This additional layer of shielding provides further safeguarding compared to the existing wooden enclosure I constructed beneath our porch. You can refer to the accompanying gallery below for a visual depiction of the setup.


About The Author

Muhammad Bilal

I am highly skilled and motivated individual with a Master's degree in Computer Science. I have extensive experience in technical writing and a deep understanding of SEO practices.