I started to look at the communication between Nikon DSLR camera and Speedlight flash not long ago as documented in the post titled Nikon Flash Interface. It turned out to be quite easy to control a Nikon Speedlight flash using a low cost micro-controller board such as the Arduino Duemilanove. I will show you how this can be done using a simple example: instruct the flash to emit the pre-flash.

As shown in the following Logic Analyzer capture, the Data line goes to logic low, followed by Handshake line doing the same. The Data line goes up then the the actual data is sent from camera to flash in sync with the Clock signal, which is generated by the flash. After the byte (0xD7 for pre-flash) is sent LSB first, the Handshake line goes up. This is exactly how a Nikon camera communicates to a Speedlight flash during TTL flash exposure sequence.

To send data, the data needs to be put on the Data line at the falling edge of the Clock. The flash at the receiving end read the data at the rising edge of the Clock. On Arduino, the digitalWrite function is typically used to write to a digital pin. However this command is too slow – taking ~100 microseconds to complete. As described in the previous post, the clock signal has a period of ~32 microseconds. To make this work, a faster alternative has to be used.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
void sendByte(byte mydata) {
  unsigned int i;

  pinMode(data, OUTPUT);
  pinMode(handshake, OUTPUT);
  fastWrite(handshake, LOW);  // Pull handshake low and wait for clock signal

  for(i = 0; i < 8; i++) {
    while(fastRead(clock)); // Wait for clock to go low

    if(mydata & 0x01) {
      fastWrite(data, HIGH);
    }
    else {
      fastWrite(data, LOW);
    }
    while(fastRead(clock) == 0); // Wait for clock to go high
    mydata >>= 1;
  }

  // Data seems always go high after sending a byte
  delayMicroseconds(12);
  fastWrite(data, HIGH);

  // Send handshake to high again
  delayMicroseconds(12);
  fastWrite(handshake, HIGH);
}

The fastRead and fastWrite are macros defined as the following:

1
2
#define fastWrite(_pin_,_state_) (_state_ ?  PORTB |= 1 << (_pin_ -8) : PORTB &= ~(1 << (_pin_ -8) ))
#define fastRead(_pin_) (PINB & 1 << (_pin_ - 8))

After receiving the pre-flash command, the flash unit signals back to the camera by pulsing the Clock low again while the pre-flash is emitted to tell the Camera to starting measuring the reflected light.

More complex communication examples will be discussed in future posts.

Disclaimer: If you decided to try this yourself you will be doing so at your own risk. I am not responsible for any damages and/or injuries.


Related Posts

Comments