November 25, 2015 will

Using a Raspberry Pi + Camera to Monitor the Nocturnal Activities of Tropical Insects

Raspberry Pis are useful little computers. I own several, since I work with them in my day job, and I thought it was about time I put one to use.

I also happen to keep tropical insects. Specifically, beetles. These are not your garden variety beetles, unless you happen to live in a rain forest. The ones I have at the moment are elephant beetles which come from Central and South America. Here's a photo:

Male elephant beetle. Banana for scale.

These insects are mostly nocturnal. During the day they tend to burrow under their bedding material (moss), or hang out on a branch. But during the night, they can be quite active. I know this because in the morning they have re-arranged the branches in their tank.

For my Raspberry Pi project, I wanted to make use of the Raspberry Pi's camera to create a webcam. I also wanted to be able to create timelapse movies, because I didn't really want to watch 12 hours of video to see what they get up to at night. The result was Beetlecam, which may or not be live here. Beetlecam takes a picture every 30 seconds (by default), and can generate timelapse movies for a given time period. Here's 24 hours worth of footage condensed in to around 2 minutes:

In this post I'll describe how you can install and run a Beetlecam on your own Raspberry Pi.

Beetlecam Hardware

To run Beetlecam, you will need the following 3 things:

  • A Raspberry Pi (any model except Pizero which doesn't support the camera)
  • A Raspberry Pi Camera
  • A tank of large tropical Insects

If you don't happen to have the last one, don't worry, it will work with just about anything you would like to make a timelapse of.

The regular RPi camera will work fine, but I used an infra-red camera, which can film in complete darkness. Essential if your subjects are active at night. Here's a photo of my RPi and camera (note the infra-red LEDs either side of the camera itself):

A Raspberry Pi with Infra red camera attached

Mounting the RP is simple enough. I used velcro tabs which easily support its weight, and lets me move it to different positions. Here it us mounted:

Raspberry Pi and infra-red camera mounted

Beetlecam Software

There are two parts to Beetlecam; there is a web application which shows the latest frame, and a script which periodically takes a photo and uploads it. Both are in the Beetlecam repository.

There are a few additional libraries you will need to run Beetlecam. You can install these from a terminal in the Raspberry Pi Desktop, or you could use SSH/Dataplicity to connect to your Pi via another computer on your network. Whatever method you use, run the following commands:

sudo apt-get update
sudo apt-get install python-dev python-pip python-lxml libjpeg-dev
sudo pip install moya picamera

This may take a while. Plenty of time for you to grab coffee.

Once that has finished, you should be able to run the command moya -v.

The next step is to get the Beetlecam code from Github. Run the following commands to do that:

sudo apt-get install git
git clone https://github.com/moyaproject/beetlecam.git

This should create a folder, beetlecam in your current directory. Change to that directory, with cd beetlecam.

In that directory, you should find a Python file called beetlecam.py. This is the script which periodically takes photos and uploads them. All the Python code does is take a picture then make a POST request to the web application. A POST request is what your browser does when you fill in a form on the web. In the case of Beetlecam, it is posting to this form in the same way a browser would.

Run beetlecam.py with the following:

python beetlecam.py run -r 30

You will see some errors in the console, because we are not yet running the web application part of Beetlecam.

To run the web application, first create a new terminal window, or SSH instance. That way we can leave beetlecam.py running on the Pi. Change to the beetlecam directory then run the following:

cd site
moya init

This will initialize the web application and create a database. Next, run the web application with the following command:

moya runserver -t --host 0.0.0.0

You should now be able to point your browser at http://127.0.0.1:8000 and see the photos that beetlecam.py is taking. Or if you are using another machine on your network, you can use the hostname of your Raspberry Pi in the URL, by default that would be http://raspberrypi:8000.

In Part II?

If there is enough interest, I'll post about how to create the timelapse videos . I'll also explain what beetlecam.py does in more detail, and go over the web application.

Comments disabled
gravatar
MH

Very cool !

gravatar
Gunnar

That's cool, I'd be interested in more detailed Part II post ;)

gravatar
Johnathan Harris

Where did you get the light sources for the camera?

gravatar
Will McGugan

It came with the camera. I got it from Amazon. I think it may have been this one.

gravatar
Kevin Moore

Hi Will, Thanks for all your hard work :-) I've just today, tried installing this on a fresh 'lite' raspbian Jessie install. All working well thanks, the only problem I had was with the line:- 'pip install moya picamera' which I had to do as super user ie. sudo pip install moya picamera I also seem to be experiencing a memory leak of about 28MB every 5 minutes, do you have any ideas about that as my Pi will run out of memory fairly quickly. Regards, Kevin.

gravatar
Will McGugan

Hi Kevin. Good spot about needing sudo there.

I didn't notice any memory leak on my Rpi. It was fine after running for few weeks. You might find memory usage stabilizes after a while. Not sure how much you know about linux memory usage, but there is a lot of caching done by the OS that might appear to be a memory leak.

If it is a legitimate memory leak then you are right, it will fall over after a while. let me know if it is still running after 24 hours!

gravatar
Kevin Moore

Hi Will, Thanks for your reply, It's been running over night, it started to use the swap, got to about 12MB of swap used and now seems to have stabilised, interesting, I'll leave it longer. I've modified your scripts a bit to reduce the picture size and quality, (45kB per pic) and up'ed the refresh rate to about every 3 seconds, get the occasional miss, but seem to be happy. I'm assuming that the sql database is filling up, even though I'm going in occasionally and deleting older pictures, is there a way of tidying the database? just stop and re-start? Thanks for your help. Kevin.

gravatar
Will McGugan

There could be a memory/object leak somewhere. I'll see if I can reproduce that here. Are you running both beetlecam and the server on you Pi?

There isn't a way of clearing out deleted items from there database at the moment. You could try adding that to the Moya app if you need it. It will only store a few bytes per frame, so it will be a long time before it gets too big.

There are a couple of commands you might find useful. Run this from the site directory...

moya beetlecam#
gravatar
Kevin Moore

Hi Will, Thanks for the hint about the other moya commands :-) I've now been trying to write a script to automate the start up of the two processes and leave the terminal fee of debug, everything works fine, including the 'moya init' and 'moya db sync' but the final 'moya runserver -t --host 0.0.0.0' which aborts with

Traceback (most recent call last): File "/usr/local/bin/moya", line 11, in <module> sys.exit(main()) File "/usr/local/lib/python2.7/dist-packages/moya/command/app.py", line 386, in main return moya.run() File "/usr/local/lib/python2.7/dist-packages/moya/command/app.py", line 186, in run for v in sys.argv] TypeError: decode() argument 1 must be string, not None

which is repeated twice, I've tried all sorts of things, any ideas what I am doing wrong? This is the script I'm trying to use. #!/bin/bash -x cd /home/pi/beetlecam/ nohup python beetlecam.py run -r 5 & cd site moya init (nohup moya db sync; nohup moya runserver -t --host 0.0.0.0) &

Sorry to be a nuisance :-( Kevin.

gravatar
Will McGugan

Hi Kevin. That's an odd one. I can't reproduce it, but I did some googling, and it looks like sys.stdin.encoding can return None, which seems to be the root of the problem. I'm guessing it is something to do with how you run db sync, and runserver in a subshell.

Can you try adding this inside the subshell:

export PYTHONIOENCODING=utf-8;

If that works, I'll add a the fix to Moya.

gravatar
Kevin Moore

Will, you're a genius :-) That has got it working perfectly. Many thanks. If you'd like me to test any fixes you put in Moya let me know. Regards, Kevin.

gravatar
Will McGugan

Good to know, thanks. :-) I'll add that fix to the next release.