0

$USD

$USD
PROJECTS ArduinoGravity

Arduino Project - Make an Arduino Intervalometer For Timelapse Photography

DFRobot Sep 21 2016 1859

SLR cameras are great for photography, and by adjusting shutter speed and aperture you can take some great looking photos. Some SLRs have input jacks built in to them for external triggers or intervalometers for time lapse photography. I have used my old Nikon D40, but being an entry level camera it doesn’t have this feature. It does have a USB jack that can be used as a trigger, but if I want to make a timelapse it will require my laptop to be tethered to it all day, as well as some proprietary Nikon software, so it’s not ideal. What the Nikon D40 does have is an IR receiver, designed to be used with a shutter remote. I can exploit this feature to make an intervalometer for time-lapse photography by using an Arduino and an IR transmitter. I hope you like this Arduino project. 


Here are the main steps to achieve what I set out to do:

1. Work out the IR protocol for the Nikon IR remote

2. Take this protocol and implement it in to a simple code so that the Arduino can emulate it using an IR transmitter LED

3. Write a program that will fire the shutter at an assigned interval (e.g. every minute)


Here is what I used on the Arduino Project:

The DFRduino UNO is the Arduino Microcontroller (Such as Arduino UNO) that I will upload code to. It will coordinate all the inputs and outputs.

The Gravity IO expansion shield will give me a convenient 3 pin gravity interface which I can connect my gravity modules to without having to make a mess with with breadboards and jumper wires.

The gravity IR transmitter module will fire off an IR signal that the camera can recognize, and already has resistors integrated right on the board so I can just plug and play!

I have used a gravity button to fire the shutter when pressed. Again, all the components and resistors to make it work properly are integrated right on to the module’s board, so I can just plug and play.


Working Out The Nikon IR Remote Protocol

IR devices such as remotes use invisible infra-red light and usually communicate by firing a specific set of pulses of light from an IR transmitter that the IR receiver on a device can recognise and decode.

It is possible to grab the code using an Arduino and IR receiver module. You can then read the code using the Arduino serial output. This is one method of finding out the protocol.
However, thanks to the internet I was able to find the specific protocol for Nikon cameras that someone else had already grabbed and shared, so this saved me some time.


The Nikon IR Protocol is as follows:

PWM ON

OFF

2.0 ms

27 ms

0.4 ms

1.5 ms

0.5 ms

3.5 ms

0.5 ms

62.2 ms

2.0 ms

27 ms

0.5 ms

1.5 ms

0.5 ms

3.5 ms

0.5 ms


The code fires an IR pulse in the pattern shown. It actually sends the same code twice if you look carefully. This is just to ensure the code is received and is quite common in IR devices.


The next step is to take this information and plug it in to some code so that we can emulate this protocol using an Arduino.


Emulating an IR Remote Using An Arduino

The IR LED is connected to digital pin 13
The button is connected to digital pin 2


Using the information above, I have implemented it in to some code that will emulate a Nikon IR Remote:

int IRledPin =  13;

int buttonPin = 2;


void setup() {

  pinMode(IRledPin, OUTPUT);

  pinMode(buttonPin, INPUT);

  Serial.begin(9600);

}


void loop() {

  int val = digitalRead(buttonPin);

  if (val == HIGH) {

    SendNikonCode();

    Serial.println("Sending IR signal");

  }

}


void pulseIR(long microsecs) {

  cli();

  while (microsecs > 0) {

    digitalWrite(IRledPin, HIGH);

    delayMicroseconds(10);

    digitalWrite(IRledPin, LOW);

    delayMicroseconds(10);

    microsecs -= 26;

  }

  sei();

}


void SendNikonCode() {

  pulseIR(2080);

  delay(27);

  pulseIR(440);

  delayMicroseconds(1500);

  pulseIR(460);

  delayMicroseconds(3440);

  pulseIR(480);


  delay(65);


  pulseIR(2000);

  delay(27);

  pulseIR(440);

  delayMicroseconds(1500);

  pulseIR(460);

  delayMicroseconds(3440);

  pulseIR(480);

}


It might not look like It, but this code is relatively simple:

First, we declare our variables.

In the setup loop we need to declare inputs and outputs. In this case, a button is the input and the output is an IR LED.

In the main program loop the Arduino is waiting for a button press. When the button is pressed, it will trigger the IR code loop and output a message to the serial monitor. (This is for debugging purposes and is not necessary for the program to work).
The next loop primes the IR transmitter to receive code.

The next loop fires the IR transmitter pulses in the sequence that the camera will recognise, resulting in the shutter being triggered.

So now we have made a functional Nikon IR remote. The next step is to tweak the code so that it will fire the shutter every minute.


Making an Intervalometer


For this code I want to have the shutter fire every minute, but I also want to implement a manual override using a button in case I want to test the connection to make sure everything works.


Here is what I came up with:

/*


Nikon D40 Intervalometer


By Matt 


15.10.2016


*/


# define interval 60 //set interval time in seconds



int intervalTime = (interval * 1000); //convert interval from seconds to milliseconds


int IRledPin = 13; // LED connected to digital pin 13


int buttonPin = 2; // push button connected to pin 2


volatile int buttonState = 0; // variable for reading pushbutton status



void setup() {


pinMode(IRledPin, OUTPUT); // initialize the IR digital pin as an output:


pinMode(buttonPin, INPUT); // initialize the button as an input


attachInterrupt(0, pinISR, CHANGE); // attach an interrupt to the ISR vector


Serial.begin(9600); // start serial communication for debugging


}



void loop() {


SendNikonCode(); // fire shutter


Serial.println("Sending IR signal");// print message on serial monitor


delay(intervalTime); // wait this amount of time before firing again


}



void pinISR() {


int val = digitalRead(buttonPin); // read button pin state


if (val == HIGH) { // if button is pressed


Serial.println("Sending IR signal"); // print to serial monitor


SendNikonCode(); // fire shutter


}


}



// This procedure sends a 38KHz pulse to the IRledPin


// for a certain # of microseconds. We'll use this whenever we need to send codes


void pulseIR(long microsecs) {


// we'll count down from the number of microseconds we are told to wait



cli(); // this turns off any background interrupts



while (microsecs > 0) {


// 38 kHz is about 13 microseconds high and 13 microseconds low


digitalWrite(IRledPin, HIGH); // this takes about 3 microseconds to happen


delayMicroseconds(10); // hang out for 10 microseconds, you can also change this to 9 if its not working


digitalWrite(IRledPin, LOW); // this also takes about 3 microseconds


delayMicroseconds(10); // hang out for 10 microseconds, you can also change this to 9 if its not working



// so 26 microseconds altogether


microsecs -= 26;


}



sei(); // this turns them back on


}



void SendNikonCode() {


// This is the code for my particular Nikon, for others use the tutorial


// to 'grab' the proper code from the remote



pulseIR(2080);


delay(27);


pulseIR(440);


delayMicroseconds(1500);


pulseIR(460);


delayMicroseconds(3440);


pulseIR(480);



delay(65); // wait 65 milliseconds before sending it again



pulseIR(2000);


delay(27);


pulseIR(440);


delayMicroseconds(1500);


pulseIR(460);


delayMicroseconds(3440);


pulseIR(480);


}


I have also uploaded this code to github for your convenience.


This code is almost exactly the same as before, but I have changed the button’s behaviour to act as an external interrupt and added a delay function to handle the interval.


You can change the interval by altering the value in the first line. I have set it to 60, as there are 60 seconds in one minute.


This value is then taken and multiplied by 1000 to turn it in to milliseconds.


There is an extra ISR loop in here so that the button can also fire the shutter if needed. As it is an interrupt, it will not reset the clock when the microcontroller is counting through to the next interval.


Results

I set my camera looking out my window for a day firing the shutter at regular intervals. I powered the DFRduino using a lipo battery, but a 5v power supply would be better for long shooting.


At the end of the day I took the images and processed them in VirtualDub to turn them in to a movie. You can find out more about how to do this here: http://timelapseblog.com/2009/08/04/using-virtualdub-for-time-lapse/


Here are some timelapses I took using this setup, I hope you like them:





Conclusion:

This is a relatively easy Arduino project for beginners and can be done over a weekend. It provides lots of scope for expansion allowing you to create other photography triggers. You could take this code and replace the button with a PIR sensor to it so that the shutter fires when someone walks past the camera. You could even take the circuit and add a light sensor in to it and tweak the code so that during a thunderstorm the camera will fire when lightning strikes – that would make for some great photos!

All the components used in this Arduino project and more can be found on DFRobot.com

If you try this out please share your results on the DFRobot forum!