|   |
![]() |
|||||||
|
A few month ago one of my visitors gave me an idea for a new small project, an IR remote control for my Nikon DSLR camera.
Not that I absolutely need one, surely I don't need it bad enough to get one for about €30 or €40 from e-bay.
However it would make a nice little in-between project.
Big Mike explains the very easy protocol used by the original Nikon remote controls ML-L1 or ML-L3 on his web site.
The site also shows some existing DIY projects for a remote.
I happen to be very good at re-inventing the wheel, therefore I have designed and built my own version.
On the above mentioned web site there are some pictures of other people who have built their own versions of an IR remote control in several different appearances.
Personally I think building the remote control in an empty tic-tac box is a great idea!
However I've chosen to build it in an obsolete existing remote control.
Simply because it was at hand and because it can hold two standard AAA batteries.
I've rewired the switch matrix in such a way that I now can press any of the keys to fire the shutter.
I don't have the original specification of the Nikon remote control protocol. The information on Big Mike's web site was also derived from reverse engineering. What I understand from that information is that the timing of the signals is not particularly critical. Therefore I have taken the liberty to adjust some of the times in the waveform to match exact multiples of one clock period of the 38 kHz carrier, which is 26,3 µs.
This diagram shows the timing of one half of the command. The second half is exactly the same and is repeated 63.2 ms after the first command.
The bursts are modulated on a 38 kHz carrier.
Care has been taken to keep the phase of the carrier between the bursts as constant as possible in order to achieve the optimal sensitivity of the IR receiver in the camera.
The software consists of only two subroutines, one of which is carefully designed in order to generate precise timings.
Well, as precise as they can get of course if you consider that the internal RC oscillator of the ATtiny13 can deviate from the nominal frequency by as much as 10%.
The SENDBURST subroutine consists of a main loop which always takes 26.3 µs to execute.
Wait, I tell a lie!
Not always, the first time through the loop is a bit shorter to compensate for the subroutine call and return overhead.
Please note that SENDBURST is the entry point of the subroutine.
;-------------------------------------------------------------------------
; Send BCOUNT pulses.
; BCOUNT : Holds number pulses to send
; BDELAY : Holds high/low delay times
; LEDSTAT : Holds mark (11111111) space (11111101) flag
;-------------------------------------------------------------------------
NEXTPULSE: LDI BDELAY,BURST0 ; Reload delay counter for Low period
SENDBURST: DEC BDELAY ; Low period delay loop
BRNE SENDBURST
NOP ; Fractional compensation
OUT PORTB,LEDSTAT ; Set or Clr output bit
NOP ; OUT is one cycle, SBI was two
LDI BDELAY,BURST1 ; Reload delay counter for High period
BURSTLOOP: DEC BDELAY ; High period delay loop
BRNE BURSTLOOP
CBI PORTB,1 ; Clr output bit
DEC BCOUNT ; Decrement burst pulse counter
BRNE NEXTPULSE ; Do until all pulses are sent
RET
Normally the CPU is in deep sleep mode, in order to save battery power.
When a change occurs on the PORTB0 pin the CPU wakes up.
An interrupt routine is started, however the contents of it are empty.
Immediately after returning from the interrupt routine the two IR commands are transmitted.
Both commands are separated by a 63.2 µs gap.
Add some initialization in front of this all and the program is ready. Before I forget to mention it, the internal RC oscillator runs at 9.6 MHz. By default this frequency is divided by 8, which is a good choice if you're talking energy saving. However it appeared that it was hard to derive a good enough 26.3 µs cycle from this frequency. Therefore I've decided to change the clock division ration to 4, which will give an almost perfect 26.3 µs cycle. Feel free to download the assembler source file and hex file here. I have used Atmel's Studio 4 development tools instead of my own SB-Assembler for a change, just to get the feeling of it. How I missed my local labels in a short program as this already!
If you don't need such a long range you might as well connect an IR LED between +3V and PB1 with a series resistor of 100 Ω.
I haven't tested the maximum range for that configuration, but I believe it should still be at least one metre, which is sufficient if you want to use the remote control to fire the camera without touching it.
OK, I'll admit that the donor remote control has too many buttons for this task.
But this was for me the easiest way to build the project.
All necessary parts are there, buttons, battery holder, output amplifier, filter capacitors, nice case which needed no filing.
What more do I want?!
Please note that the camera will shut down after 15 minutes of inactivity.
So if you need longer intervals than that, make sure to fire it occasionally.
|