DIY Nikon ML-L3 IR Remote Hack Part I

The Nikon ML-L3 Infra Red Remote Control is used to remotely control a Nikon DSLR Camera. It costs between US$20 for an original Nikon to US$8 for a cheap Chinese copy. This device only allows a single shutter release with each button press.

Wireless Remote Control ML-L3

The ML-L3 allows only one single shot to be triggered at a time. Its a great little remote but it could do a lot more interesting things  such as :-

1. Automatically timed multiple shots for time lapse photography
2. Adjustable exposure timings directly from the remote in bulb mode
3. Light sensitive automatic shutter control for those great pics of lightning blazing through the sky
4. Shutter control based on movement like used by researchers in camera traps for shy animals
5. who knows what other possible uses there might be?

The problem is that commercial devices that perform any of these tasks are prohibitvely expensive. As you can see from

70-300 Euros is not something that I would want to spend on technology that could easily be assembled with a little bit of analytic effort and electronic design. Here is the first part of a 3 part write up on how to build a Nikon IR Remote control that would be capable of all of the functions above at a cost of about 10-12 US$, a fraction of what one would pay for a commercial product.

Step 1. Record the IR signal emitted by the Nikon ML-L3 and analyse it.

To analyse the waveform I used a chinese copy of the ML-L3 hooked up to an external battery, and connected the output pin on the IR LED to an oscilloscope.

Hacking a Chinese copy of an ML-L3

Hacking a Chinese copy of an ML-L3

Here is what I found when I looked at the signal on my oscilloscope.

Here are the pair of Command Signals captured on teh Oscilloscope

Here are the pair of Command Signals captured on the Oscilloscope

It looks like a pair of identical signals were emitted every time I pressed the trigger on the remote. Each signal consists of four pulses, a single long pulse followed by a short gap and then three shorter pulses in quick succession. Using the time cursors on the oscilloscope, I measured the exact timing of each pulse and the time gap between them.

When I zoomed in to see more detail, I found a modulating signal that was superimposed on each pulse of the emitted signal.

Modulating Signal

Modulating Signal

This is what most other remote control devices such as TV/ DVD remotes also do to their emitted signals. Once again I used the oscilloscope’s timing cursors to identify the exact charateristics of the modulating signal.

This is what my analysis of the ML-L3 emitted signal revealed…..

Waveform description after analysis is complete

Waveform description after analysis is complete

Step 2.  Now we have to find a way to duplicate this signal. Luckily for us, the clever people who designed the Arduino have provided us with the ideal platform to replicate a modulated pulsing signal. Here is the Arduino Code:-

int outPin = 7;
 int pulseWidth=0;

void setup()




void SendPulse(int pulseWidth)
 //SendPulse generates the modulating signal and pulses the signal on the designated output pin.
 // Notice I used a delay of 11 and 5 microseconds instead of 15 and 9 microseconds
 // as my oscilloscope has indicated. I did this because 11 and 5 gave me exactly 15 and 9 microseconds
 // when i hooked up the Arduino UNO my oscilloscope. You may need to change these slightly to get the right
 // modulating signal.

//argument pulseWidth must be in microseconds

int reps = pulseWidth/23.6;

for(int i=0;i<=reps;i++)


void SendSequence()

// SendSequence generates a full command signal by repeatedly calling SendPulse().
 // The duration of each pulse and the time gaps between pulses is exactly the same as the
 // values obtained from the analysis by oscilloscope

for(int i=0;i<2;i++)
 //pulse for 2.0 millis
 //delay for 27.8 millis
 //using a combination of delay() and delayMicroseconds()
 //on pulse for 0.5 millis
 //delay for 1.5 millis
 //on pulse for 0.5 millis
 //delay for 3.5 millis
 //send pulse for 0.5 millis

void DoPhotoLoop(int reps, int timeInterval)
 // Do PhotoLoop() transmits a pair of command signals by calling SendSequence() and then delay()
 //timeInterval in millis
 for(int i=0;i<=reps;i++)


void loop(){

//Here we decide how the shutter is to be triggerred...

//shutter control from serial interface

while (Serial.available()==0);;

//shutter control for time lapse photography
 // We can now call DoPhotoLoop() as required to emit the command signals
 // For instance, to to time lapse photography of 25 shutter releases with a gap of 300 seconds
 // between each click, we would do DoPhotoLoop(25,300);



Step 3. Now lets look at the circuit diagram on the Arduino UNO.

Arduino UNO pin diragram

Arduino UNO pin diragram

The output pin is pin 7, and it is connected to the IR Led through a 220 ohm resistor. This resistor ensures that no more than 20mA or so of current flows through the LED. The -ve pin of the IR Led is connected to Arduino’s ground.

Step 4. Trials. As you can see from the video, the shutter release works perfectly when controlled by the computer keyboard. In the next part of this write up, we’ll look at other triggering mechanisms such as light/ motion detection.

Step 5. Obviously this is a prototype, and we need to make a more permanent construction by using an Arduino Mini Pro and hardwired components in a solid box. I will try that and post my results soon.

So here is the question….Why kneel before the forces of exploitation and pay 300 Euros for a device that we could build for under US$15?


13 thoughts on “DIY Nikon ML-L3 IR Remote Hack Part I

  1. Pingback: Light Sensitive Camera Shutter Release : Voltage Divider Application | Bayesian Adventures

  2. Pingback: Getting Started With the Arduino Pro Mini | Bayesian Adventures

  3. Pingback: DIY Nikon ML-L3 Remote Control Part 4: Completed Schematic | Bayesian Adventures

  4. Pingback: DIY Multifunctional Nikon ML-L3 Remote Part 5: Prototyping | Bayesian Adventures

  5. Thanks for the great post and code. This works a treat. I just wanted to add a comment about using it with the bulb setting. The ML-L3 remote apparently releases the shutter on the first press and closes it on the second press. Using the code you’ve written, if you want to run a bulb exposure for one minute, say, you could use DoPhotoLoop(1,60). Not sure if you have changed it since then, but in your for loop in the DoPhotoLoop function (line 72), you use “i <= reps". Strictly I think this should be "i < reps", and then you run DoPhotoLoop(1,0) twice with a suitable delay in between. Either way works but I'm going to make a remote on some protoboard and for me the latter way is how I want to use it so that it will function correctly for bulb settings. Thanks again, you saved me a lot of time and a lot of effort 🙂

  6. you saved my life with the 11 and 9 microseconds delay! i wasn’t sleeping, was thinking about going to a shrink when i bumped into your web site (i dont have an oscilloscope at hand, it has to be said!) tks a lot!

  7. Hi, very nice demo. But unfortunately i’m not being able to produce the same outcomes.
    I used a 330 Ohm resistor with the IR led instead. I loaded the program on UNO but it doesn’t release the shutter. Could you please help me?

  8. hI,
    I’m getting trouble to get the system to work.
    I wired the circuit and used a 330 ohm resistor instead.
    Used the same program you wrote.
    Tested it and doesn’t work with my dslr.
    Could you please help me?

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s