Showing posts with label Raspberry Pi. Show all posts
Showing posts with label Raspberry Pi. Show all posts

Saturday, 21 September 2019

Bird box activity counter v3: Build, detect & log activity

Update Dec 2019:  see part 2 of this series that deals with logging entrance hole activity to a postgres database and text file:

I've built entrance hole detectors into two existing bird boxes, lets call those counter versions 1 + 2.
This year, the v.2 counter box had two consecutive Great Tit nesting sessions, 8 chicks fledgling in total (7 and 1).  With the data it records, it can generate informative visuals like this one that shows daily counts of 'in events' for nesting sessions 1 and 2.  Can you work out which was the more successful 2019 brood?

Nest box activity for two consecutive nesting sessions in Spring 2019


I re-visited this from an earlier version (v1), this post describes version 3.  It uses the same principle as a commercial product from Schwegler that displays a local count - their product doesn't do anything else and will set you back approx £65.

Commercial counter displayed on the of the box front

My detector uses a pair of infrared (IR) beams & detectors that are offset from each other giving an 'outer' and an 'inner' beam.  A bird coming in will break the outer beam before the inner one and vice versa for a bird exiting the box.  Beam disruption events are logged to a text file on the integral  Raspberry pi Zero W which also runs video motion capture software, controls the lighting etc.

By having two detectors, its possible to differentiate between 'in' vs 'out' events.  Sensor noise such as a bird popping its head in from the outside or a spider jumping up and down on one IR LED can be ignored.  This is better than a 'one beam' approach that would produce noisy data that would be impossible to clean.

My design is an evolved version of a project in the 'Raspberry Pi projects' book by Robinson & Cook.  Don't buy the book for this project as it uses obsolete hardware (something called a 'PiFace', I used that in my v1 counter from 2014), the python code is chock full of mistakes, the code also isn't available to download on the publisher's website.

I reckon my v3 version is simpler to do and I've fixed the code side of things too 😏

Parts / equipment
2x 5mm IR LEDs buy here
2x IR phototransistor QSE113 buy here
Some 0.25 watt resistors: 1x 100ohm, 2x 1k ohm, 2x 10k ohm
Small piece of stripboard (grandly(!) referred to as the 'interface board' below)
1.6mm / 2.4mm heat shrink tubing
Wire.. I buy one roll of black 2 core firework shooting wire every few years, and a box of ethernet cable provides virtually endless colour-coded twisted pairs of low gauge wire.
Raspberry pi Zero W + power source

For the box:
Plywood (front of bird box): 1x 18mm piece and 2x 3mm pieces
30mm flat drill bit for the entrance hole
Router with a narrow cutter for the cable runs, e.g. this 3.2mm one.

The idea is to create a plywood sandwich for the v3 counter, with the 18mm ply between two 3mm pieces.  In contrast, v1 and v2 used more layers of plywood and was more fiddly to make.

How to make this....
Start off by clamping the three plywood pieces together.  Drill the entrance hole through all three ( I use a 30mm hole) then put the inner and outer 3mm plywood pieces to one side.
Drill 4 small 'guide holes' through the inner 18mm piece only, in approx a square (ish) arrangement around the entrance hole.  Use these as guide to route a diagonal channel on either side.  The channels need to intersect the guide holes   You want an 'X' shape  with one / and \ channel cut on each side, some of these guide holes will also double up as cable conduits.  Cut a couple of cable channels for the LED and phototransducer as shown below.  Its important that the cable channels are not full thickness.


Cut a recessed chamber on the 'outer' face of the 18mm ply piece that is deep enough to fit a small piece of stripboard (no smaller than 8 holes along the top, 10 on the side).  Drill another small hole through the ply in the recess that connects to a channel that runs up to the top of the inner face.  Power and GPIO connections to the Raspberry Pi come out via this route to the Pi in the top of the bird box.

Routing channels for the phototransistor and LEDs is a bit fiddly, here's a closeup of my efforts.  Any over cut/gappy bit around the detector can be filled with blu-tac or wood filler.


Before making the 'Interface board' I prototyped it out to make sure it worked


Breadboard fiddling
The resistors are as follows:
1) 100 ohm for the in-parallel LED circuit (220 ohm may also be okay)
2) 10k ohm pull up resistor to 5V for the transistor collector
3) 1k ohm resistor for the transistor collector GPIO connection

A handy hint for making stuff with IR LEDs: You cant see when they're on, however if you point a digital camera (with a screen on it) at them, then the camera can see it.

The breadboard prototype evolved into this shrunk down version on stripboard:

'Interface' resistor board

I use 2 core cable to wire the phototransistor emitter and collector legs as shown above, and a couple of twisted pair wires from a piece of ethernet cable for the LEDs, using different colour twisted pair wires for each LEDs - this make is easier to tell them apart.  I'm in the habit of using the stripy one of the pair for the + and the solid colour for the - pole (helps avoid soldering stuff in-situ the wrong way around).

Wire the transistors and LEDs cables first, then slot them into their routed channels and solder in-situ to the prepared interface board as shown above.

There are 4 connections to be made coming off the interface board: (1)5v and (2) ground [GND] (3) GPIO_1 for inner beam, (4) GPIO_2 for outer beam connections.  For the 5V and GND I use two core cable again, and coloured twisted pair for the GPIOs - as before, having a stripy one and solid coloured one for the GPIO connections helps you tell which is which.

How you inerface this with your raspberry pi is up to you, these 4 wires can be connected directly to the appropriate GPIO pins.  In my boxes, the 5V and GND will connect direct to the recom switching regulator (R-78B5.0-1.5) that drops the box's 12v feed to 5v. 

In this setup the IR LEDs are 'always on'.  I cant forsee a situation where I may need to turn them off but you could alternatively wire the LEDs via a second GPIO for power and power them on/off programatically.

The holesensor.py python script writes a single line to a log file if one of the beams transitions from broken to whole or vice versa.

The logfile logic is as follows:  BEAM,STATE,event time
Outer beam = 1; Inner beam = 2
Whole = 1; Broken =0

In this excerpt from the log, a bird has come into the box:
Outer beam broken, event_time
Inner beam broken, event_time
Outer beam whole, event_time
Inner beam whole, event_time

### recordBird_v3 starting up at:21 Sep 2019 09:47:35.990
1,0,21 Sep 2019 09:48:04.100
2,0,21 Sep 2019 09:48:04.446
1,1,21 Sep 2019 09:48:05.180
2,1,21 Sep 2019 09:48:05.228

The python script 'holesensor.py' that records this is detailed below.
On my 'to do' list is to modify this to record to a database rather than a static text file. 
Having this recorded to a database opens up the possibility of connecting remotely to this box and directly querying its on-board database.

The 'log to file' version is below.  I'll write up the graphing functions in another post...

import RPi.GPIO as GPIO
from time import sleep
import time
import datetime

# Change log
# 16/09/19 updated for zerocam 7

GPIO.setmode(GPIO.BCM)          #use BCM pin numbering system
GPIO.setwarnings(False)

whichBirdcam = 'zerocam7'

#file used to log entrance actions
EntrancelogFile='/home/pi/testpizero/logs/zerocam7_birdlog.txt'
OpenEntrancelogFile= open(EntrancelogFile,  'a', 0)

#function to return the current time, formatted as
# e.g. 13 Jun 2013 :: 572
def getFormattedTime():
    now = datetime.datetime.now()
    return now.strftime("%d %b %Y %H:%M:%S.") + str(int(round(now.microsecond/1000.0)))

#generate and record an event to file
def logEntranceEvent(sensor, state):
    OpenEntrancelogFile.write(str(sensor) + "," + str(state) + "," + getFormattedTime() + "\n")


#setup GPIOs

detect_OUTER = 22 #6    #set GPIO pin for Outer photransducer (input)
detect_INNER = 23 #12    #set GPIO pin for Inner photransducer (input)

print 'detect_OUTER = ' + str(detect_OUTER)
print 'detect_INNER = ' + str(detect_INNER)

#Constants
#OUTER_BEAM = 1
#INNER_BEAM = 2

#WHOLE = 1
#BROKEN = 0

# setup GPIO pins:
GPIO.setup(detect_OUTER, GPIO.IN)   #set Outer GPIO Phototransducer as input
GPIO.setup(detect_INNER, GPIO.IN)   #set Inner GPIO Phototransducer as input


#indicate the point the program started in the log
OpenEntrancelogFile.write("### recordBird_v3 starting up at:" + getFormattedTime() + "\n")
print "============================================"
print whichBirdcam.upper() + ": Starting up entrance hole counter script..."
sleep (0.5)

#Set initial state of WasBroken for both beams:
OUTER_WasBroken = False
INNER_WasBroken = False

# LED status check
# LEDstate= GPIO.input(detect_INNER)

print ""
print "detect_OUTER status = " + str(GPIO.input(detect_OUTER))
print "detect_INNER status = " + str(GPIO.input(detect_INNER))
print ""


#When the detector          'sees' IR led, the detector pin is 0/LOW/False
#When the detector does not 'see ' IR led, the detector pin is 1/HIGH/True

def checkStatus():
    if GPIO.input(detect_OUTER):  #if OUTER detector does not see IR led, print error, GPIO.input = HIGH
        print "OUTER beam detect failure!, status = " +str(GPIO.input(detect_OUTER))
        #quit()
    else:
        print "OUTER beam detect - passed :) | Status = "+str(GPIO.input(detect_OUTER))

    if GPIO.input(detect_INNER):  #if INNER detector does not see IR led, print error, GPIO.input = HIGH
        print "INNER beam detect failure!, status = " +str(GPIO.input(detect_INNER))
        #quit()
    else:
        print "INNER beam detect - passed :) | Status = "+str(GPIO.input(detect_INNER))
        print "============================================"
        print ""

def status2():

    print "============================================"
    print "OUTER_IsWhole = "+str(OUTER_IsWhole)
    print "OUTER_WasBroken = "+str(OUTER_WasBroken)
    print ""
    print "INNER_IsWhole = "+str(INNER_IsWhole)
    print "INNER_WasBroken = "+str(INNER_WasBroken)
    print "============================================"
    print ""

checkStatus()

# (x,y)
#  x=beam   (1=Outer,2=inner)
#  y=state  (1=Whole,0=Broken)

while (True):
    OUTER_IsWhole = (GPIO.input(detect_OUTER) == 0)  #read current state of beam
    INNER_IsWhole = (GPIO.input(detect_INNER) == 0)  #read current state of beam
    
    sleep(0.01)

    if (not OUTER_IsWhole and not OUTER_WasBroken): #if OUTER beam is broken [FALSE], and OUTER_WasBroken=FALSE (ie default value)
        OUTER_WasBroken = True
        print "(OUTER,Broken)"+ getFormattedTime()
        status2()
        logEntranceEvent(1,0)


    if (OUTER_IsWhole and OUTER_WasBroken): #if Outer beam is whole [TRUE] and OUTER_WasBroken=TRUE
        OUTER_WasBroken = False
        print "(OUTER,Whole)"+ getFormattedTime()
        status2()
        logEntranceEvent(1,1)


    if (not INNER_IsWhole and not INNER_WasBroken): #if INNER beam is broken [FALSE], and INNER_WasBroken=FALSE (ie default value)
        INNER_WasBroken = True
        print "(INNER,Broken)"+ getFormattedTime()
        status2()
        logEntranceEvent(2,0)


    if (INNER_IsWhole and INNER_WasBroken): #if INNER beam is whole [TRUE] and INNER_WasBroken=TRUE
        INNER_WasBroken = False
        print "(INNER,Whole)"+ getFormattedTime()
        status2()
        logEntranceEvent(2,1)

GPIO.cleanup()

Here is a 'production version' of this being setup.  I swapped out the camera unit from an existing box.  You can see the IR leds in this camera - the're invisible to humans/birds


2x entrance hole IR beams - Digital camera view only!



Saturday, 1 June 2019

Dual camera birdbox 2019 update: Mistakes, Fixes, Bodges, nesting success and same year re-nesting

The dual camera bird box build started off back in 2016, and has been live since the 2017 Spring nesting season. It was my second Raspberry Pi-based birdbox, and my first attempt to combine a Raspberry pi camera module with a USB webcam on the same Raspberry pi mini-computer.  The system has video motion-capture, day + night illumination modes, an entrance hole activity logging mechanism, and also monitors temperature (?why not)...

Nearly fledging: My favourite picture of the 2019 season

This year (2019) is its first successful nesting season, seven great tit chicks fledged a few weeks ago, with another pair currently sitting on five eggs. I've had some requests on the Twitter about his box so this is an attempt to describe some of the modifications I've made over the last few years to fix various issues, and share some of the stuff I've learned along the way.

That's a 32mm entrance hole 

The Cameras

Camera 1 (SIDE): This is a Microsoft LifeCam Cinema usb webcam.  It can only see in visible light - I used one of these in my first birdbox (side-view-box, 2016).  A motion-jpeg (mjpeg) network video stream from this webcam is picked up by a remote PC running iCatcher CCTV software.  iCatcher isn't able to include audio from this source.

Camera 2 (TOP): This is a Raspberry Pi v2 Infra-Red (IR) camera positioned above the nest space.  An IR-cut module sits between the camera and the main nesting chamber and switches it between IR (night/dark) and visible light sensitivity (day/lit) .  A motion capture application called pikrellcam uses this camera, with the videos saved directly to the same networked PC mentioned above.  Camera-1 (the webcam) has a handy built-in microphone that pikrellcam cleverly uses, adding sound to the captured video from camera 2.

Camera 1 (Side) fits into height-adjustable slots.  Entrance hole is on the Left of this pic

The entrance hole has two IR beams that once broken record the event to a file.  Based on the order of breaking it's possible to work out whether the bird is coming or going.  I added a visual indicator to check this is working, the video below shows the outer then inner beams being triggered whilst I balance precariously up a ladder...


The Brain: This is a Raspberry pi model B+.  It's powered over a single cat5 network cable run of approx 150 meters using power-over ethernet (PoE),  which also connects it to my home network.

Yes, I know the wiring is a mess...
Practicalities of video review
The side camera can be reviewed directly via iCatcher console on a remote PC, or via a webpage using any network connected device.  Exporting video / screengrabs from iCatcher is a pain in the proverbials.

iCatcher Console with Camera-1 as source (USB webcam.  Visible light only.  No audio)

The top camera (Raspberry Pi cam) can be reviewed in a web browser on any network-connected device.  Exporting video / images is really easy and can be downloaded directly via a web browser.

Pikrellcam with Camera-2 as source (Raspberry Pi v2 IR camera+IR cut (day mode)_white LEDs on.  WITH Audio

Design evolution, 2017 to now (May 2019)

2017: The Bird Box went up in April.  No birds came in all year with just the occasional wasp and spider triggering video capture (pikrellcam).  The entrance hole had logged some attempts that were probably birds popping a head in, so assuming  that the hole was too small, I enlarged it from 20mm to 32mm over the Winter.  This wasn't as simple as just drilling the hole bigger as the entrance hole IR activity detector beams needed moving to accommodate a bigger hole.  The 'glass partition' between the side camera and the main nesting chamber kept getting dusty and it also created an annoying reflection of the side camera (which could essentially 'see itself'), so I replaced it for a half height plywood partition that the camera could see over, giving it an unimpeded view into the box, as well as allowing its microphone do a better job.



This box did do some useful work that season - Using a programme called ffmpeg, I used it to transcode a video feed from a separate, less-powerful Raspberry pi/usb webcam combo on a Robin nest and live-stream the result to YouTube.

2018: The enlarged entrance hole meant birds were coming in periodically, probably looking for food.  The default lighting remained on 'night mode' (just infra-red) as I thought the birds would be put off by the visible light LEDs.   I also hadn't got round to making the day-night switching happen automatically.

By April we had a pair of great tits bringing in moss.    I had the 'bright' idea of making the white leds come on when movement was detected by pikrellcam software to improve the daylight video capture... bad idea.  What I actually ended up with was a system that kept switching from night to day mode whenever a bird came in.  I think that the 'thunk' of the IR cut module switching between modes freaked them out so they nested in a neighbour's box instead.  That was the end of Spring 2018 nesting.

THIS YEAR.. 2019: A great tit pair started making visits from early March this year.  Nest building started 10 March, nine eggs laid and eight hatched on approx 17 April.  The last one fledged two weeks ago 7:50am on Sunday 5th May.  Unfortunately I missed them hatching as the PC where the videos are saved had crashed and I was away on holiday.

I also got around to fixing the day/night transition as described in this post, so lights come on at sunrise and off at dusk (switch to IR mode).

A selection of images / videos from nesting session 1

Cropped-in still image from camera 2.  Lighting aided by south-facing window on RHS of this image

Feeding False Black Widow Spider
Difficulty swallowing another false black widow spider

The next image is a screen-grab from a top camera video.  These are really easy to make using vlc media player.

An explosion of Great Tits

This is the male on the day the last chick fledged.  He's looking a bit battered

Scruffy male adult after the chicks all fledged

So... I though that was it for this season, which was timely as we were just about running out of disk space on the PC that stores the captured video.  I removed the remains of the deceased chick, and in the process broke the night illumination mode...

This one didn't make it :(
I switched from motion capture to timelapse on the last couple of days (pikrelcam makes this easy).  I converted this to a timelapse using Adobe Lightroom then converted it to a manageable size in vlc.  The dead chick above sadly passed away during this period which is evident particularly in the overnight section...



Poo-cam?
Daylight-sensitivity / video quality from the top down camera had dropped considerably over the previous year.  With no physical partition, the chicks were able to have a lovely time jumping up and down and pooing on the the side camera too.......Leaving a 'poo-obscured cam in the day, cant see anything at night' bird box.

Surprise 2nd nesting
...But 5 days later, another Great tit pair have moved in (Fri 17 May) and re-built the nest.  I've never had two back to back nests in the same box before.

And who miss, are you? this is the second female re-building the nest
So, poo-cam, poor lighting an degraded image quality will never do, so I removed the top camera section and cleaned the mess off the side camera that you can see in the picture above.

Top camera modifications... New Daylight LEDs / IR cut replacement
The Raspberry pi camera has poor low light sensitivity so I wanted to improve the lighting.  I swopped some of the existing 5mm LEDs for some LED panels from Pimoroni- I've used these in four other bird boxes I built this year see here.  They give a nice even illumination, avoiding the spotlight effect you get with 5mm LEDs.  You can see my original attempt to avoid spotlighting with the original 5mm leds by pointing them up towards a white background, but they don't really make enough light for the Raspberry Pi camera which has fairly awful low light sensitivity which isn't surprising given that its lens aperture is a couple of mm.

New LED panels on underside of top section

 I also swopped the IR cut for a new one (see this post) as the old one had fogged up.

2019 2nd nesting, updated performance...
Our five eggs have yet to hatch, the image quality is much better:

Cropped down to show detail.  I like the symmetry in this one
I'm using a python module called ephem to trigger the day to night lights-off at sunset, however she's usually tucked up 1 to 1.5 hrs before then.  Here you can see aside camera view before the upgrades (or cleaning the webcam...)

Female number two turning in for the night
The new pair has a different male
Male number 1 was looking very shabby at the end of the the last nesting session.
This clip shows make number 2 feeding female number 2 while she's incubating her five eggs, he's not scruffy, so Ithink that he's a different bird.  Can't say much about her though.


More to come... when this lot hatch


Monday, 5 June 2017

ZeroView IR-Cut hack

This is hopefully the beginning of something beautiful...  This a ZeroView, which is a neat way to attach a Raspberry Pi zero-W + camera module to a window:


I've modified modified the ZeroView (+IR camera module) to squeeze in an infra-red cut filter (IR-cut) between the ZeroView and the PiZero, making a wifi enabled 8MP camera that can see in the dark (+IR illumination)...


This is still very much a work in progress as I need to add an IR illumination source too.  Some incarnation of this will find its way into a nest box or a trail camera.  As-is it does stay stuck to a window, but the addition of the perfboard does make it a bit top-heavy.  I'm sure it can be refined a bit...

IRcut OFF (top) & ON (bottom)

Here is a video showing filter on and off.  This was captured using PikrellCam:


Filter is switched using a L293DNE, connected in the above example as follows:


Sample python script:
import RPi.GPIO as GPIO
import time
import datetime as dt
import os

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.cleanup

IRcutEnable=13
IRcut1A=6
IRcut2A=9

IRcutPins=[13,6,9]
for IRcutPin in IRcutPins:
    GPIO.setup(IRcutPin,GPIO.OUT)

#Default states:
global IR_cutState
IR_cutState="not_set"

def separator():
    print "---------------------------"

def IRcut_DayTime():

    print "IR cut DAY"
    print "============="
    GPIO.output(IRcutEnable,GPIO.HIGH)
    GPIO.output(IRcut1A,GPIO.LOW)
    GPIO.output(IRcut2A,GPIO.HIGH)
    print "IRcutEnable ("+str(IRcutEnable)+") = HIGH"
    print "IRcut1A ("+str(IRcut1A)+") = LOW"
    print "IRcut2A ("+str(IRcut2A)+") = HIGH"
    print ""
    
    global IR_cutState
    IR_cutState="IRcut_DAY"
    time.sleep(0.5)

def IRcut_NightTime():    

    print "IR cut NIGHT"
    print "============="
    GPIO.output(IRcutEnable,GPIO.HIGH) #was LOW
    GPIO.output(IRcut1A,GPIO.HIGH)
    GPIO.output(IRcut2A,GPIO.LOW) #was HIGH
    print "IRcutEnable ("+str(IRcutEnable)+") = LOW"
    print "IRcut1A ("+str(IRcut1A)+") = HIGH"
    print "IRcut2A ("+str(IRcut2A)+") = L"
    print ""
    
    global IR_cutState
    IR_cutState="IRcut_NIGHT"
    time.sleep(0.5)

def IRcut_STOP():    

    print "STOP"
    GPIO.output(IRcut2A, GPIO.LOW)
    time.sleep(2)

while True:
 IRcut_NightTime()
 time.sleep(2)
 IRcut_DayTime()
 time.sleep(2)


Tuesday, 21 March 2017

2017 Double camera Bird Box - sneaky peek

My 2017 Bird Nest Box should hopefully be up and running later this week, hopefully not too late for this season.  This version has two camera:  A 'from the side' camera which is a webcam (as described in previous posts), and a 'view from above' camera that uses as raspberry pi InfraRed (IR) camera with Infrared-cut to allow night and daytime viewing, I've added dimmable IR and non-IR led illumination.  The RPi camera does video capture via the marvelous program PikrellCam.

Test screen shots below (Microsoft LifeCam above, Raspberry Pi v2 IR cam below)

Daytime
Daytime previews
Night-time
Night time previews
I've also included an entrance hole counter and facility to measure ambient temperature and outside light levels.

More details to follow....

Monday, 12 December 2016

Blue tit argument...

The bird box has been recently used as an overnight roost for a blue tit.  On a couple of occasions we've had two in there.  Today was a little different since tit 1 didn't appreciate tit 2 in the same space, as can be seen in the following clip:



It's interesting that in addition to feet and beaks being used as offensive weapons, there are a couple of hooks using a wing...

Right hook


The posturing at the beginning is also interesting:

Posturing

Reminded me a bit of this



Sunday, 8 May 2016

Sunset timelapse: Raspistill vs PiCamera

There two ways (that I know of)  that the Raspberry pi camera can be triggered to take a still image, using Raspistill, or PiCamera.  PiCamera is a python interface for the Raspbery Pi camera. Raspistill can be called from the command line [or... within a python script using os.system("raspistill commend etc").

My preliminary attempts at sunrise timelapses using PiCamera have lead to over exposed skies, with all the details blown out.  This side by side comparison compares:  PiCamera (LEFT) to Raspistill (RIGHT).  

These timelapses are made from a consecutive series of alternate jpgs (PiCamera then RaspiStill) on default settings, as follows (I've left out any referenced variables to stop it getting too unwieldy):
PiCamera
def imagePiCamera():

 with picamera.PiCamera() as camera:

  camera.led = False
  camera.resolution = (2592, 1944)
  camera.framerate = (1, 1)
  camera.vflip = False
  camera.hflip = False
  camera.quality = 100
  camera.exposure_mode = 'auto'
  camera.awb_mode = 'auto'
  camera.image_effect = 'none'
  camera.color_effects = None
  camera.start_preview()
  time.sleep(2)
  camera.annotate_bg = True
  camera.annotate_text = dt.now().strftime('%Y-%m-%d %H:%M:%S')
  camera.capture(folderToSave + "/" + s_fileSerialNumber + "_PiCamera.jpg")

RaspiStill
def imageRaspiStill():    
 os.system("raspistill -w " + str(imgWidth) + " -h " + str(imgHeight) + " -o " + str(folderToSave) + "/" + s_fileSerialNumber + "_imageRaspiStill.jpg --nopreview -awb auto") 

My take on this is that I get a better sky / sun using RaspiStill, which is a bit of a disappointment since I like being able to annotate with text (as you can see in the PiCamera version (LEFT)... which is no use in a timelapse, I just forgot to switch it off...)

For interest, the 'grouped per-method' images are make into a video as follows:
#rename files
aa=0;for i in `ls`; do sudo mv $i `printf "%04d" $aa`.jpg; aa=$(($aa+1));done
#make timelapse
avconv -r 24 -i %04d.jpg -r 24 -vcodec libx264 -crf 20 -g 15 output.mp4

I got fed up waiting for this to run on my Raspberry pi, so run it on a linux virtual machine through virtualBox on a windows PC = much faster.  The RaspPi3 will compile a 800 image timelapse in approx 30 min using this approach.  Takes me approx 1 min using the other approach.

For the comparison... A side-by-side stitch of the two sunset timelapses as follows:
ffmpeg -i timlapse_PiCamera.mp4 -i timlapse_RaspiStill.mp4 -filter_complex \
'[0:v]pad=iw*2:ih[int];[int][1:v]overlay=W/2:0[vid]' \
-map [vid] -c:v libx264 -crf 23 -preset sideBySide.mp4



Saturday, 13 June 2015

Ground-level wildlife webcam camera hack

Over the last week or so I've been attempting to photograph my local badgers using conventional means (DSLR + telephoto lens) - the main problem being: 1) badgers are active at dusk / night, so light levels are low, 2) they are very timid so don't let you get close.

This is the closest I managed to get 'in person':
Badger - can you spot her?
Wanting to get better pictures, I cobbled together an improvised ground level webcam to see if I could get a more 'up-close and personal' perspective:

Cobbled together 'Garden-cam'
This is an unused robin nesting box, with a TP-link POE adapter and a Raspberry Pi model B with Microsoft Lifecam Studio webcam.  All sourced cheaply from ebay. Connected via oudoor cat5 ethernet cable to a PC running iCatcher Console.  The video stream is setup as described  in this post.
I part set this up one evening last week, and left wires and components scattered about having popped in to eat - I left it on in the hope that something would wander past, and got this footage of one of my local badgers:


You can see her being a bit wary of the attached gear, but not to the point that she wont come and investigate.  Later that night I stuffed all the components into the robin box to tidy things up.  Since then,  we have got nice views of the local wildlife as the following screen grabs show:

Passing fox: 4:30 am
Red deer fawn
Squirrel
Jay with mohican
In most of my bird boxes I've used the Microsoft LifeCam.  I only recently acquired a LifeCam Studio ebay bargain - its much better in low light levels due to a bigger sensor size.  It cant see in the dark, but is good for low light levels

Sunday, 16 November 2014

Part 2: How to make your own Raspberry Pi Trail Camera 'PiTrailCam': Basic design model

In part 1 of this series, I outlined how a Trail Camera is made, and what might be used to make a home-brew version.  

I've put together a basic functional trail camera, a very early prototype if you like. 
I'm testing with a standard Raspberry Pi camera, not the IR version.  I do have an IR version, but haven't got around to using it yet.  For now, I'm limited to daylight triggering since I've not yet incorporated my IR illuminators since the box (tupperware - no expense spared) was too small to incorporate all the required bits.

This shows the prototype build so far (lack of hot glue gun skills notwithstanding).  This will be hardwired into my home network, and uses power-over ethernet (PoE) hence the wire going to into it.

Simple front view showing PIR and RasPi camera with LDR detailed in insert

PiTrailCam ver1 - Inside
This is a cut-down version of the version I had planned out on my desk, which included a relay that triggered a separately powered IR LED array, which unfortunately does not fit in the box.  Version 2 will probably be in a wooden box that is a bit more roomy and durable, and can accommodate a relay switch for the IR LED arrays.

Kit used in RasPi TrailCam version 1
Raspberry Pi model B
Raspberry Pi camera + supplied ribbon cable
Power over ethernet & connectors
I'm planning on directly splicing a hacked microUSB cable to the TP-Link power-out but bought the wrong cables...so have to make do with more bulky cables following this guide
  Micro USB (male) to USB cable (female)
  USB (male) to barrel power connector
Small prototyping breadboard
Female to male breadboard wires (various)
PIR motion sensor: Components, wiring and code described here
Mechanism to measure light level: code + components from here
Not strictly necessary in this build, but will be used to measure ilght level to activate IR led array in version 2:
  1x 2.2 kOhm resistor
  1x 1uF capacitor
  1x Light Dependent resistor

Prototype board layout as follows.  Note, I significantly slimmed this down to a small prototype board, but tend to use a larger breadboard with GPIO breakout at the 'drawing board ' stage.  this also shows a possible layout that will incorporate a relay to operate a pair of IR LED arrays:


For now, I'm just using the PIR (motion sensor) and LDR (measure light level) aspects .

First imageSome things I'm very happy with, others not I'm less so..

The observant among you will spot something wrong with this image...
Whats really cool is that I've got the time and date stamp included at the top (erm, bottom?) of this image.

Timstamp - just to prove it....
How the image capture works
I've coded the scripting side of things in Python.  I'm relatively new to this, so its a fun way of learning a new programming language, and to be fair most of this is mercilessly cribbed from other websites/blogs.

The Raspberry Pi camera is a described here, and can be used to capture video or stills, or both at the same time (may come back to this).  You'll mostly see the two programs Raspistill and Raspivid referred to which are used to capture still images and video respectively.  There are also several third party libraries built for it.  For this application I've used the PiCamera library.
My limited Python skills will likely show here, but as I understand it this offers a way for python to directly access the camera hardware, versus using calls to external software (such as to Raspistill and Raspivid).

In your python code, you have the option of either calling Raspistill as follows:
os.system ("raspistill -o /mnt/SHARE/captures/TrailCam.jpg")

or using PiCamera module, where you can see I've added a camera.hflip and camera.vflip command to fix the upside down and back to front image above.
def recordImage2():
 
 timestamp = dt.datetime.now().strftime('%Y%m%d%H%M%S')
 print "Motion Detected: " , dt.datetime.now()  
 
 with picamera.PiCamera() as camera:
  camera.led = False
  camera.resolution = (2592, 1944)
  camera.framerate = (1, 1)
  camera.vflip = True
  camera.hflip = True
  camera.quality = 100
  camera.exposure_mode = 'auto'
  camera.awb_mode = 'auto'
  camera.image_effect = 'none'
  camera.color_effects = None
  camera.start_preview()
  time.sleep(2)
  camera.annotate_bg = True
  camera.annotate_text = dt.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  camera.capture_sequence(['/mnt/savelocation/TrailCam_'+timestamp+'_image%02d.jpg' % i for i in range(3)])

By calling recordImage2() on a PIR activation event causes 3 images (image1, image2, image3) to be saved to a network location that I've mounted to a folder in /mnt, and am currently saving files there.  Not sure how that will pan out if I switch to video though.

How to get text overlay working with picamera python library
I'm quite pleased that I have been able to get the text overlay working.  The next thing to do is see if I can get a dark background behind the time & datestamp, as date and time in white over a white sky isn't much use to anyone.

At first I could not image overlay to work, and could not see why the instructions here did not work.  Turns out I was running an version 1.5 of PiCamera, and need at least the current version (1.8 at this time).  You can tell which version you're running by following these instructions here.  You can update that by doing sudo update then sudo upgrade, you may need to update the Raspberry Pi's firmware : sudo rpi-update.

How to mount network drive to Raspberry Pi
For info, to setup network mounting you need to edit /etc/fstab as follows:

sudo nano /etc/fstab

Then add the following line:
//XXX.XXX.XX.XX/SHARE/TrailCamPi /mnt/SHARE cifs username=RasPiUser,password=RasPiPwd,uid=1000,_netdev 0 0

Ctrl & O, then Ctrl & X exits the nano text editor.
At a reboot, (or sudo mount -all) the network folder will be mounted at /mnt/SHARE

/XXX.XXX.XX.XX/SHARE/TrailCamPi = IP address of target PC with save file destination folder.  Although its not strictly necessary, and you could setup a network share with no user password protection, I've set mine up with a dedicated user RasPi user + password on the destination machine, and pass those credentials with the mount command.

I'll sign off with another badger video from my commercial Trail cam, captured a couple of days ago:




Next step is to swop out the standard RasPi camera to the PiNoir, and add some LED arrays.