I love that turning-point moment in a project where everything suddenly clicks into place. That goes double when several hours of my time have seemed all for naught.

After a successful day of photography yesterday, I decided to embark on a small weekend project: creating an Android-based remote shutter controller for my DSLR. Nikon sells dedicated units for anywhere between $20 and $260, but I’d seen microcontroller-based homebrew designs in the past and wanted to try my hand.

For those unfamiliar with photography, a remote shutter release may not immediately seem useful outside of taking group photos – and that’s why built-in timers exist. However, there are several situations where a timer falls short of what’s required for a quality result. When taking longer-exposure pictures, it’s absolutely critical that the camera be as still as possible to prevent motion blurring. Even with a tripod, you’ll often find that the minute camera movement introduced by pressing the shutter button is more than enough to spoil a shot (I found this out the hard way while capturing fireworks at Lake Tahoe in 2009. Some of the shots were great, but a good deal had just enough motion blur to distract the eye).

HDR (High Dynamic Range) photographs have become massively popular with the advent of sophisticated post-processing tools (Photoshop, most notably). One main method of shooting HDR photographs is to shoot three (or more) pictures of the same subject over a range of exposures. This allows the camera to capture information about dark and light areas individually, rather than prioritizing for one and sacrificing data for the other. Those photographs are stitched together in software later to form an image with exquisite detail. When shooting the multiple exposures, it’s important that the camera remain motionless between shots. However, photographers will notice that changing exposure settings and pressing the shutter release button will move the camera slightly, even with a sturdy tripod.

In my short time as an amateur photographer, I’ve run into situations where having a remote shutter would have helped tremendously. With an open weekend and a brand new Ikea desk, I had a perfect storm of DIY brewing.

Concept

After queueing up an utterly ridiculous number of songs on Grooveshark and brewing some tea, I started researching some other DIY remote projects. I was delighted to see that a handful of other folks had created remotes for their DSLR cameras; there is also a wealth of resources for building an iPhone- or Android-based universal remote control. As it turns out, Phillips developed a communication protocol for infrared (IR) communications in the 80s called RC-5 that has become a de-facto industry standard. Like AM radio, it “modulates” the control signal to a much higher carrier frequency (because higher frequencies can travel further through air without attenuating) and is “de-modulated” at the receiver.

Nikon IR remotes use this same method of IR modulation at a carrier frequency of 38kHz. Several hobbyists reverse-engineered the Nikon ML-L3 remote and recorded the control signal generated to trigger the shutter. Several sources I found disagreed on the exact timings, but this is the version I used (credit goes to SB-Projects):

The black bars in this diagram represent the times where the IR LED must be “on”. Since we’re modulating this signal at 38kHz, the LED is actually blinking 38 thousand times per second when “on.” No big deal, right? I mean semiconductors can switch billions of times per second these days.

Ordinarily, that would be spot-on, but I wanted to create an Android-based application for my phone. My HTC Incredible (and the overwhelming majority of smartphones) are very limited when interfacing to external hardware. Besides the USB port, I really only have the audio/headphone jack to work with. That would be perfect, except for one small detail.

Human hearing is “limited” to a range of about 20Hz to 20kHz (which is really a huge range), which means audio hardware rarely needs to function above a 20kHz ceiling (let’s call it 22kHz just for fun). Due to some complicated properties of signal processing (the Nyquist-Shannon Theorem for the bold), in order to prevent distortion of a 22kHz signal, a recorder must “sample” the signal at 2*22kHz, or 44kHz. No doubt, audiophiles reading this know that 44.1kHz is a common audio recording sample rate.

So what? 44.1kHz is above your modulation frequency of 38kHz, isn’t it?

There’s one other part of the equation we haven’t looked at yet: filtering. There’s a condition on our Theorem that your original signal audio signal can’t have any frequencies above 22kHz (for a 44kHz sampling rate). If it does, these will become distorted. To guarantee this condition without any extra software, most sound cards will filter any input/output signals with a cutoff frequency of about 22kHz (so a frequency of 10kHz will pass, but a frequency of 30 kHz will not). So our 38kHz modulated signal is hosed.

Luckily, in the early 2000s, a man named Paul Griffin (of Griffin Technologies) developed a method of using a stereo audio signal to generate a 38kHz modulated IR signal! Here’s the patent for the interested. Here’s a very simplified explanation of how it works: each stereo channel switches an IR LED off and on at a frequency of about 19kHz (which is below a typical sound card filter cutoff frequency). When one channel is switching off, the second channel will be switching back on. If this is timed just right, the switching frequency will effectively double to ~38kHz.

Hardware

Since an LED is still a diode, it will only turn on once a positive voltage has appeared across its terminals. In real LEDs, there is a turn-on voltage that must be exceeded before the light will be visibly bright (of course, with IR LEDs, you won’t be able to see the light). Thus, we can start to create a circuit with two LEDs that will work with a standard audio jack. The original circuit schematic was included in Griffin’s patent (you read it, right?), but Former Bender at the Hackint0sh forums created a really nice diagram (and a great post) about adding IR output to iPhones. Here is his version (part of the iCouchPotatoe project) of the transmitter circuit with the 1/8″ audio jack included:

Boom. A few dollars of hardware at RadioShack gets you a fully-functional audio jack-based IR transmitter, although you won’t win any aesthetics contests with it.

Software

I’ve been dabbling in Java/Android off-and-on for a few months now (more off than on, truthfully), so I know just enough about creating apps to be dangerous. For an absolutely basic remote app, all I really need is a button that, when pressed, will play an audio file that contains the shutter release control sequence.

The Android platform includes the MediaPlayer class that will open a file and play it without requiring any sort of user interface. You can start() , stop() , or pause() the code, but all this application requires is a start command.

The [extremely ugly] user interface is a button that activates the audio file. In order to play the media on a click, you have to register a listener that will execute a callback function when the click event happens. Android uses the OnClickListener class. Simple. Feel free to browse the source here. Here’s a screenshot of the UI:

Gorgeous!

Control Waveforms

Alright, the hardware is complete (though untested) and I can successfully play audio at the click of a button. Now to generate the modulated waveform from earlier in the post. One of the methods for obtaining the audio files to control IR devices is to create a circuit that will perform the opposite function as our transmitter: read the IR signals from a real remote and convert those into audio files with an analog-to-digital converter (ADC). The iCouchPotatoe project also includes schematics for a detector, but I wanted a quicker and (hopefully) easier approach.

Luckily, another individual wanted to programmatically generate these waveforms. There is an implementation of the RC-5 protocol by Phillips called Pronto that is used on their higher-end devices. It is a slightly more sophisticated version of IR signaling that transmits a preamble of meta-data that tells the device what kind of data it will be receiving (how many bytes, what modulation frequency, etc). Andrey Mikhalchuk at rtfms.com wrote a program in Python that accepts strings of Pronto Hex Codes and converts them into the appropriate .wav file (with the help of some scientific computing python packages). Andrey’s source code is available on his post about IR transmission.

After doing some reading about Pronto codes, I was able to translate the waveform shown above into a hex code string. Here it is, just for fun:

0000 006d 0008 0000 0000 00FF

004C 042D 0013 0039 0013 0086

0013 0966 004C 042D 0013 0039

0013 0086 0013 0966 0000 0000

So, what does it sound like? Follow this link and click “View Raw” in the gray box to download. Don’t listen to this with the volume too loud. 38kHz square waves aren’t really that pleasing.

Initial Test

With all of the pieces in place, I mounted my tripod in the living room of my apartment, plugged in my IR transmitter, and set the camera to remote mode. Moving in front of the camera, I opened my IR Emulator app, aimed the transmitter, pressed the button and…

…. nothing. Damn.

I double-checked my setup and tried it again several times. No luck.

Having tested continuity on the transmitter assembly after soldering, I suspected the waveform to be part of the problem. Luckily, my music side project had influenced me to install Ableton Live a few months ago, so I had a tool for inspecting the waveforms. Since I knew exactly what pattern was required, I had some diagnostic tools in my toolbelt.

Here is a view of the beginning of the first 2ms pulse, zoomed in:

The timebase is cropped from this image, but counting the pulses yielded about 20-25 pulses per millisecond, which is about what we expected (19kHz cycles times times per millisecond).

The two lines in this image are the two stereo audio channels. As I described (simplistically) above, those two channels will take turns switching so that the final signal is double the frequency of the individual channels. Can you see anything wrong with this picture?

For some reason, the two channels are switching at the same time, instead of switching in an alternating fashion. Thus, the IR LEDs are transmitting at half the designed modulation frequency. When my Nikon camera is decoding the transmission, the effective 19kHz signal is being ignored. Game Over.

Using my Live-fu, I developed a strategy to fix my phase error without re-generating another (potentially incorrect) waveform. By duplicating this waveform, adding it to another track, and manually shifting it ahead in time by half a cycle, I effectively created the alternating signals. To export the new pair of tracks as individual stereo channels, I panned the first track 100% right and the second track 100% left. Here’s the same part of the control waveform after my modification:

Notice that the channels have been offset by about half of a 19kHz cycle (~26 microseconds).

Deep breath.

Second Test

I updated the waveform in my application, built it, and redownloaded to my phone. Posing for the camera, I clicked the shutter button, and…

…nothing. Damn.

Oh wait! I forgot to put it into remote mode.

Ready, aim,…

Note the Chicago parking ticket on my coffee table. Whoops.

A successful mini-project. Thanks to all of the hackers who paved the way by reverse-engineering the Nikon communication protocol, generated the hardware schematics, documented the Android platform, and wrote software to generate waveforms. Without that foundation, this would have taken much longer.

Cheers,

Ryan

Sources:

Wikipedia’s RC-5 Entry

Barry Gordon’s Discussion of IR signaling and Pronto codes

Paul Griffin’s Patent Work

Andrey Mikhalchuk’s Work at RTFMS.comStan Bergman’s ML-L3 reverse-engineering

Android Developers Network