I fancied figuring out if it was my cat or the neighbourhood cats pooping in my side alley (oh er missus!) so thought I’d find a use for my PiNoIR camera and that spare B+

I usually use RaspiMJPEG for webcam sorts of things like timelapse or somesuch, but it seems in a state of flux – the internal motion-detection system simply doesn’t work it would seem, and the external system is still using Motion and not the MMAL version, so its slow and can only cope with about VGA resolution on a B+, and it doesn’t seem to work in timelapse mode, and seems flaky at best anyway.

MotionEyeOS seemed like it was much more professional and motion-detection with timelapse worked really well, but again was limited to pretty low resolutions with weird aspect ratios. Also doesn’t seem to use motion-mmal anymore (think it did when it was motionpie).

Anyway, I figured the problem was software motion-detection using image analysis, so I decided to go the hardware route and use a PIR. So far I’ve come up with this Python script which is based on the excellent picamera module. It can do useful things like vertically flip the image (on the GPU!) which is handy as my Sainsmart camera module is a bit hard to mount the right way around!

Also the code uses interrupts so events don’t get missed and the CPU is mostly asleep. I chose to use 1080p resolution, but you could go up to to full 5MP (or 8MP on the new camera boards!) if you wanted to, forget 640×480

The only problem is that the PIR sensor doesn’t work through double-glazing, so I need to mount it in a box outside, which I was going to do eventually anyway.

#!/usr/bin/python

# import module
import picamera
import time
import RPi.GPIO as GPIO

# setup gpio mode
GPIO.setmode(GPIO.BCM)
PIR_PIN = 14
GPIO.setup(PIR_PIN,GPIO.IN)

# instantiate class
camera = picamera.PiCamera()

# vertical flip
camera.vflip = True

# set resolution
camera.resolution = '1080p'

# interrupt function
def onMotion(PIR_PIN):
    filename = time.strftime("image-%Y%m%d-%H%M%S.jpg")
    camera.capture(filename)

try:
    GPIO.add_event_detect(PIR_PIN, GPIO.RISING, callback=onMotion)

    # loop until interrupted
    while 1:
        time.sleep(100)

except KeyboardInterrupt:
    GPIO.cleanup()

You have to run the script using sudo, or from an init script like /etc/rc.local perhaps, and maybe set a directory to write the files to rather than just cwd.

Edit: just bought a v1.3 Raspberry Pi Zero and cable for this, as it should use a lot less power than the B+ and is a lot smaller to encase.