Wildlife camera with Raspberry Pi, Motion, and temperature sensing

I’m toying with the idea of going along to the Ipswich Raspberry Jam on Saturday 8th Aug and figure it’s be nice to have something to show. There’s of course our farm Raspberry Pi cameras which are in service and this one is riffing a bit off an idea Wildlife Gadget Man is playing with. He’s the guy with the wildlife – I only have sparrows[ref]I like my sparrows but they aren’t going to pose long enough for the camera, and presumably they have their heads under their wings in a hedge somewhere now, a hedgehog in a hog box is the sort of target that would work well here[/ref] so I have to make do with a stuffed toy stoat 🙂

stoatpi

temp

There’s nothing earth-shatteringly new in here, but the ability to make a box which gives you video, snapshots and a temperature plot taken from one of those Chinese waterproof DB18B20 probes is good for mammals.

The reason the picture is soft is because the camera is fixed focus and 15cm from the stoat; it needs reading glasses or a close-up lens.

It’s not demanding of hardware; I run this on an old-skool Raspberry Pi Model A with the big board headless and a nano USB dongle doing WiFi connectivity

Basically you run Motion on a Pi – that used to be hard but it’s as simple as :

# get your Pi camera onto /dev/video

sudo nano /etc/modules

append

bcm2835-v4l2

like the man says, then sudo reboot, then

sudo apt-get update

sudo apt-get upgrade

sudo apt-get install motion

sudo nano /etc/motion/motion.conf

change resolution to 960 by 720

# Rotate image this number of degrees. The rotation affects all saved images as
# well as mpeg movies. Valid values: 0 (default = no rotation), 90, 180 and 270.
rotate 0

# Image width (pixels). Valid range: Camera dependent, default: 352
width 960

# Image height (pixels). Valid range: Camera dependent, default: 288
height 720

set snapshot to every minute

# Make automated snapshot every N seconds (default: 0 = disabled)
snapshot_interval 60

ice this

# Restrict webcam connections to localhost only (default: on)
webcam_localhost off

make it always overwrite one file

# File extension .jpg or .ppm is automatically added so do not include this.
# Note: A symbolic link called lastsnap.jpg created in the target_dir will alwa$
# point to the latest snapshot, unless snapshot_filename is exactly ‘lastsnap’
# snapshot_filename %v-%Y%m%d%H%M%S-snapshot
snapshot_filename lastsnap

use the temporary file system to not trash your SD card

# Target base directory for pictures and films
# Recommended to use absolute path. (Default: current working directory)
#target_dir /tmp/motion
target_dir /run/shm

mask off all motion detection you can use this black PGM file (600k) if you are running 960×720

# PGM file to use as a sensitivity mask.
# Full path name to. (Default: not defined)
; mask_file value
mask_file /home/pi/blank960x720.pgm

then run it. Use a cron job to upload /run/shm/lastsnap.jpg to your website however many minutes you want and you’re sorted. You may view the motion jpg video on http://yourPiIPaddress:8081

To add the temperature display you follow Simon Monk’s instructions over on adafruit. I did a gonzo install using a 16-way header which is a nice cheap way of getting onto your Pi GPIO as long as you take care to get it the right way round and match up the start

Quick'n'dirty onewire isntall
Quick’n’dirty onewire install

but there’s nothing stopping you going the neater Adafruit way if that lights your fire. Now go

 

sudo apt-get install rrdtool which will do all the display for you, and make an rrd directory under the /home/pi dir. I used this shell script to actually set up the rrd database

#!/bin/bash
DIR="/home/pi/rrd/"
DS="SP"
STEP=600
# step is 10m = 10*60= 600
# save 365*24 raw samples of 60 mins (=8760 of 60m), 797 daily (24*4 samples =  96)
# one day is 48 steps, image with = 800 so raw is 16 2/3 days for 800 samples
# last 66 days is consolidate to avearge fo 4
# one year is consolidate to average of 32, make this an average of 48 and save three years (1152 days)
rrdtool create $DIR/$DS.rrd --start N --step $STEP \
DS:$DS:GAUGE:$((STEP*3)):-10:50 \
RRA:AVERAGE:0.5:1:800 \
RRA:AVERAGE:0.5:4:800 \
RRA:AVERAGE:0.5:24:1152 \
RRA:MAX:0.5:48:1152 \
RRA:MIN:0.5:48:1152

I hacked Simon’s code thusly

import os
import glob
import time
from commands import getstatusoutput

ID="/home/pi/rrd/SP.rrd"   # where rrd databases are held 
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')
 
base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + '28*')[0]
device_file = device_folder + '/w1_slave'
 
def read_temp_raw():
    f = open(device_file, 'r')
    lines = f.readlines()
    f.close()
    return lines
 
def read_temp():
    lines = read_temp_raw()
    while lines[0].strip()[-3:] != 'YES':
        time.sleep(0.2)
        lines = read_temp_raw()
    equals_pos = lines[1].find('t=')
    if equals_pos != -1:
        temp_string = lines[1][equals_pos+2:]
        temp_c = float(temp_string) / 1000.0
        #print "/usr/bin/rrdtool update "+ID+" N:"+str(temp_c)
        getstatusoutput("/usr/bin/rrdtool update "+ID+" N:"+str(temp_c))
        return temp_c
    
file = open("tempc.txt", "w")
file.write("StoatPi - temp: "+"{:.1f}".format(read_temp()) + "C time: " + time.strftime("%c"))
file.close()

and call it from cron every 10 minutes, offset from 0 by 1 (ie 1min, 11 min, 21 min etc), which updates the /home/pi/rrd/SP.rrd database and also drops in a caption for the picture in

/home/pi/tempc.txt

while probably also ought to go in the temp filesystem.

I deleted the original updating cron job. and put in another every 1 minutes and 11 etccalling this with a cron job, you have to sudo python that because you a putzing about with the hardware

Finally two minutes later (on a 3, 13, 23… raster)  I get another cron job to make the graph from the previously updated temperature and caption the picture

#!/bin/bash
DIR="/home/pi/rrd"
DIROUT="/run/shm"
ID="SP"

time_readible=$(echo $(date) | sed 's/\:/\\:/g')

#define the desired colors for the graphs
INTEMP_COLOR="#FF0000"
MIDTEMP_COLOR="#FF00FF"
OUTTEMP_COLOR="#0000FF"
AQUA="#00FFFF"
BROWN="#A52A2A"
CORAL="#FF7F50"
CRIMSON="#DC143C"
FORESTGREEN="#228B22"
GOLD="#FFD700"
RED="#FF0000"
ORANGE="#FFAF00"
GREEN="#00FA00"
GREY="#808080"
LGREY="#C0C0C0"
BLUE="#0000FF"
MAUVE="#FF00FF"

# combined detail
#hourly 1 day
rrdtool graph $DIROUT/temp.png --start end-2d  --width 800 --height 300 \
-a PNG -E  --disable-rrdtool-tag  \
DEF:$ID=$DIR/$ID.rrd:$ID:AVERAGE LINE:$ID$CRIMSON:"Temp" \
HRULE:6$LGREY:"T min (6 C)":dashes \
VDEF:SPmin=SP,MINIMUM \
VDEF:SPmax=SP,MAXIMUM \
VDEF:SPnow=SP,LAST \
COMMENT:" \n" \
COMMENT:"Stoat " \
COMMENT:" \n" \
COMMENT:"Temp now " \
GPRINT:SPnow:"%2.1lf C" \
COMMENT:"Temp min " \
GPRINT:SPmin:"%2.1lf C" \
COMMENT:"Temp max " \
GPRINT:SPmax:"%2.1lf C" \
COMMENT:"\n" \
COMMENT:"\n" \
COMMENT:"\n" \
COMMENT:"Last Update\: $time_readible" \
COMMENT:"\u" \
time_readible=$(echo $(date) | sed 's/\:/\\:/g')

convert /run/shm/lastsnap.jpg  -pointsize 24 -fill white  -annotate +30+710  '@/home/pi/tempc.txt' -gravity Center $DIROUT/stoatpi.jpg
scp insert your details here $DIROUT/stoatpi.jpg $DIROUT/temp.png

and job done. There’s no error checking which there really should be, but for a first cut it’ll do

Leave a Reply

Your email address will not be published. Required fields are marked *