Sunday, January 10, 2010

Infrared controlled timelapse photography
with Canon DSLRs

I wished all digital cameras would allow timelapse shooting out of the box. Digital cameras with a selftimer are able to trigger a photo via it's software but for some odd marketing reasons timelapse is seldom added. And even if your camera has a timelapse option it is often limited to 999 shots.

You can find lots of remote cable based external timelapse solutions for Canon cameras on the web but I haven't yet seen one that works infrared based.



This solution is based on a previous post. A different code and a push button instead of a switch allows timelapse control of Canon DSLRs that are compatible with the Canon RC-1 infrared remote control.

The timelapse settings like interval and number of shots can be set in the code. Once the sketch is loaded to the Arduino board it can run standalone close-by to the cameras infrared receiver.


/*
Arduino sketch for simulating a Canon RC-1 IR remote control to do timelapse photography with a compatible Canon DSLR
2010, Martin Koch
http://controlyourcamera.blogspot.com/
Huge thanks go to http://www.doc-diy.net/photo/rc-1_hacked/index.php for figuring out the IR code.
*/

#define irLED 12
#define statusLED 13
#define pushBUTTON 7

int interval = 15; //seconds
int timelapseDuration = 60; //seconds
int numberOfShots = timelapseDuration / interval;

void setup() {
pinMode(irLED, OUTPUT);
pinMode(statusLED, OUTPUT);
pinMode(pushBUTTON, INPUT);
digitalWrite(pushBUTTON, HIGH);

}

void loop() {
if (digitalRead(pushBUTTON) == LOW) {
digitalWrite(statusLED, HIGH); //Timelapse active
for (int i=0; i <= numberOfShots; i++) {
sendInfraredSignal();
if (i < numberOfShots) delay(interval * 1000); //ms
}
digitalWrite(statusLED, LOW);
}
}

void sendInfraredSignal() {
for(int i=0; i<16; i++) {
digitalWrite(irLED, HIGH);
delayMicroseconds(11);
digitalWrite(irLED, LOW);
delayMicroseconds(11);
}
delayMicroseconds(7330);
for(int i=0; i<16; i++) {
digitalWrite(irLED, HIGH);
delayMicroseconds(11);
digitalWrite(irLED, LOW);
delayMicroseconds(11);
}
}


If the infrared timing is known the sendInfraredSignal() sub routine can be adapted to release other cameras.

Add a serial LCD and potentiometers for setting interval and number of shots for a simple to make luxury intervalometer that doesn't require to re-programming the Arduino every time you want to change settings. Multi turn precision potentiometers would allow very fine adjustments e.g. a voltage between 0 and 5 V could translate to an interval between 1 to 3600 seconds and to 1 to 5000 shots. Rotary encoders would give even more flexibility and accuracy.

12 comments:

  1. Hello Martin!
    Considering how much you work with video recording devices, I thought you could be interested to test/review GraphEditPlus (software tool for DirectShow developers). I do work for company which created it, and I do think that GraphEditPlus is relevant to this blog. If you are interested, check out details at http://infognition.com/GraphEditPlus/, our contacts can be found on the same website.
    Best of luck and thanks for your blogs.
    Irina

    ReplyDelete
  2. Man thanks a LOT for your project. I am searching this for some time. ;)
    I am an Arduino Addicted and photographer/FilmMaker, using a Canon7D. Now i can do really usefull stuffs with my arduinos. ;)
    Thanks again ! This will be VERY useful !

    ReplyDelete
  3. Hey cool. you may be interested in the openmoco.org project! ;-D J

    ReplyDelete
  4. Two questions: 1) I have a Rebel XTi and an RC-6 remote ... do you know how to adjust this? Also, if the camera has gone to sleep, can the IR wake it ... or do you need to have the camera plugged into wall power?

    ReplyDelete
  5. Howard, there's a comment by Carlos to the previous post where he describes how it works with the XTi.

    I don't think it will wake up the camera but since you have a remote and the Xti I suggest you try it.

    I have never done a long duration timelapse but I guess people turn of the sleep mode and use large batteries or if possible wall power.

    ReplyDelete
  6. Thanks for sharing, but I had better results with a modified version of the code, based on code I used for remote control of a television.

    #define PERIOD_CANON 30 // 32.7khz =~ 30.6us
    #define DUTY_CYCLE 1/3 // Carrier duty cycle, was 1/3
    #define ACTIVE_HIGH_CAN (PERIOD_CANON * DUTY_CYCLE)
    #define ACTIVE_LOW_CAN (PERIOD_CANON - (PERIOD_CANON * DUTY_CYCLE))

    void sendCanonIR()
    {
    //disable interrupts
    cli();

    for(int i=0; i<16; i++) {
    PORTB |= _BV(4);
    delayMicroseconds(ACTIVE_HIGH_CAN);
    PORTB &= ~_BV(4);
    delayMicroseconds(ACTIVE_LOW_CAN);
    }
    delayMicroseconds(7330);
    for(int i=0; i<16; i++) {
    PORTB |= _BV(4);
    delayMicroseconds(ACTIVE_HIGH_CAN);
    PORTB &= ~_BV(4);
    delayMicroseconds(ACTIVE_LOW_CAN);
    }

    //re-enable interrupts
    sei();
    }

    ReplyDelete
  7. Hi!
    Thanks for sharing this! That comes really handy and you can do great stuff with it!

    I just got a question about the IR Signal:

    Here http://www.doc-diy.net/photo/rc-1_hacked/ it says the Signal consists of 2 bursts with 16 pulses in a frequenzy of 32700Hz with a delay between the bursts.

    I understand your code:

    void sendInfraredSignal() {
    for(int i=0; i<16; i++) { //16 pulses
    digitalWrite(irLED, HIGH);
    delayMicroseconds(11); //11ms ?
    digitalWrite(irLED, LOW);
    delayMicroseconds(11); //11ms ?
    }
    delayMicroseconds(7330); //delay
    // next burst

    Just how do the 2 delays of 11ms sum up to a frequenzy of 32700Hz?? Might be a stupid question but I am new with this kind of stuff and pretty curious about it ;)

    Thanks a lot for any answers!!

    T.

    PS: Same problem in the code Adion postet. What is the DUTY-CYCLE? Could anyone explain the math (for either one of the codes or both)

    ReplyDelete
  8. I am testing your Code an with my EOS 60D it works better than DUTY_CYCLE snippet. Thank you for sharing!

    For the maths:

    1 cycle is 22uS = 22/1000000 seconds. So this would be equivalent zu 45454 Hz if the processer needed only time to execute the delays.

    One improvement I've made is to use a high power IR-LED (100mA) driven by an extra transistor.

    ReplyDelete
  9. With 500D and arduino mega:
    Initial I couldn't get this to work so I boosted the IR led with a transistor like R3 R4 and Q1 in http://www.robotroom.com/Infrared555.html I used 22ohm R3 as using high power 150mA max LED. Still no joy till reduced high freq delay - my code was:

    #define irLED 7
    #define statusLED 13
    #define pushBUTTON 7


    #define PERIOD_CANON 16 //14-19 seems to work for 500d //original: 30 ~= 32.7khz =~ 30.6us
    #define DUTY_CYCLE 1/3 // Carrier duty cycle, was 1/3
    #define ACTIVE_HIGH_CAN (PERIOD_CANON * DUTY_CYCLE)
    #define ACTIVE_LOW_CAN (PERIOD_CANON - (PERIOD_CANON * DUTY_CYCLE))



    void setup() {
    pinMode(irLED, OUTPUT);

    }

    void loop() {
    sendCanonIR();
    delay(2000);
    }


    void sendCanonIR()
    {
    //disable interrupts
    cli();

    for(int i=0; i<16; i++) {
    digitalWrite(irLED, HIGH);
    delayMicroseconds(ACTIVE_HIGH_CAN);
    digitalWrite(irLED, LOW);
    delayMicroseconds(ACTIVE_LOW_CAN);
    }

    // choose 5330 for 2s delay, 7330 instant.
    delayMicroseconds(5330);
    //delayMicroseconds(7330);

    for(int i=0; i<16; i++) {
    digitalWrite(irLED, HIGH);
    delayMicroseconds(ACTIVE_HIGH_CAN);
    digitalWrite(irLED, LOW);
    delayMicroseconds(ACTIVE_LOW_CAN);
    }

    //re-enable interrupts
    sei();
    }


    Thanks to all for the useful info.

    ReplyDelete
  10. Hello Martin
    Thanks for this software, it works well for me. I am using an Arduino Duomilanova running Arduino 1.0 version of the IDE. I tested it using a Canon 60D. I plan to adapt it to do some time lapse photography. Thank you again.

    ReplyDelete
  11. Amazing, I made it! This works! Thank you for this tutorial also.

    ReplyDelete