• Increase font size
  • Default font size
  • Decrease font size



Analysis of the Nikon iTTL protocol

In this article I describe my findings on the iTTL protocol used by Nikon to control on-camera electronic speed lights. I will include information on the physical layer, serial data transmission, commands, timing, frame composition, and standard sequences like ON/OFF, and firing a flash.

Note: In this article I will only describe the iTTL protocol. In contrary to the TTL (Trough The Lens) protocol iTTL uses a series of pre-flashes to determine the strength of the main flash light output.

Note: These findings are based on sniffing the lines between flash and camera. I also send fake bytes to camera and flash to determine its behavior in case of a broken connection. No device has been hacked into and no firmware has been downloaded, analyzed or broken. No camera or flash took physical or software damage. Most of my findings are based on the combination D700 and SB800. The sole purpose of the information presented on this page is to for academic reasons.

Note: Implementing this protocol in a commercial product may violate the rights of Nikon



Overview: iTTL Data transmission

The iTTL interface uses two signal lines that form a synchronous serial interface plus one acknowledge and one trigger line. In total there are four signals. Data to and from the flash is send in packets consisting of at least one byte, possibly multiple data bytes and usually a one byte checksum. The camera always initiates a data transmission, during transmission the flash provides the clock signal. Each byte send is acknowledged as well as the reception of the whole frame. 

Physical Layer


The hot shoe connector of the camera. The big middle contact is the old X-SYNC contact, the metal framing is ground. The hole top middle is part of a locking mechanism.


Picture of the cameras hot shoe


 The flash-side of the interface as seen from the bottom. The bolt on the top middle is used to lock the flash onto the camera and prevent removal by sliding it off. The golden contacts are used for an external AF illumination light.


Hot shoe interface of the SB800


Missing: Dimensions



Four lines (and ground) connect the flash and the camera:


 Position (camera)

Notesalternative nomenclature
SB800 service manual  old TTL
ACKtop right
acknowledge and enable line, driven only by the camera; camera acknowledges each byte
CRYSpeedlight Present
DATAbottom right
bidirectional data line, signals start of frame, transports transmitted data and receivers "frame acknowledge"CSTP Q Quench STOP
CLOCKbottom left
clock line, driven only by the speedlight during data transfer CSP Ready 
when pulled low the speedlight fires a flash
CX  X (trigger)X-SYNC

Each line (except for the good old X-sync) has multiple functions, for example the camera starts a transmission by pulling the data line low then the data is being transmitted in both directions and in the end the speedlight signals the successful reception of a frame by pulsing the DATA line low. So there is a start, data and acknowledge on this one line.


Electrical specifications

Flash side:

In the flash connector the pins ACK, DATA, CLOCK are bypassed to GND via a 220pF capacitor. The digital circuitry in the SB800 is powered by 4V suggesting 4V TTL levels. I strongly recommend not to use voltages above this level. On my test bench the electronics is powered by 3.3V and works flawless, 3.0V is too low.


Schematic of the flash interface


The CLOCK line is handled by the flash only. If the bus is idle the CLOCK is at a high level. Data is shifted in and out on the DATA line on every rising CLOCK edge. The CLOCK line is actively driven by the flash via a 330 Ohm resistor.

DATA and ACK are pulled up via a resistor of some 10K Ohms (micro controller internal pull-up), I think the actual value does not matter. Both, the flash and the camera cam pull each of the lines low - either via a chip internal open collector/drain or by setting the corresponding output buffer as output. This way data and acknowledge pulses can be send in both directions.

Note: keeping the ACK line low effectively blocks any user input on the flash.

The X-SYNC is special: Due to historical reasons the voltage on an arbitrary flash unit can be as high as several hundreds of volts. The SB800 however only outputs around 3.6V. If you pull this line low without any previous data communication the flash will fire at full power.

More information can be distilled out of the SB800 Service Manual.

Camera side:



Hardware used

Let me briefly describe which hardware I used to sniff and decipher the lines, figure out the meaning of the frames and the timing.

Logic analyzer

I used my saleae logic (external link) to capture the data, and the built-in SPI decoder to decode the raw data. Further processing is done by means of a python script that looks for frame start conditions and compresses repeating frames into one data block containing a counter that shows how many times this particular frame occurred.


To interface with the camera I build a small battery powered circuit that sits on the hot shoe and allows me to tap the contacts of the camera as well as to simulate a flash. For this purpose the circuit contains a micro-controller and an RF transceiver that allows communication in real time.  Connection to the flash is done via the connector of a TTL extension cord. The circuit also serves as a remote shutter release for future use.

Missing: Picture


Frame composition

A data frame consists of exactly one header byte (command) which is always send by the camera, multiple data bytes and a checksum byte. There are a few frames that are obviously time critical and therefore contain no data and/or no checksum to reduce latency.

 Header (1 byte)


 Checksum (1 byte)


Sending a frame

The data is transferred in a synchronous serial way, with one acknowledge/enable line. It differs from all serial protocols I know in that special conditions signal the start of a frame, acknowledge each byte and finally acknowledge the whole frame. Data is send LSB first at a peak bit rate of about 30kbp, but due to the protocol overhead the average bit rate is only 12kbps.

Only the camera is allowed to start a frame.

Step 0:
Wait until the bus is clear: CLOCK, DATA, ACK must be high for at least 600µs
Step 1: Arbitration phase
 Step 1a:t=0µsThe camera initiates the frame by pulling DATA low for 370µs
 Step 1b:t = 100µs .. 600µsAs soon as the flash recognizes DATA low it acknowledges by pulling DATA low as well for 600µs
 Step 1ct=370µsThe camera releases the DATA line (which is held low if a flash is present)
 Step 1d:t = 600µs .. 700µsThe camera checks whether DATA is low: This signals the presence of a flash
 Step 1e:

As soon as the camera has detected a flash it pulls the ACK line low to signal the start of the data transmission

 Step 1f:The flash releases the DATA line: Ready for Step 2
Step 2:Data transmission
 Step 2a The flash pulles the CLOCK line low for 16µs; as soon as the sender detects the CLOCK line low it applies the first bit (LSB) to the DATA line
 Step 2b:On the rising edge the data is shifted into the receiver
 Step 2c:The CLOCK line is high for 16µs. Steps a-c are repeated until all 8 bits are send
 Step 2d:The camera acknowledges the byte within about 120µs by pulsing the ACK line for 71µs.
 Step 2f:The next byte is transmitted as soon as the flash starts pulsing CLOCK low again. This usually happens within 100µ - 450µs.
 All consecutive bytes are transferred in the same manner as in steps 2 a-f.
Step 3:Send the CRC. This is done as in steps 2 a-c
Step 4:Signal the successful transmission of the frame
  If the flash was the receiver of the payload:
 Step 4a:Immediately after the last rising edge of the CLOCK the camera releases the DATA line
 Step 4b:The camera acknowledges the byte within about 120µs by releasing the ACK line.
 Step 4c:Within 300µs the flash signals the successful reception of the frame (correct number of bytes and valid CRC) by pulling DATA low for about 2ms after it detects the rise of the ACK line.
  If the camera received the payload:
 Step 4a:The camera acknowledges the byte within about 120µs by releasing the ACK line.
 Step 4b:After the flash detects the rise of the ACK it releases DATA (in the case the last transmitted bit was 0) (typ. after 30µs)
 Step 4c:After the camera detects DATA high for 140µs it acknowledges the frame by pulling DATA low for 1.30ms
Step 5:The bus has to be free (all lines high) for at least 600ms until the next transmission (step 1) can be started.

If the flash is the receiver it can stop any data transfer from the camera after each byte by not issuing any more CLOCK pulses until the camera releases the ACK line. This takes about 5.5ms.
Below you find a few snapshots of the communication. I also uploaded a series of data dumps at Resource Section of this article.

Start of frame:

Start of frame


Transmission of a single byte:

Transmission of a single byte


End of frame:

End of frame


One frame:

One frame



Detailed Description

Header (first byte in frame)

The header byte (which is always send by the camera) determines whether the camera or the speed light sends the following data and the checksum. The following header bytes are known to me:

 Table: Command overview

Command (header byte)


Who sends payload?

Payload length
without CRC

Checksum seed












Standard frame, flash reports its settings, meaning 90% known








first byte after power on, fixed unknown content








third byte after power on, fixed unknown content








Standard frame, camera reports its settings, meaning 90% known








second byte after power on, unknown content, camera specific








send by the cam after the main flash, no checksum

2d 1dafter Postflash_1 the camera queries the speedlight for this data







 CRC always 0

enable/disable the AF assist light

209d  0xD111010001bRed_eye Cam1d

Send red eye reduction preflashes: Payload 128 start, 0 stop (check)





Cam, Flash


 CRC always 211d

set flash power, CRC is send by flash




Modeling Light



 CRC always 213d

enables the modeling light, check who sends CRC








first pre-flash, no data, no checksum, special timing on the clock line








second pre-flash, no checksum, special timing on the clock line








sends the speedlight to sleep

The command seems to consist of various addressing bits. But so far they don't make any sense. There is no obvious way to tell from a command how many bytes have to be transferred. The only thing I know is that the MSB is always set (i.e. only commands >128d exist) and bit 4 seems to specify the sender of the payload (except command 0xC0).

 41: Camera sends payload; 0: Flash sends payload
 71 always



The number of payload bytes differs from command to command: How many bytes are exchanged is stated in the table for the header byes. The sender of the payload is determined by the bit 4 in the header byte. If this bit is set the camera is the sender, else the camera receives the data.

INIT_0 (0xA1)

This if the first frame after either the camera is switched on or the speedlight is detected by the camera. The camera issues the command 0xA1 and the flash responds by sending 17 bytes and the checksum (seed 1d). Although the data is known for the SB800 the meaning of the data is unknown. Below you find the data send by the SB800, byte 1 is send first.

Byte 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
dec 1 1 2 1 8 7 1 50 150 100 12 78 165 44 67 38 67
hex 0x01 0x01 0x02 0x01 0x08 0x07 0x01 0x32 0x96 0x64 0x0C 0x4E 0xA5 0x2C 0x43 0x26 0x43


INIT_1 (0xB1)

The second frame after power-on is transmitted from the camera to the speedlight. It consists of 9 bytes plus a checksum (seed 1). The content of the nine bytes depends on the camera. I suspect the camera to tell the flash about its capabilities, for example about FP synchronization and BL as this is shown on the display of the flash. The meaning of the data is unknown. Below you find the data send to the speedlight by various cameras. Byte 1 is send first.

Byte 1 2 3 4 5 6 7 8 9 Camera
0x01 0x06 0x01 0x03 0x01 0x09 0x00 0x00    D70s
  0x01 0x01 0x08 0x0D 0x03 0x01 0x09 0x1C 0x00    D200
 0x01 0x010x12 0x05
0x090x1C0x00   D700
  0x020x010x180x040x030x010x080x240x00   D3100

Serial number of SB800: 2399449

INIT_2 (0xA2)

The third frame after power-on finishes the initialization process. After the camera issues the command 0xA2 the flash sends a surprising 45 byte long answer. The 45 bytes are the same for all different INIT_1 frames I have seen (see above). Sadly as for the other INIT frames I have no idea about the content, but I somehow doubt that there is that much data needed by the camera.

Byte1234567891011121314151617 18
hex03 0D7A
 Byte33 343536373839404142434445                   

There is a pattern in this data: in the table below I sorted the data into four groups. Within one column (e.g. bytes 2, 13, 24, 35) the values actually "do not change much". Whatever that means. And there is a regularly appearing 128d.

byte 1 2 3 4 5 6 7 8 9 10 11 12
dec 3 13 122 172 156 139 128 119 108 96 87 78
hex 0x03 0x0D 0x7A 0xAC 0x9C 0x8B 0x80 0x77 0x6C 0x60 0x57 0x4E


byte   13 14 15 16 17 18 19 20 21 22 23
dec   14 135 171 157 141 128 116 105 95 86 76
hex   0x0E 0x87 0xAB 0x9D 0x8D 0x80 0x74 0x69 0x5F 0x56 0x4C


24 25 26 27 28 29 30 31 32 33 34
dec   12 114 156 148 137 128 120 113 105 98 91
hex   0x0C 0x72 0x9C 0x94 0x89 0x80 0x78 0x71 0x69 0x62 0x5B


byte   35 36 37 38 39 40 41 42 43 44 45
dec   11 111 156 148 139 128 119 113 103 98 92
hex   0x0B 0x6F 0x9C 0x94 0x8B 0x80 0x77 0x71 0x67 0x62 0x5C

I converted the above data to ASCII as well, but the characters make no sense. Nothing like "SB800" or so. Nor did I find the serial number of the flash in that data.


Flash_Settings (0xA0)

This byte is send as a command to the flash to read its settings. The flash then sends 21 bytes payload and one checksum byte with the seed 1d. Byte 1 is send first.

2 3
 10 1112 13
Mode #8+102
RPT: f
RPT: n

discrete values

 0 0 0CLS?Menu
Gr A: fv
 Gr B: fv Gr C: fv 

Byte 1: Status byte

This byte contains numerous status bits of the flash reflector settings and the ready-light of the flash.

 0Set if the ready light of the flash is on
 11 if flash display illumination is on
 2clear if reflector is facing forward and not tilted, otherwise set
 3 set if ready light of the flash is flashing
 4 set if diffuser is pulled out
 5 set if soft-box attached
 6 always clear

 always clear

Byte 2:  Mode

This byte reflects the actual operation mode of the flash. Note that "FP" is additionally displayed on the LCD of the flash, if the camera supports it (not for RPT).

ValueFlash displays
4A (speculation)
I speculate that #4 is be a simple "A" mode as from the manual of the SB800, p19. In mode "AA" the aperture from the camera is taken into account for calculating the required flash power, in "A" mode you have to enter this manually.

Byte 3: Unknown

This byte is always #8+102d. Purpose unknown

Byte 4: Activity

This byte signals user activity to the camera (eg. to reset the exposure meter tome-out).

 0set for 1 second after a button press and for 5sec. if power of the flash was not sufficient
 10 always
 21 always
 3set if flash is in mode A
 4high if AF assist light is on
 50 always
 6set if flash is in mode A
 70 always

NOTE: Red eye reduction lamp (if available) and maybe the buzzer status (can not check this one) should be in there as well.

 Byte 5: Unknown

This byte is always 0d. Purpose unknown

 Byte 6: Flash Power

This byte reflects the fraction of the flash power as set on the speedlight in all manual modes.

Output power = 2^(-x/6)

Please note that on the flash you can only set the power in 1/3 stops.

 Byte 7: Unknown

This byte is always #8+34d. Purpose unknown

 Byte 8: Unknown

This byte reappears modified in bytes 3 and 7. Purpose unknown

 Byte 9: Unknown

This byte is always 48d. Purpose unknown

 Byte 10: Reflector Settings

This byte shows the zoom-setting of the reflector in the flash. The focal length is given in millimeter.

 Byte 11: Stroboscope - Frequency

The frequency of the stroboscope (flash in mode RPT) given in Hz.

 Byte 12: Stroboscope - Number of Flashes

The number of flashes the speed light will fire when set to mode RPT

 Byte 13: Unknown Settings

Purpose unknown. Values observed so far: 9, 16, 18, 20, 21, 22

 Byte 14 - 16: Unknown Settings

Purpose unknown. Always 0d. I suspect group settings for the CLS (creative lightening system). Not checked yet

Byte 17: CLS 

Changes when the remote settings of the flash are changed. Exact purpose unknown.

Byte 18: Menue activiy

Changes when the menue of the flash is accessed.

 Byte 19 - 21: CLS - flash exposure compensation / power

Flash exposure compensation or flash power for the three groups (A-C) of the CLS. Flash power is encoded the same way as in byte 6.



The checksum for this frame uses 1 as seed. 

2 3
 10 1112 13
Config. 64d always
f-stopfocal length
exposure compensation


changes with cam

f-stop +1

D700: ISO else:0

D700: ISO else:0

 Note: There is no bit to indicate that the flash was fired using the "Test" button.

Byte 1: Mode

Depending on the Settings of these bits various modes show up on the display of the flash. So far I have only seen the below values

Byte 2: Configuration

This byte sets the configuration of the camera/flash.

 0sync on 2nd curtain
 1red eye reduction
 2camera display illumination on
 30 always
 4FP required (check!)
 5FP available in current mode
 6TTL available
 70 always

NOTE to self: check whether bit 5, 6 enable the display of FP and TTL in flash display


Byte 3: unknown

On all cameras I have tested this byte is always 64d. 

Byte 4: ISO setting

The set ISO value can be calculated the following way:
ISO = 100 * 2^((x-30)/6)

Byte 5: Exposure

This signed char encodes the exposure time:
t [s] = 2^(-x/6)
x = 128d encodes the bulb mode.

Byte 6: f-stop

f-stop = 2^(x/12)

Byte 7: Focal length

f [mm] = 2^( (x+55.4)/24)
That was a hard one to figure out, thanks Marcus!

 Byte 8: Flash exposure compensation

This signed byte encodes the flash exposure compensation:
EV [stops] = -x/6

Byte 9: unknown

This byte is always 48d = 110000b = 0x30

Byte 10: Distance

The actual focus distance is transferred to the flash as well:
d [m] = 2^( (x-80)/6)

Byte 11: strange byte

The value of this byte depends on the focal length and the focus distance. The exact formula is unknown.

Byte 12: f-stop (again)

Most of the time the value of this byte is equal to the byte 6. But every now and then it is one count higher. This +1 does no depend on the in-camera fine tuning. Maybe this byte represents something like debounced data?

Byte 13/14: ISO (again)

On a D700 these two bytes contain exactly the same value as byte 4. On myD200/D70s these bytes contain only zeros (0x00). Purpose unknown.

Postflash 1 (0xC0)

There is something not quite right here, it seems that C0, C1 are commands which are send within one frame. So this must be handeled separately...

After the power of the flash has been set via the Flashpower command and the flash was triggered by the X-Sync line beeing pulled low the camera sends one byte to the flash (presumably to tell about about underexposures etc). The meaning of the bits is unknown so far.

Within the same frame the camera sends thecommand 0xC1 and the flash responses by sending its data.

Postflash 2 (0xC1)

This command is issued within the same data-frame as the 0xC1 after the flash has fired. The flash presumably sends data of whether it actually has fired. The further meaning is unknown to me. All I can say is that the payload is different for high-speed-sync and normal flashes, e.g. after a normal flash the payload can be 0x0A, 0xB4 (flash mode M, 1/1, D70s&D200, non FP), 0x0A, 0x00 (flash mode M, 1/1, D200&D700, with FP), 0x0A, 0xC6 (flash mode M, 1/1, D700, no FP), 0x0A, 0xC2 (flash mode M, 1/1, D3100, no FP).


AF-ILL (0xD0)

Controls the AF illumination lamp in the speedlight. The camera sends two bytes after the command. The first byte enables (0x01) or disables (0x00) the AF-LED, the second byte is always 0x00. The LED is enabled/disabled 1ms after the frame was send. If the frame is not repeated the LED is automatically shut off by the flash after 900ms. My investigations show that you can also send a 0x00, 0x01 to enable the AF LED. Other bits than bit 0 in either byte seem to have no effect.
"208 001 000" is appended after each regular transmission of command 160/176 as long as the AF light is required


Red_eye_reduction (0xD1)

The 1 byte payload enables (128d) or disables (0d) weak flashes before the main flash to reduce red eyes.


Modeling Light 0xD5

To enable the modeling light the camera sends the command 0xD5 and 0xD5 again as "CRC". The flash then fires a series of flashes for about 1.5 seconds. During this time it holds the DATA line low to signal it is not ready for new data.


Preflash1 (0xD7)

The camera uses several pre-flashes to determine the requires flash power. The first pre-flash is weaker than 1/128 full power, but stronger than one single flash when the button for the modeling light is pressed.

After the command has been transmitted to the flash the flash fires about 2ms after the last rising clock edge. There is a jitter of about 500µs around this 2ms.The flash signals the firing of the flash by pulling the clock line low for 310µs as it fires.


Preflash2 (0xD8)

In case the first pre-flash was not strong enough for the camera to be evaluated the camera can issue a second pre-flash. After the command byte the camera sends 1 byte of payload containing information about how strong  the second pre-flash will be.

0d: weakest setting, the power of preflash1

9d: 1/128 + 2/3ev

24d: maximum, standard value, 1/32 + 1/3 power

After the command and the 1 byte payload has been transmitted to the flash the flash fires about 2ms after the last rising clock edge. There is a jitter of about 500µs around this 2ms.The flash signals the firing of the flash by pulling the clock line low for 310µs as it fires.

Note: I managed to fire pre-flashes at rates of about 100Hz, but the flash head heats up quickly doing so. I do not recommend this!


Flashpower 0xD3

After one or two pre-flashes have been fired the camera calculates the required output power for the main flash. This data is then transmitted in two bytes to the flash using the command 0xD3. The first byte carries information about the required flash, the second byte sets the flash power.

Byte 1: This byte sets the flash type

 3FP on
 4always 1
 50 always
 61 if Flash EV lock
 71 if Flash EV lock
  • Bit 3 enables the FP feature for the following flash.
  • The lowest 3 bits give the time the flash will emit bursts of short flashes in FP mode. One LSB is worth 4ms, the valid range is from 4ms (001b)  to 32ms (111b). If not in FP these bits are ignored.
  • Bit 4 has only been observed set.
  • Bit 5 does not change anything on the behavior of the flash if set.
  • Bits 6/7 are set if the data transmitted is from a flash exposure lock measurement. This might signal that the actual flash may be fired later. (maybe: enables display of underexposure - flash-power > 128)

Byte 2 sets the output power of the flash. In FP mode it seems to specify the frequency of the flash bursts. The minimum value is 54d-75d, maximum is 201d

After the data has been send to the flash, the fixed CRC 0xD3 which is send by the flash (sic) follows. The flash is triggered by pulsing the X-Sync line low. There is no signal on the lines indicating that the flash has fired. These settings are only valid for all consecutive flashes, that is if you pulse X-Sync low a second time, the flash will fire again with the set power. Minimum time between consecutive flashes is about 15ms. This time can get as long as a few seconds depending on the recharge time of the flash capacitor. In FP mode the minimum time is about 30ms.

For the FP mode to work properly at least one preflash1 has to be fired first. Check whether needed only once!!


Checksum byte (last byte in frame)

For payload lengths greater than 3 bytes the very last byte in a frame is a checksum byte. It is calculated by summing all the bytes in the payload plus the seed given in "Table: Command Overview". The lowest eight bits of this sum are send as the checksum:

CRC = (SUM(payload)+seed)%256


Data that is not send

The following data is not send from the D700 to SB800:

  1. Status about the shutter release button
  2. VR on/off setting
  3. Focus limitation switch 
  4. AF/M setting

The flash does not send any data at all if it is in the mode "CLS-Remote"

Notes: Der SB900 is able to detect color filter and sends this data to the cam for white balance adjustment

Note to self: set flash to af-ill only (not to fire a flash) => Status bits??



This protocol is pretty weird: It is frame based, but the header of the frame does not show how many bytes are to be transferred. You have ho implement a lookup table for this. Although the communication is initiated by the camera the flash provides the clock for the synchronous data transmission. The clock frequency and the whole timing is agonizingly slow. So slow that during normal operations the bus is busy for about 80% of the time. In case you want to implement this protocol you will find that you will have to sacrifice about the full processing power for the transmission of just a few bytes. But anyway Nikon managed to successfully implement it. Hats off!



Data captured by my logic analyzer. The software to view the data is free for download and available at http://www.saleae.com/downloads/

wake_cameraSample communication: Wake up camera by half-pressing the shutter button; Initialization of the flash. D700 and SB800, 24mm lens, mode P, 1/30, f5.6
2.) Regular status communication: 0xA0 and 0xB0
3.) AF-ILL on and off
4.) Fire a flash: Preflash1, Preflash2, Flashpower, X-Sync, Postflash

Here you find the Nikon SB800 Repair manual

or if the above link is broken: Google for this string


Only registered users can write comments!

3.26 Copyright (C) 2008 Compojoom.com / Copyright (C) 2007 Alain Georgette / Copyright (C) 2006 Frantisek Hliva. All rights reserved."