Arduino based camera control

I’ve been tinkering over the last couple of weeks with a prototype programmable camera controller based around the Arduino system. If you haven’t come across it before, Arduino is a flexible, open source electronics prototyping platform which is well documented and relatively easy to get started with, making it a solid base for this kind of project.

testing an early prototype at dusk

Testing an early prototype at dusk

One aim for me in this little project is to create a controller which I can program to help with the job of shooting timelapse sequences. There are ready made timelapse tools available such as the excellent ‘little bramper‘ but I’m at the point where I’m finding it useful to be able to add some custom hardware and software to my timelapse toolkit. An equally strong aim is simply to teach myself about both Arduino programming and what’s involved in using it to control my camera, partly just out of interest and partly so I have the knowledge and flexibility to be able create hardware and software of my own design.

If you’re interested in doing a similar project, I’ve documented some basics here to help you get started. This isn’t intended to be a complete solution to everything you could possibly want to do but rather a primer on taking those first steps along with with some pointers and ideas on where to go next.

Before I go any further I guess I need to make it clear that in doing this I was prepared to accept the small risk of damaging my camera in some way in order to learn and create. The potential rewards were worth it for me but if you’re going to follow me down this route, you need to accept that risk for yourself too.

Firing the shutter

The core of this project is a simple circuit which connects to the camera’s remote shutter release. At a basic level, this just involves connecting two of the pins used for the camera remote together, to simulate pressing the button on the remote. I’m working with the canon N3 type of connector but if you search online you can find plenty of info for other connector types.

For Canon N3, the connections when looking at the camera are:

n3 connections

Connecting the focus pin to the common ground pin is equivalent to a half press of the shutter button whereas connecting the shutter pin to ground is equivalent to a full press. For now, we’ll ignore the focus connection and just deal with the shutter.

The Arduino board is used to control my circuit in order to fire the camera in bulb mode. I’m using an opto isolator in my circuit too, to control the shutter. This is essentially an electronic switch which uses light to isolate two circuits, while allowing the circuit on one side of the opto isolator to control the other. The camera side of the circuit is kept electrically separate from the Arduino side, with light being the the only link between the two. The basic circuit looks like this:

camera control circuit

I’m using a 4N35 opto isolator because I had a couple already available and it’s a decent choice for a general purpose job like this. There are many others available too which work similarly. I’ve found it convenient to add an indicator LED to the circuit to show when the controller is activating the shutter. This is optional but can be useful in practice.

The values of resistors R1 and R2 should be tailored to provider the correct current to your particular opto isolator and LED. There’s a handy online calculator which helps with this. The arduino pin will be 5V when the shutter is triggered, so use 5V for the source voltage and take the other values from your LEDs spec sheet. In my case, R1 = 330Ω. I’ve set R2 higher than the calculated value because I was planning to use the circuit mostly in low light conditions and didn’t need the indicator to be super bright. So for me, R2 = 820Ω.

Once you have this basic circuit, you can connect it to the Arduino board. I’m using the Arduino Uno and this sketch assumes you’ve connected the circuit to pin 7 to control the shutter.

The programming bit

An extremely basic ‘hello world’ program (Arduino calls them ‘sketches’) which will test the circuit by firing the shutter for approximately 1 second every 5 seconds is:

/*
  A basic sketch to illustrate camera control by firing a 1 second bulb exposure
  every 5 seconds. http://blog.newfocusphoto.com/
*/

#define SHUTTER_PIN 7

void setup() {
  // set the shutter pin to output
  pinMode(SHUTTER_PIN, OUTPUT);
}

void loop() {
  digitalWrite(SHUTTER_PIN, HIGH);   // open the shutter
  delay(1000);                       // wait for a second
  digitalWrite(SHUTTER_PIN, LOW);    // close the shutter
  delay(4000);                       // wait for four seconds
}

If you need them, there are some general getting started instructions for Arduino which show how to set up the development environment and load sketches to the Arduino board.

Monitoring when the shutter opens

When testing the above program, you might notice that there’s a slight delay between sending the signal to fire the shutter and the shutter actually opening, so one of the first enhancements you can make is to monitor when the shutter actually opens by using the camera’s external flash connection. This allows increased accuracy in the exposure time.

The camera fires the flash by closing two contacts on the flash connection (essentially closing a switch) and if we have the camera set to first curtain sync (i.e. to fire the flash as soon as the shutter is open) we can use this to fine tune our exposure. To start with, some additions are made to the circuit as follows:

flash connection circuit

The purpose of resistor R3 is to hold the arduino input low and stop it wandering when the flash signal isn’t present. This may be unnecessary when the optional LED indicator is in place but I’ve left it in for now to give me the option of disconnecting the LED in my final version. The value of R3 is 10K. R4 should be tailored to the LED as with R2 above. I’ve chosen 820Ω again.

I’ve connected this circuit to my camera’s flash PC sync terminal. If you don’t have a PC sync terminal on your camera, one option is to use a hotshoe adapter which has a PC sync or 3.5mm jack output to make the connection. You need to be careful that you don’t exceed your camera’s maximum flash trigger voltage (I’m not aware of any cameras that wouldn’t be OK with the 5V we’re using here but check your documentation).

Once connected to the camera, this circuit can then be used in the program to wait for the flash signal before starting the timing of the bulb exposure. You can then use this extra circuitry in your program to fine tune the bulb exposure by monitoring when the flash signal occurs in your sketch.

Enhancing the sketch

The following code shows one way you can use this flash signal. I’ve also replaced the blocking ‘delay’ commands with some timing code which allows the loop to continue running. This has the advantage that when you get more advanced, you can do other things while waiting, such as responding to button presses.

At any one time the sketch is in one of three states:

  • Waiting for the next (or first) interval to start (INTERVAL_WAIT)
  • Waiting for the flash signal from the camera (FLASH_WAIT)
  • Shutter open, during the bulb exposure (BULB)

Time based conditions or the flash signal from the camera move the sketch from state to state.

/*
  Example of shutter control with flash monitoring. http://blog.newfocusphoto.com/
*/

#define SHUTTER_PIN 7
#define FLASH_PIN   8

String state;         // What's currently happening
long intervalStart;   // When the current interval started
long bulbStart;       // When the current bulb exposure started
long current;         // The current time (in milliseconds since last reset)
long interval;        // The interval from exposure to exposure in milliseconds
long bulb;            // The bulb time in milliseconds

void setup() {

  pinMode(SHUTTER_PIN, OUTPUT);                // set the shutter pin to output

  interval = 5000;                             // Time from exposure to exposure = 5 seconds
  bulb = 1000;                                 // Bulb exposure time = 1 seconds
  state = "INTERVAL_WAIT";                     // We're waiting for the next interval to start
  intervalStart = millis() - interval;         // Pretend we've just finished a previous interval
                                               // (helps avoid any special logic for the first
                                               // interval in the rest of the sketch)
}

void loop() {

  //Get the current time (milliseconds since last reset)  
  current = millis();

    //State: Waiting for the next interval
    if (state == "INTERVAL_WAIT") {

      //If end of interval is reached, start the next bulb exposure and note the time
      if (current - intervalStart >= interval) {
        intervalStart = current;
        digitalWrite(SHUTTER_PIN, HIGH);   //Open the shutter
        state = "FLASH_WAIT";
      }
    }

    //State: Waiting for the flash signal from the camera
    else if (state == "FLASH_WAIT") {

      //When the flash signal is received, start timing the bulb exposure
      //(the shutter signal has already been sent)
      if (digitalRead(FLASH_PIN) == HIGH) {
        bulbStart = millis();
        state = "BULB";
      }
    } 

    //State: Shutter currently open and timing the bulb exposure
    else if (state == "BULB") {

      //When it's time to end the bulb exposure, close the shutter and wait for the next interval
      if (current - bulbStart >= bulb) {
        digitalWrite(SHUTTER_PIN, LOW);   //Close the shutter
        state = "INTERVAL_WAIT";
      }
    }
}

Here are the shutter control and flash circuits, complete with LED indicators, prototyped and connected to the Arduino Uno. I’ve used 3.5mm jack plugs and sockets to connect the cables running to the camera.

prototyping the camera control circuit

What next?

This is deliberately pitched as a simple starting point in both the circuit and the software but it illustrates the basics of firing the camera shutter in a programmable way. There are many places you can go from here, such as:

  • Use a light or sound sensor to build a lightning trigger or sonic trigger.
  • Add an LCD screen to give some feedback on what’s happening. For a getting started guide, see this Arduino LCD tutorial.
  • Add some buttons and use them to allow you to set parameters for your program, such as the bulb time.

Personally, so far I’ve added a 16×2 LCD screen and four push buttons which allow me to start/stop the program and adjust parameters such as the bulb exposure time. One of the first real world tasks I’ve put this to is taking some of the manual work out of post sunset dusk through to full darkness timelapse sequences, with a little sketch which gradually ramps up the bulb time to compensate for the falling light levels. 

Initially, the sketch ramps up the bulb time by about 0.15 stops every minute, then gradually reduces the rate of ramping to reach a constant bulb time of 25s about 90 minutes after sunset. This works quite effectively, as shown in the following timelapse video which compresses 2.5 hours of dusk through to night down to about 12 seconds.

I hope this gives a basis for your own Arduino camera control projects. If you get to the point where you’re looking for more advanced material to draw on, one resource which is worth a look is OpenMoco, which is a collection of open source hardware and software for camera motion control and timelapse. If you do create your own projects, please feel free to share links to them in the comments.

Category: projects

4 Responses to “Arduino based camera control”

  1. Riccardo Meconi says:

    how about a mechanical “finger” for a camera without electronic shutter? Radio controlled to shoot birds at 100 feet away, at a bird feeder? Push a botton on the transmitter and Bingo! … The finger: a common servo.Have you seen such a project? Can you orient my search? On the outskirts of Madrid, Spain there is too little vegetation to hide…but a tripod plus a bird feeder will do…

  2. Allan says:

    I like this, it is informative and easy to read. Thank you John, the information is invaluable to all interested in this topic.

  3. Anthony says:

    Hi, would it be possible to buy one already made and programmed so that could be used by passing a command to the board via USB. I’m trying to make a home photo booth and want a camera flash to flash once when given a command. Many thanks and kind regards. Anthony

  4. Vatché says:

    Hi John

    I can not thank you enough, you have solved my biggest problem
    it was very challenging for me to get my Canon 6D triggered with no current

    I would say this is the safest way to do it……..

    Big thank you again

Leave a Reply to Anthony