Raspberry Pi Motion/Bird Cam


How it works
Introduction
Using a Raspberry Pi Model A, Canon IXUS 110 HS compact camera running CHDK and a PIR motion sensor (plus other bits) as a wireless motion detection camera.

A couple of hardware modifications for the camera were needed to make it a fully automated system. The camera was picked because I bought it as part of a job lot of broken Canon compact cameras and it runs the CHDK custom firmware.

CHDK is a great piece of software which gives a large range of extra features to many Canon compact cameras. For this project it is ideal because of the CHDK-PTP client that is available for the Raspberry Pi. This gives you the ability to take full control of the camera from the Raspberry Pi via software. This includes taking photos, downloading photos and deleting photos off the camera.

When a 12V 12Ah SLA battery is used to power everything you get 3-4 days of running time. This obviously depends on how many events are detected.

It is currently in a cardboard box but I plan to move it to something waterproof and eventually add a solar panel to increase the battery life.

It uses WiFi and FTP to copy the photos to a local FTP server so the system needs to be within range of a WiFi AP/router. Though this could definitely be replaced with some sort of 3G dongle to make it a truly remote motion detector camera.

Since I live in Manchester City Centre I've only had Pigeons make an appearance!

The Hardware
Raspberry Pi Model A
Canon IXUS 110 IS running CHDK (modified)
2GB SanDisk Class 2 SD Card
Generic Ralink RT5370 USB WiFi Adapter
Powered USB Hub (modified)
7-24V To 5V 3A DC Converter (modified)
PIR Motion Sensor
Arduino Compatible Relay
Mini Breadboard + Wires
DS18B20 Temperature Sensor (not required)
12V SLA Battery
Various Wires

DC Converter Modifications
Rather than using the USB Port two wires are soldered to the +ve and -ve terminals to allow direct 5V feeds. This was needed to power the camera. The DC Converter is hooked up a 12V SLA battery.

Camera Modifications
To enable the camera to be turned on when motion is detected two wires are soldered to the on/off switch of the camera. These wires are attached to a relay which gives you the ability to turn the camera on using very simple commands on the Raspberry Pi.

To power the camera without a battery two wires are soldered to the +ve and -ve battery terminals and attached to the wires coming out from the DC converter. The camera battery is rated at 3.7V, the official Canon mains power supplies are rated at 4.3V but these cameras run fine on 5V (which is very useful!).

USB Hub Modifications
The USB Hub is powered directly from the 5V DC converter via two wires soldered to the power socket of the USB Hub. The Raspberry Pi is then powered up when connected to the USB Hub which saves using the Micro USB power socket.

GPIO Setup
PIR Sensor
5V ------ VCC
GND ----- GND
GPIO17 -- IN

Relay
5V ------ VCC
GND ----- GND
GPIO18 -- IN


The Software
Rasbian - Wheezy
CHDK-PTP Client (a Raspberry Pi compatible build is available)
FTP
WiringPi

To keep things simple the motion camera is controlled using a few bash scripts and an init.d script.
The first three scripts are located in "/usr/bin/" and the init.d script is in "/etc/init.d/" These scripts are:

1. Main motion detection script

This script enables GPIO17 as an input and loops for the detection of motion on the PIR sensor. When motion is detected the camera switch script is run, then the CHDK-PTP script. Once the photos are downloaded to the Raspberry Pi they are upload via FTP. Everything is then deleted and the loop goes back to the start.

#!/bin/bash
#
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

gpio export 17 in

while true
do

HOSTftp=FTP-IP-address
USERftp=ftpuser
PASSftp=ftppass

currdate="`date +%y-%m-%d_%H-%M-%S`"
curryear="`date +%Y`"
currmonth="`date +%Y-%m`"
currday="`date +%Y-%m-%d`"
currhour="`date +%H`"

date

if [ `gpio -g read 17` -eq 1 ];
then

mkdir /tmp/chdk-download
mkdir /tmp/chdk-cap-$currdate
cd /tmp/chdk-cap-$currdate

echo "Motion Detected - Checking Camera"
camera-switch

chdk-cap-photo-motion

mv /tmp/chdk-download/1*/*.JPG /tmp/chdk-cap-$currdate/
rm -rf /tmp/chdk-download/*


ftp -inp $HOSTftp << EOF
user $USERftp $PASSftp
binary
cd outmotion
mkdir $curryear
cd $curryear
mkdir $currmonth
cd $currmonth
mkdir $currday
cd $currday
mkdir $currhour
cd $currhour
mkdir $currdate
cd $currdate
mput *
bye
EOF

rm -rf /tmp/chdk-cap-$currdate

else

echo "No Motion"

fi

date
echo "Script End"
echo ""
sleep 2

done

2. Camera switch script (camera-switch)

lsusb and grep are used to check whether the camera is turned on. If it isn't on the relay is turned on then off to turn the camera on simulating a press of the on/off button.

#!/bin/bash
#
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

cd /tmp
#ixus110-31bd
lsusb | grep -i -c 31bd >> lsusbcanon.txt
CAMERA=$(cat lsusbcanon.txt)

if [ "$CAMERA" = "0" ];
then
echo "Turning on Camera"
echo "18" > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio18/direction
echo "1" > /sys/class/gpio/gpio18/value
sleep 0.3
echo "0" > /sys/class/gpio/gpio18/value
echo "18" > /sys/class/gpio/unexport

sleep 3
else
echo "Camera Already On"
fi
rm /tmp/lsusbcanon.txt

3. CHDK-PTP client script to take photos (chdk-cap-photo-motion)

Using the provided file "chdkptp-sample.sh" along with some commands CHDK-PTP connects to the camera, deletes any existing photos, changes to photo mode, sets the zoom level to 0, takes 5 photos, downloads the photos to the Raspberry Pi.

#!/bin/sh
#

sudo sh /home/pi/chdkptp/chdkptp-sample.sh -c"-p=0x31bd" -e"delete DCIM" -e"exec sys.sleep(1000)" -e"luar switch_mode_usb(1); set_zoom(0); shoot(); shoot(); shoot(); shoot(); shoot(); switch_mode_usb(0)" -e"exec sys.sleep(2000)" -e"mdl DCIM /tmp/chdk-download" -e"exec sys.sleep(2000)" -e"delete DCIM" -e"dis" -e"quit"

4. init.d script to start detection on boot and to be able to stop/start (motion-photo-init)

Run "sudo update-rc.d motion-photo-init defaults" to enable the init.d script.
To stop - "sudo /etc/init.d/motion-photo-init stop"
To start - "sudo /etc/init.d/motion-photo-init start"

#!/bin/bash
# myapp daemon
# chkconfig: 345 20 80
# description: motion-photo daemon
#!/bin/bash
# myapp daemon
# chkconfig: 345 20 80
# description: motion-photo daemon
# processname: motion-photo

DAEMON_PATH="/usr/bin"

DAEMON=motion-photo

NAME=motion-photo
DESC="PIR Motion Log"
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

case "$1" in
start)
printf "%-50s" "Starting $NAME..."
cd $DAEMON_PATH
PID=`$DAEMON > /dev/null 2>&1 & echo $!`
#echo "Saving PID" $PID " to " $PIDFILE
if [ -z $PID ]; then
printf "%s\n" "Fail"
else
echo $PID > $PIDFILE
printf "%s\n" "Ok"
fi
;;
status)
printf "%-50s" "Checking $NAME..."
if [ -f $PIDFILE ]; then
PID=`cat $PIDFILE`
if [ -z "`ps axf | grep ${PID} | grep -v grep`" ]; then
printf "%s\n" "Process dead but pidfile exists"
else
echo "Running"
fi
else
printf "%s\n" "Service not running"
fi
;;
stop)
printf "%-50s" "Stopping $NAME"
PID=`cat $PIDFILE`
cd $DAEMON_PATH
if [ -f $PIDFILE ]; then
kill -HUP $PID
printf "%s\n" "Ok"
rm -f $PIDFILE
else
printf "%s\n" "pidfile not found"
fi
;;

restart)
$0 stop
$0 start
;;

*)
echo "Usage: $0 {status|start|stop|restart}"
exit 1
esac