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
- 
	
	
					
				
			
			 
	
		
			
											
					mcb1
				
					
		
			
		
			 
 
	
		- 
				Cancel
			
 
		
 
 
		 		 		
		- 
					
						
						
													Vote Up
						
						+2
													Vote Down
											
				
 
				- 
															
				
 
										- 
											Sign in to reply
									
 
																		- 
				More
			
 
			- 
				Cancel
			
 
		
 
  
 
	
- 
	
	
					
				
			
			 
	
		
			
											
					kk99
				
					
		
			
		
									
					in reply to mcb1
				
						 
 
	
		- 
				Cancel
			
 
		
 
 
		 		 		
		- 
					
						
						
													Vote Up
						
						+2
													Vote Down
											
				
 
				- 
															
				
 
										- 
											Sign in to reply
									
 
																		- 
				More
			
 
			- 
				Cancel
			
 
		
 
  
 
	
Comment- 
	
	
					
				
			
			 
	
		
			
											
					kk99
				
					
		
			
		
									
					in reply to mcb1
				
						 
 
	
		- 
				Cancel
			
 
		
 
 
		 		 		
		- 
					
						
						
													Vote Up
						
						+2
													Vote Down
											
				
 
				- 
															
				
 
										- 
											Sign in to reply
									
 
																		- 
				More
			
 
			- 
				Cancel
			
 
		
 
  
 
Children