IR remote control for Nikon

Introduction

In fact, I don’t need a remote control

I was searching a way to:

But if I could program my arduino to emit the Nikon remote IR sequence, my problem will be solved

In the web

Make.refractal

At first, I tried this code make.refractal
in theory, it should work, but like his author said, it doesn’t

I found 2 possibles reasons:

1. oscillationWrite takes more time than delayMicroseconds

	before=millis();
	for(i=0;i<1000;i++)  oscillationWrite(outPin, 1000);
	intervalle=millis()-before;
	
	Serial.println(intervalle);
	
	before=millis();
	for(i=0;i<1000;i++)  delayMicroseconds(1000);
	intervalle=millis()-before;
	
	Serial.println(intervalle);
	Serial.println(”“);

result in millisecond:

	1306
	1009
	
	1305
	1008

2. I added a variable in the oscillationWrite function to count the number of oscillation.
And this figure doesn’t match 38400Hz at all.

Why 38400Hz ?
Most infrared transmissions operate by modulating the led with a relatively high frequency (in most cases 38 or 40KHz).
This means that when we have to send a bit value “1” the led is turned on and off 38000 or 40000 times in one second. (from bigmike ).
For Nikon remote, it’s 38400Hz.

Cibomahto

I also try this one, cibomahto , completely written in asm,
it looks great, but I never achieved to make it work (compilation problems).
And even if I understand the code, ASM is less flexible than C (at least for me !http://ilpleut.be/ip2-static/face-blink.png!)

A new version

This code is based on 3 ideas:

How it works

The code knows it has to modulate its IR emission at 38400Hz
without a delay at each oscillation, my arduino can emit IR at 100.000hz, too much.

The first part of the code will process the most accurate delay.
It tried to find it in a range of 1 to 100 micro second (min/max variable).
(it’s not exactly a microsecond, but it’s not important)

Once it has this value (called oscd in the code).
It will rewrite the emission sequence. (on,off,on,off…)

the original sequence is {2000,27830,390,1580,410,3580,400,63200,2000,27830,390,1580,410,3580,400,0}

This sequence is in micro second, the code will rewrite it in number of arduino oscillation.

When the setup() is done,
it just has to read the IR emission sequence and call the ‘oscillation’ function.

Output

Ready
2122 : 1<->50   # time in millisecond : next range to test
1154 : 1<->25	  
689 : 13<->25
921 : 19<->25
1038 : 19<->22
961 : 20<->22
999 : 21<->22
1000 : 21<->21	# it found the most accurate delay with 21 microsecond
oscd: 21
2000->76	#start to convert the emission sequence, 2000 micro second = 76 oscillations
27830->1068
390->14
1580->60
410->15
3580->137
400->15
63200->2426
2000->76
27830->1068
390->14
1580->60
410->15
3580->137
400->15
0->0
       #start the emission

Self-portrait

The code


	// ----- C -------
	/**
	 * arduino Nikon IR remote
	 * @license	Creative commons: Attribution-Noncommercial-Share Alike 3.0 (http://creativecommons.org/licenses/by-nc-sa/3.0/)
	 * @author Aurelien ANTOINE
	 * version 1
	 * date 20081217
	**/
	 
	#define PIN_STATUS 13
	#define PIN_IR_LED 12
	#define FREQ 38400  // IR frequence
	 
	//shutter sequence (on,off,on,off ... in microsecond)
	unsigned long sequence[] = {2000,27830,390,1580,410,3580,400,63200,2000,27830,390,1580,410,3580,400,0};
	int seq_l;
	 
	//oscd is a delay in microsecond used at each oscillation.
	int oscd;
	 
	void oscillate(int pin, unsigned long n, int shine){
		int ir_status=0;
		while(n>0){
			n--;
			delayMicroseconds(oscd);
			ir_status  =  !ir_status; 
			digitalWrite(pin,  ir_status && shine);  
		}
	}
	 
	void snap(){
		int i;
		digitalWrite(PIN_STATUS,  1);  
		for(i=0;i<seq_l;i++){
			oscillate(PIN_IR_LED, sequence[i], i%2==0);
		}
		digitalWrite(PIN_STATUS,  0);
	}
	 
	void setup() {
		int min=1, max=100, i;
		int last_oscd=0;
		unsigned long before, intervalle;
		oscd=max;
	 
		seq_l = sizeof(sequence)/sizeof(unsigned long);
	 
		pinMode(PIN_STATUS, OUTPUT);
		pinMode(PIN_IR_LED, OUTPUT);
		Serial.begin(28800);
	 
		//this "while" will process the best "oscd"
		Serial.println("Ready");
		while(last_oscd!=oscd){
			last_oscd=oscd;
			oscd=(min+max)>>1;
	 
			before=millis();
			oscillate(PIN_STATUS, FREQ, 1);
			intervalle=millis()-before;
	 
			if(intervalle >= 1000) max=oscd;
			else min=oscd;
	 
			Serial.print(intervalle);
			Serial.print(" : ");
			Serial.print(min);
			Serial.print("<->");
			Serial.println(max);
		}
	 
		Serial.print("oscd: ");
		Serial.println(oscd);
	 
		//rewrite the sequence array, we replace all values in microsecond by the number of oscillation
		for(i=0;i<seq_l;i++){
			Serial.print(sequence[i]);
			Serial.print("->");
			sequence[i] = (sequence[i] * FREQ) / (intervalle * 1000);
			Serial.println(sequence[i]);
		}
	}
	 
	 
	void loop() {	
		//make a photo, wait 10 seconds
		snap();
		delay(10000);
	 
	}

Notes

Links

Those links helped me a lot !!

Referrer