Monday 8 April 2013

Raspberry Pi Controlled Canon DSLR

As I work from home, overlooking the garden, I decided to build myself a bird table to have something interesting to look at whilst working out whatever network problem has fallen into my lap that day.

I am by no means a carpenter but I think it turned out OK, and the birds seem to like it.
Click for Larger Version

Next it was time to take some pictures of the visitors I had, this turned out to be very difficult with only a 250mm zoom lens. As soon as you moved the little blighters flew off! plus I had work to do, couldn't do both at the same time.

Having made a DIY shutter release for my Canon1000D camera the obvious next step was to build a remote release and the device most suited to this task was of course my RaspberryPi.....

This post will not cover setting up and updating your RPi, there are plenty of those already, suffice to say, keep your system updated.
There is also a myriad of websites detailing the physical differences between camera shutter release connections, please check your own camera/connectors. Although each one will have at least 3 pins to connect to, these are usually pre-focus, shutter & ground. You'll need to know which is which.

So, let's get to it.....

Step1 : The Circuit
Click for Larger Version

The circuit comprises of two transistors which replace the physical buttons used on a standard handheld shutter release, a transistor is a switch after all - just one controlled by electricity instead.
The transistors I used were "2N3440", I decided quite arbitrarily on these (Lots of Googling shows these are quite 'beefy' so not much chance of any power from the camera getting to my RPi) - I'm not an electronics person either, although I do have a soldering iron !


The basic logic is that each transistor has 3 'legs' Base, Collector & Emitter, they usually have a flat edge or a bumb to show it's orientation - again, google it.
We apply current to the 'Base' from the RPi GPIO pin (via software which we'll get to later), which throws the transistor 'switch', the 'Emitter' is ground and the 'Collector' is connected to the respective pin in the 2.5mm jack.
You can see all of the 'grounds' are connected together.
The pictures below show the finished board, and with it connected to the RPi. The 3 grey connector wires, with respect to the diagram above, from top to bottom, GPIO Pin#6(Green), #16(Red) & #18(Yellow)
Click for Larger VersionClick for Larger Version



















That covers the hardware side of things, next is the software..

The software side of this project is surprisingly simple.
I used a Youtube video to understand how the GPIO is used and what software you need to install in order to write your own routines.
I'm not going to re-invent the wheel here so I suggest you watch it too : GPIO For Beginners

OK, so now you have the software installed and understand a bit more about GPIO.
To fire the camera shutter all we need to do is set the correct pin to 'high' for a specified amount of time and then bring it back down to 'low'
Below is the short script that I used, actually fires the camera for 4 seconds - you can of course change this to whatever you want. I have setup pin 23 as well (shutter half press), although I'm not using it in this script at the moment.
The code (shutter.py):

import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setup(23, GPIO.OUT)
GPIO.setup(24, GPIO.OUT)
GPIO.output(24, True)
time.sleep(04) 
GPIO.output(24, False)
print "Done..."

Make it executable :

sudo chmod +X shutter.py

To actually run the code :

sudo python shutter.py

So you can see that by setting the pin number to 'True' we are in fact delivering current from the RPi GPIO pin to the 'Base' of the transistor which then fires the camera, then switch it off by setting the pin to 'False'.

This short video shows the whole setup working, this was my first YouTube video and the quality isn't great but it gives you the idea :  RPi GPIO Controlled Canon DSLR

Next step is make the whole setup battery powered!!

Again, I'm not going to re-invent the wheel here, this site is where I got all the information needed :
 RPi Running From Batteries

The only changes I made were getting a 10xAA Battery box and connecting a salvaged micro USB instead of using the GPIO header to connect the power. So far I have had my setup running for about 5 hours on 10xAAs. In the end you then get :

Click for Larger Version
The webcam is used in the next part, detecting motion then activating the camera shutter!

We now have an isolated platform (associated with my wireless network) which can be placed in the field.
Set up the tripod, camera etc approx 8-10 feet from the bird table, connect the 2.5mm jack to the remote shutter release port of the camera, SSH to RPi from the comfort of the conservatory and wait.....sometimes for a while.....until something lands on the table. When it is roughly in the area you have setup the camera for then run the script that fires the shutter, and repeat until your satisfied you have enough material to work through. When your finished you can get some good pictures.

Selection of pictures taken with this setup can be found here :  Recent Blackbird Pictures

Next we want to fire the camera only when motion has been detected, so we don't have to sit there waiting, ie: automate the process.

Software we need for motion detection is called 'Motion', so first of all we need to install it, which is as simple as :

sudo apt-get install motion

Motion has its' own configuration file, 'motion.conf', we need to edit that to make a few changes, so....

sudo nano /etc/motion/motion.conf

Motion.conf is a long file, lines starting with a "#" are comment lines and are ignored. Listed next are the parameters I changed :

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

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

# Maximum number of frames to be captured per second.
# Valid range: 2-100. Default: 100 (almost no limit).
framerate 50

# Image File Output
output_normal off

# Live Webcam Server
webcam_port 8081

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

# Command to be executed when an event starts. (default: none)
# An event starts at first motion detected after a period of no motion defined
on_event_start sudo python shutter.py

So when we start 'motion' you can use your favorite browser to go to your RPi's IP address and port 8081 eg: http://192.168.1.50:8081 to see what the webcam can see. Once motion is detected then the script shutter.py is called and fires the camera - that's it !!

The short video below shows the setup working, this was before the battery pack was completed:
 RPi Controlled Canon DSLR Motion Detect


This does work 'in the field' but is a bit restrictive by the length of USB cable from the webcam to the RPi. To overcome this we need the webcam independent of our RPi running motion.
We'll use another program called 'mpeg-streamer', details and instructions of which are found here :
 RPi-Webcam_Streaming


There is information regarding other programs in there but we are interested only in mpeg-streamer for this.

All we do then is edit motion.conf again and add the line

netcam_url http://192.168.1.64:8080/?action=stream

In the NetCam section of the file, amending the IP address according to whatever your second RPi's address is.
I have had this working on the bench but no video available.


So that's it, you should now be able to get 'up close & personal' with whatever you want to get pictures of, without having massive lens or sitting around getting bored, hope it's useful.

Thanks go to people who I have linked to, it's thanks to their efforts that this work has been possible.
I'd also like to add my personal gratitude to Adam Kovacs for supporting me in this piece of work - Thanks Adam - Top Man !!

29 comments:

  1. nice project, thank you, I will try this myself.
    btw, you can upgrade your camera's firmware from current 1.0.3 to 1.0.7

    ReplyDelete
    Replies
    1. Thanks 'insomniak', I will look into firmware upgrade you mention.

      Delete
    2. Amazing shots Adrian.
      Of course you can't get the flexibility you got with the RPI solution, but have you seen the MagicLantern (http://www.magiclantern.fm/) firmware hack for Canon Cameras? There are many pretty cool functions, even for controlling the camera via USB.

      thanks for sharing.
      mario h.c.t.

      Delete
    3. Thanks Mario, I'll have a look at Magic Lantern, but I must say my solution gives me what I need - at the moment. Thanks again for the link, it's appreciated.

      Delete
  2. Excelent.. can't wait to get a moment to try this.

    Thanks for sharing! People like you make the world a better place.

    ReplyDelete
    Replies
    1. Thank You Sir, very kind indeed...I wish you luck and if you need anything please ask.

      Delete
  3. I have the bits to do this, but not quite got around to it yet:) I have built the hardware to trigger the shutter on my Canon. Now I just need to get the webcam setup. Did you put the webcam on the bird table, or on a tripod nearby?

    Incidentally motion does work with ip cameras, but you need to do a bit of work to find the url of the mjpeg stream. I have got a Panasonic, which is part of my security system and use motion with it.

    ReplyDelete
  4. Hello Ian, the webcam was setup on a separate tripod with USB extension cables. Yes, Motion does work with IP cameras and I have had that working 'on the bench' with Pi #2, I need another wifi adaptor to get it off ethernet connection, so it can be placed anywhere.

    ReplyDelete
  5. If you wouldn't want to do it with GPIO, you should be able to control your camera over USB with piggyphoto (uses libgphoto2) as well. Depending on the camera you might be able to do more than just shoot pictures.

    https://github.com/alexdu/piggyphoto
    http://www.gphoto.org/proj/libgphoto2/

    I made a simple python program to make a time-lapse with my Canon EOS 650D.
    Video: http://www.youtube.com/watch?v=Am1P_fADJ90
    Source: http://pastebin.com/Xxiu3Rn7

    ReplyDelete
  6. Hello Ornotermes, i did try Gphoto2 but had difficulties in the USB connection, including playing with the USB reset scripts that are available. In the end I went for a hardware solution and some good old fashion photography skills to make up the difference.

    I do appreciate your contribution, links and your advice though, many thanks.

    Adrian....

    ReplyDelete
  7. There is a error in the shematic of the circuit : a mofset is drawn instead of a transistor. Have a look to the datasheet of the 2N3440 here : http://www.datasheetcatalog.org/datasheet/stmicroelectronics/4080.pdf

    Regards

    ReplyDelete
  8. Thank you Guillaume, I think the basic objective was met in the diagram, but your correction is understood and will be observed in any future work.

    Regards, Adrian...

    ReplyDelete
  9. You should really place a shebang line at the start of your python script:

    #!/usr/bin/python

    Then you don't need to explicitly run the script with python, simply running the script itself will automagically invoke python. Also not having a shebang can sometimes cause weird errors with your scripts.

    ReplyDelete
  10. Hello Ian, many thanks indeed, very useful information. I will also add "automagically" to my lexicon - super!

    Adrian..

    ReplyDelete
  11. Hi Great project.
    I have set this up just with one Rpi and a web cam attached and everything is working fine, except after the motion software triggers the camera, the picture is taken, but the shutter.py program is still showing done but does not exit to the motion software. I'm new to python, so do need to something to the shutter.py, or is their something in the motion.conf what needs setting up after the shutter.py has been executed. Also if I stop the motion software and run it again and motion is detected the shutter.py runs, but complains the GPIO channels are still in use and nothing happens, just gets stuck at the print "done", with no picture taken. I have to reboot to clear the channels. Any idea how to solve.

    Thanks Garry

    ReplyDelete
    Replies
    1. Hi Gary, once shutter.py is 'Done' there is nothing else to do, the script finishes. I suspect that you are expecting motion to fire the camera again immediately if motion is detected, if so then you need to change a variable in motion.conf. Look for "Gap", this is a numerical value expressed in seconds, and effectively waits 'x' number of seconds after an event before it starts to look for more motion events, default is 60 seconds.
      Config options here : http://www.lavrsen.dk/foswiki/bin/view/Motion/ConfigFileOptions

      Delete
    2. Thanks for your reply, yes you are correct in me expecting the camera to fire again. I would like to take multiple shots, then have the motion to wait for the next occurrence of motion. One idea is to get motion to restart after it has taken shots of the subject. I will take a look at the Gap in the conf file.

      Thanks again.

      Garry

      Thanks

      Delete
    3. Garry, it will fire again, after the 'GAP' timeout. This is where a bit of photography comes in as well. I set mine to continuous shooting and shutter.py set to fire for 3-4 seconds, so you get multiple shots. Add that time and a time for the camera to store the pictures and be ready for the next lot, so you then create a 'GAP' time that suits. To reiterate once shutter.py is finished there is no procedure necessary to return control to 'Motion' it's automatic, there is no restarting.

      Delete
  12. Hi, Adrian.
    One small thing, (as an electronics engineer) you are missing current-limiting resistors between the base of the transistors, and the associated GPIO pin. This means the Pi is under serious danger of overcurrent - when fired, the pin's effectively shorted to ground, or nearly so. Stick a resistor between each GPIO pin and the associated base of the transistor, and you'll be fine. Anything from about 4.7K to 22K should be fine - whatever you can find. (The batteries might last a fraction longer, too!)

    ReplyDelete
    Replies
    1. Hi Andy,

      Many thanks for dropping by and taking the time to comment. I will in future add the resistors as you suggest. My reason for not doing in the first place was I don't know how to work out what a reasonable Ohm to use. My reading suggested I would be safe enough in not using any, but I accept that they probably should be there for belt and braces.

      Regards.

      Delete
  13. I enjoy since websites that understand the value of providing a prime supply for free. I truly loved analysis
    your post.
    http://buyadslrcamera.org/

    ReplyDelete
    Replies
    1. Very kind of you to say so Ernie, many thanks.

      Delete
  14. Raspberry Pi Controlled Canon DSLR. As I work from home, overlooking the garden, I decided to build myself a bird table to have something ... ccanoncameras.blogspot.com

    ReplyDelete
  15. Hi A.J,

    That's a cool DIY automation using Raspberry Pi, I'm currently collecting awesome inventions, creations, projects using this mini computer and will post it under one of my blog posts Raspberry Pi Philippines so that my viewers will have a grasp how powerful Raspberry Pi is.

    Vins

    ReplyDelete
    Replies
    1. Thanks Vins, nice to hear that RPi has made it to the Philippines, good luck with your projects.

      Delete
  16. Yes bro there are few distributors of Raspberry Pi's accessories, add-ons and boards here in the Philippines and they are really affordable.

    ReplyDelete
  17. Hi. Great tutorial thanks for sharing!! I am using it to mount my DSLR to a RC Car for wildlife photography. SO this will be great to remotely capture images! I have followed all, but when i send the command nothing happens. Would it work if i connected LED's to the camera end to see if they light up when i send the commend to test?

    ReplyDelete
    Replies
    1. Hi Louis, thanks for your kind words. It's difficult to see why your setup would not be working, I would suggest double checking everything first. An LED may be useful, you would need to check how to wire that up. Wish you good luck.

      Delete
    2. Thanks for your reply. After doing some research (which admittedly i should have done first instead of being in such a hurry to try this fantastic project) i found that the alternative transistor i am using has the Base & Collector swapped around so it goes ECB instead of EBC. Will correct this and then it will more that likely work. Thanks again.

      Delete