Saturday, February 2, 2013

Arduino Intervalometer (Hardware)



Summary:
I design and build an Arduino-powered intervalometer for my camera, but mostly I learn that circuit design is non-trivial.

Motivation:
I do a decent amount of photography, and have always enjoyed doing time-lapses. To trigger my camera at regular intervals, I've been using a cheap intervalometer that has a few simple functions. One issue I've always had with this particular one is that you can't specify both the interval between shots as well as the exposure time. One reason for needing this would be when doing nighttime time-lapses, where the exposure time might need to be greater than 30s (longest the camera can be set to do on its own).

So I decided to build my own intervalometer using an Arduino-compatible microcontroller to trigger the shutter release at arbitrary intervals and for arbitrary exposure times.

Build Details:
After doing a little research, I found that my camera can be triggered easily using a 2.5mm audio cable. The three wires in the audio cable are for ground, auto-focus, and shutter release. Shorting either of the last two to the ground wire will cause the camera to perform the desired function. I've never wanted to redo my focus after each shot of a time-lapse, so I didn't do anything with the auto-focus wire. This very basic circuit shows how I controlled the shutter release using the microcontroller:
Shutter gets shorted to ground when Logic goes high.

Now, I could have essentially stopped there. With a 555 timer and some potentiometers I could have had an intervalometer with fully adjustable intervals and exposure times, but that would just be too easy. And boring. I wanted some kind of visual output from the circuit as well as the ability to run more advanced interval routines. To handle user input, visual output, and triggering the camera, I decided to use an ATMega328P (the brain of an Arduino Uno) that I had lying around. It has plenty of IO pins, can use the Arduino bootloader (to make programming easy), and can even run on an internal 8MHz oscillator, eliminating the need to add an external oscillator to the circuit.

I found some neat 8-character, 8-segment displays at my local electronics shop for $1.50 a piece, so I grabbed a couple so I could use them in future projects if they turned out useful. They have 16 lines, 8 common cathode lines for each segment and 8 common anode lines for each character. I decided to source the segments directly from the ATMega and select which character to drain through a 3-8 line decoder and some transistors. In all, the display needed 12 IO lines from the microcontroller (8 source, 3 line selection, 1 enable/disable for the decoder).
This one was actually broken. Good thing I bought a couple.

I'm still very much a novice at designing circuits and putting them on boards, but I've been experimenting with a few different methods. Usually I just solder everything onto a protoboard and hope I can make all the necessary connections with solder bridges and jumper wires. This time I decided to try something that might make my life a little simpler, these pre-wired protoboards. Every pad is connected to each neighboring pad, and the connections can be severed with an exacto knife. The goal was to plan out which connections to keep, cut the other connections, then solder all the components in place and be done. So first, I planned the circuit and layout.
It's almost like I know what I'm doing. Time for the layout..

This is not going well. Time to use a computer.

This makes sense... Right?

Drew in the lines I didn't want to cut. Everything else must go!

This was extremely tedious.

Almost forgot the back. Instead of attempting to duplicate a reversed pattern, I just cut everything. One side should be enough.
Everything soldered on, minus the display. Camera cable is the bottom right.

After attaching the display lines to the top of the board, it was time to test everything. I loaded a simple sketch onto the ATMega that would enable the segments making up a '0' while looping through the characters fast enough to have them all appear on at the same time. I switched it all on and nothing happened. Well, nothing that I intended on happening happened. The ATMega did start to heat up a bit though.. Turns out there were a couple shorts in the board due to me not severing the preset connections properly. After spending some quality time with an ohmmeter to check connectivity, I fixed all of the unintentional shorts, and luckily none existed in hard to reach places. Finally, the display could light up.
Well that's not right.

This time the problem was with a burnt out display segment and a mistake in my board layout. The display anodes are connected to a group of transistors at the top of the board, but I forgot to connect all of the emitters to ground. Added an extra wire, replaced the display with one of the extras I bought, and finally the display is working.
Fancy!

At this point I stopped. There's no user input, but I have full control of the camera shutter and the 8-character display. I've just started working on the code to run everything, so at some point I'll make another post about the firmware and how I will deal with user input. For now, I've made a Github repository for the intervalometer code as I work on it.

Insights:
1) The pre-wired protoboards are a pain to use. I need to either make my own PCB, or get them printed elsewhere. If the circuit is complicated enough, it will be worth the money.
2) Programming the ATMega currently requires removing it from the board, placing it on a breadboard, and using another Arduino to upload the sketch. Next time I should add an ICSP header to the board itself to make programming easier.