The basic idea was to create IR intervalometer for my Nikon DSLR. I have found in network information about captured raw signal from existing Nikon ML-L3 remote control. So, I have decided to use this information and Arduino Uno to create IR time-lapse intervalometer device for Nikon DSLR. Original RAW IR signal is modulated with 38kHz frequency and have following timings:
- 2.0 ms - on
- 28.0 ms - off
- 0.5 ms - on
- 1.5 ms - off
- 0.5 ms - on
- 3.5 ms - off
- 0.5 ms - on
- 63.5 ms - off
First step was to create a shield for arduino with support for IR LED and one button. IR diode is driven by NPN transistor to achieve 35 mA of current and larger distance for control. Button it pulled-up to 5 volt. Here is schematic:
Second step was to create program. Value of current interval for time-lapse is stored in EEPROM and it is possible to update it by USB serial by sending command:
- setInterval:12345 (five digit value of interval in seconds). I have used two libraries:
- first for button debouncing. Here is library source: https://github.com/thomasfredericks/Bounce2
- second for driving IR LED. Here is library source: https://github.com/z3t0/Arduino-IRremote
Here is flow diagram for program:
Source code is also available in attachment.
/* Basic IR intervalometer for Nikon DSLC cameras by kk99 2018 */ #include #include #include IRsend irSend; Bounce debouncer = Bounce(); const int BUTTON_PIN = 2; const unsigned long DEFAULT_TIMELAPSE_INTERVAL_SEC = 5; const int EEPROM_ADDRESS = 0; bool isWorkingMode = false; bool requestNextPhoto = false; bool isUpdateTimelapseInterval = false; unsigned int timelapseIntervalValueToUpdate = 0; unsigned long timelapseIntervalMs = 0; unsigned long lastPhotoTime = 0; unsigned long getTimelapseInterval(void) { unsigned long timelapseIntervalVal = 0; EEPROM.get(EEPROM_ADDRESS, timelapseIntervalVal); return timelapseIntervalVal; } void setTimelapseInterval(unsigned long timelapseIntervalVal) { EEPROM.put(EEPROM_ADDRESS, timelapseIntervalVal); } void takePhoto(void) { // modulation frequency in kilohertz int frequency = 38; // signal for take a photo by Nikon DSLR unsigned int irSignal[] = {2000, 28000, 500, 1500, 500, 3500, 500, 63500}; irSend.sendRaw(irSignal, sizeof(irSignal) / sizeof(irSignal[0]), frequency); } void workingModeLED(bool on) { if (on) { digitalWrite(LED_BUILTIN, HIGH); } else { digitalWrite(LED_BUILTIN, LOW); } } void setup() { // initialize serial communication Serial.begin(9600); // initialize digital pin for builtin status LED as an output pinMode(LED_BUILTIN, OUTPUT); workingModeLED(false); // initialize digital pin for button as an input pinMode(BUTTON_PIN, INPUT); // setup button debouncer debouncer.attach(BUTTON_PIN); debouncer.interval(50); // read timelapse interval in seconds unsigned long tempTimelapseIntervalVal = getTimelapseInterval(); if (tempTimelapseIntervalVal == 0) { Serial.println("Restored default value of time-lapse interval"); tempTimelapseIntervalVal = DEFAULT_TIMELAPSE_INTERVAL_SEC; setTimelapseInterval(tempTimelapseIntervalVal); } timelapseIntervalMs = tempTimelapseIntervalVal * 1000; Serial.println("Intervalometer initialized"); } void loop() { // update time unsigned long timestamp = millis(); // check button state debouncer.update(); bool buttonState = debouncer.fell(); if (buttonState) { isWorkingMode = !isWorkingMode; } // update status LED workingModeLED(isWorkingMode); if (isWorkingMode) { // check timelapse interval if (requestNextPhoto) { unsigned long diffMs = timestamp - lastPhotoTime; if (diffMs > timelapseIntervalMs) { requestNextPhoto = false; } } // take a photo if (!requestNextPhoto) { Serial.println("Captured picture"); takePhoto(); requestNextPhoto = true; lastPhotoTime = timestamp; } } else { requestNextPhoto = false; lastPhotoTime = 0; if (isUpdateTimelapseInterval) { unsigned long currentTimelapseInterval = timelapseIntervalMs / 1000; if (currentTimelapseInterval != timelapseIntervalValueToUpdate) { setTimelapseInterval(timelapseIntervalValueToUpdate); timelapseIntervalMs = timelapseIntervalValueToUpdate * 1000; Serial.println("Updated value of time-lapse interval"); } isUpdateTimelapseInterval = false; } } } void serialEvent() { if (isUpdateTimelapseInterval) { return; } const int dataLength = 18; if (Serial.available() < dataLength - 1) { return; } int i = 0; char receivedData[dataLength] = { 0 }; while (Serial.available() > 0) { char character = Serial.read(); if (i < dataLength - 1) { receivedData[i] = character; } i++; } char *data = strstr(receivedData, "setInterval:"); if (data) { data += 12; int timelapseIntervalVal = atoi(data); if (timelapseIntervalVal > 0) { Serial.println("Got new value of time-lapse interval in seconds:"); Serial.println(timelapseIntervalVal); isUpdateTimelapseInterval = true; timelapseIntervalValueToUpdate = timelapseIntervalVal; } } }
Here is example video of remote controlling of Nikon DSLR:
Top Comments