Remote Farm camera using Raspberry Pi – alpha test version

At The Oak Tree we have acquired two bullocks/steers, and it would be good to be able to monitor these guys to check they are okay.

cattle
cattle

The obvious way is a GSM trail camera, which has got some merit. However, these are typically tripped by movement, and you get a lot of that outside. It might work to use a trail camera with a 15 minute trigger lockout – it’d be tripped all the time but wouldn’t spam you senseless with the 15 min delay. But it’s going to be dear to run as they tend to use MMS – giffgaff charge 16p per MMS for instance, whereas their data rates are 20p per 20Mb . CCTV solutions have the same problem – they are event triggered, whereas we want to be able to see a picture taken sometime in the last 15 minutes. Well, obviously we’d really like realtime streaming video by a pic at most 15 minutes old is a decent second best 🙂

What we ideally want is a camera you can send a message to to take a picture.

I used to have a Youthnet V900 which you could send an SMS to take a picture, but it was the most maddening hunk of junk I have ever purchased. Configuring the settings was done by SMS, and I only ever got it to work with Virgin mobile once. Then Virgin must have changed something and I never got this to work again, either with Virgin or with Giffgaff. In the end I put a hammer through it so it wouldn’t waste any more of my time and money. The satisfaction of doing that was the most value I got out of it.

I took a look at this trail cam and recognised the same commands as the Youthnet . I’m just not going to go there again if it uses the same software. Plus there’s the fact that it doesn’t really suit what I want it to do.

The Pi’s USB subsystem isn’t good enough to run a 3g dongle

So it’s time to break out the Raspberry Pi. Unfortunately the USB subsystem of the Pi means I couldn’t use Gammu directly with a Huawei E156G USB 3G dongle. It would work for a while and then conk out, and only come good again when the Pi was power cycled, not even a restart would fix it. That’s a real shame – this would save me a lot of power drain. Maybe it’s specific to this dongle, but there is always a world of hurt when it comes to the Pi and USB because of the power problem, and a 3G dongle has a high power usage when connected. Even running the E156G off an approved USB separately powered hub and the Pi off an approved PSU didn’t make it any better.

Go MiFi

Obviously if your site has WiFi you don’t need to wrangle with 3G, but there is a lively market in boxes to put a WiFi hotspot using 3G, called MiFi devices. You need to configure these to make use of your 3G dongle (and make sure they are compatible), the type I used is a TP-Link MR-3220

1501_TL-MR3020-V1-03

So I used a MICRONEXT  MN-WD552B WiFi dongle in the A’s single USB port, which seems reliable. Of course I now eat the power drain of the Pi, WiFi is never low power and the TP-Link 3020 MiFi device gives me another power hit. But it works, and I needed results fast rather than good, so it’ll do for now.

The Raspberry Pi Camera module is really rather excellent

The camera module that the Pi foundation sell for of the Pi is rather good – the larger version of the pic above is already scaled down by half in the camera to reduce the file size. And I compressed it a fair bit. You can control the camera in Python too, using Picamera. Python seems to be the default language for the RPi.

Although the Raspberry Pi is credit card sized, it’s remarkable how big it gets if you want to do anything with it. I used a box I already had – if I decide this works well enough for a permanent version then I will use a PICE waterproof case, but for the prototype a temporary rig is fine.

the Pi gets big fast when you hang enough onto it to make it useful
the Pi gets big fast when you hang enough onto it to make it useful

At the moment both are powered up all the time, and a cron job takes a picture and SFTPs it up every 15 minutes during the day. The Pi and the TP3020 are powered via one of those dual-output 12V car to USB converters, the power drain at 12V is 250mA which is horrible, meaning using 40Ah of a 80Ah leisure battery will take 40*4=160 hours, nearly a week. Which is nasty, but livable with. There is massive opportunity to cut the power drain by bringing up the TP-Link 30210 and the Pi only once every 15 minutes when it’s light – they can be up and do their stuff in 5 minutes so I’d get a 3x drop in power drain from that, and not running in the night would save me another third.

The installation is bush-league, but this is going to need a bit of optimisation anyway

the camera is at the top left of this IBC
the camera is at the top left of this IBC

and a close-up shows just how bad it is – waterproofing by electrical tape is living on borrowed time. But that’s where those nice people at PICE come in, so there’s no point in putting any real work in that.

best not let the IEE see that else they'll revoke C.Eng for disgraceful and outrageous bodgery of the first order ;)
disgraceful and outrageous bodgery of the first order 😉 The PICE case has solved most of the mechanical challenges kludged together here.

This shows one of the hazards of this location, in that the crows sit on the bar surveying their domain and crap on the IBC. There’s no crap on the bars though, so I might get away with it. Some anti-bird spikes might be in order.

 #!/usr/bin/python
#$Id: takepic.py 53 2014-06-26 16:30:17Z richard $
import time
import picamera
import paramiko
import os
import socket
import datetime
# import RPi.GPIO as GPIO

# GPIO.setmode(GPIO.BOARD) # USE Pi BOARD pins, not the BCM ver
# GPIO.setup(7, GPIO.IN, pull_up_down=GPIO.PUD_UP) # 7 is next to gnd on pin 9, so set pull up

# defs
camerafail=False;
DIR='/home/pi/mine/'
imagename='cam01.jpg'
remotename='mysite.com' # assuming this is reachable by ssh and www



try :
    with picamera.PiCamera() as camera:
        #camera.resolution = (2592, 1944)
        # The following is equivalent
        #camera.resolution = camera.MAX_IMAGE_RESOLUTION
        # run half res to test out connectivity etc and save money
        #camera.led = False
        camera.resolution = camera.MAX_IMAGE_RESOLUTION
        #camera.resolution = (1296, 972) # do half real to eliminate Bayer softness and save TX bandwidth
        camera.start_preview()
        time.sleep(2)
        camera.capture(DIR+imagename, resize=(800,600), format='jpeg', quality=15)
except picamera.PiCameraError,e :
    print e
    camerafail=True
finally :
        camera.close()
time.sleep(10) # hopefully nw is up by now   

if not(camerafail) :


    timedout=False
    connected=False
    counter=0

    while (not timedout) and not connected :
        try :
            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            s.connect((remotename,80))
            print(s.getsockname()[0])
            connected=True
        except socket.error,e :
            
            counter += 1
            print counter
        finally: 
            s.close()
        time.sleep(5)
        if counter >= 5:
            timedout=True
            print 'Failed to connect to ',remotename,' ',datetime.datetime.now().strftime("%y/%m/%d %H:%M")
    
    # Ideally, this gets called by cron once every quarter of an hour. 

     
    #upload
    if not timedout: 
        print 'ftp image starting ',datetime.datetime.now().strftime("%y/%m/%d %H:%M")
        try :
            ssh = paramiko.SSHClient()
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            ssh.connect(remotename, port=2222, username='username', password='password')
            sftp = ssh.open_sftp();
            sftp.put(DIR+imagename, '/my/remote/path/'+imagename)
            sftp.close()
            print "closed SFTP"
        except paramiko.AuthenticationException,e :
            print e
        except socket.error,e :
            print e

The cron job

This is then called by a cron job on the Raspberry Pi. You must to this with root privileges because you are accessing the hardware, so use

sudo crontab -e

and mine looks like

*/15 4-22 * * * /home/pi/takepic.py > /home/pi/log.txt

which means every 15 minutes between 4am and 10pm run takepic.py and save the error messages etc to log.txt. Before running this as a cron job you want to make sure that if you manually run

sudo /home/pi/takepic.py

you get a picture uploaded to where you want it 🙂

Flock of young Jackdaws begging food, Whitchurch, Hampshire

Flock of Jackdaws with young in trees by playing fields and trees by the River Test in Whitchurch. The calls of the young from all around come out in this binaural recording.