Posts Tagged ‘xsi’

Canon ETTL protocol

March 19, 2009

This is a continuing story from and previous posts.

Good news!  I found out today that the drop of CLK to ground (after command message 0xb4 0x3d) before the “X” pin drops is exactly 4.00 msec.  This has been measured several times.  This is good as we now have a leading indicator when the flash is requested to do its job!   This is sufficient time for even wireless modes.  Of course I don’t really have the data of the shutter curtain positions relative to the “X” pin.

I’m working on a collective document that describes everything that I’ve found so far.  This would be easier for people to look at than these piece-meal postings.



Sniffing Canon’s ETTL protocol

March 18, 2009

This is a continuation of several posts that relate to my experiences sniffing the communication protocol between my Canon XSi camera and 580ex flash.  The previous posts are:

I have now achieved stability of results.  The messages between the camera and flash are now consistent from sample to sample.  The program had significant modifications from my starting program, but now it works.

Here is the program: ettl_program_1   This program requires some additional hardware support to perform the level shifting and logic threshold as described in my first post.

Here is a sample of the raw messages seen for some random settings of the camera and flash: putty log   After reduction (elimination of already seen messages) and some amount of analysis the ordered messages reduce to:

0xff – 0x8c 0x8c
zoom: 49 0xbd 0x00 0x31 0x99 0xff – 0xaa 0x59 0x00 0xff 0x8c
0xb5 0x4c – 0xcc 0x8c
camera mode: 0xb9 0x80 – 0x00 0x8c
zoom: 49 0xbd 0x00 0x31 – 0x18 0x69 0x46
0xfb 0xff – 0x02 0x8c
0xf9 0xff – 0x74 0x8c
0xb3 0x13 0x46 0x2f – 0x00 0x00 0x00 0x00
0xf5 0xff 0xff 0xff 0xff – 0x53 0x49 0x5c 0x0f 0x00
0xbe 0x20 – 0x8c 0x8c
ISO: 1600 – 0xbb 0x58 0xff 0xff – 0x00 0x00 0x8c 0x8c
0xf9 0xff – 0x55 0x8c
ISO: 1600 – 0xbb 0x58 0xff – 0x00 0x00 0x8c
Aperture: F/5.6 – 0xb7 0x30 – 0x8c 0x8c
Shutter: 1/60 – 0xb8 0x68 – 0x8c 0x8c
0xb4 0x1d – 0x8c 0x8c
0xb3 0x13 0x46 0x2f 0xff – 0x00 0x00 0x00 0x00 0x8c
0xb4 0x1d 0xff – 0x8c 0x8c 0x8c
0xf9 0xff – 0x75 0x8c
zoom: 49 0xbd 0x00 0x31 – 0x18 0x69 0x32
Shutter: 1/60 – 0xb8 0x68 0xff – 0x8c 0x8c 0x8c
0xb4 0x03 – 0x8c 0x8c
0xf2 0xff – 0xa0 0x8c
Set flash intensity: 0xa0 – 0xb0 0xa0 – 0x8c 0x8c
0xb1 0x04 – 0x8c 0x8c
0xb4 0x23 0xff – 0x8c 0x80 0x8c
0xb3 0x33 0x46 0x2f – 0x00 0x00 0x00 0x00
0xf8 0xff – 0x5e 0x8c
Set flash intensity: 0x63 – 0xb0 0x63 – 0x8c 0x8c
0xf2 0xff – 0xc0 0x8c
0xb3 0x37 0x46 0x2f – 0x00 0x00 0x00 0x00
0xb4 0x3d 0xff 0xff 0xff 0xff 0xff 0xff – 0x8c 0x63 0xaa 0x1a 0x09 0x86 0x06 0x8c
Aperture: unknown @ 0x00 – 0xb7 0x00 0xff – 0x8c 0x8c 0x8c
Shutter: 1/40 – 0xb8 0x63 – 0x8c 0x8c
0xb4 0x1d – 0x8c 0x8c

I’ve also spent some time analyzing when AF focus, preflash and actual flash events occur during these messages. 

Preflash message: 0xb4 0x23 0xff – 0x8c 0x80 0x8c     The preflash occurs between the 0x23 and 0xff bytes.  CLK drops to signal-ground (not actual camera ground) for about 83msec.  D2 pulses after the end of CLK.  The actual preflash itself is about 35msec after CLK drops.

Flash message: 0xb4 0x3d 0xff 0xff 0xff 0xff 0xff 0xff – 0x8c 0x63 0xaa 0x1a 0x09 0x86 0x06 0x8c  The flash occurs right after the 0x3d byte.  CLK drops all the way to camera ground.  The actual flash occurs after the “X” pin drops.

AF assists message: 0xb3 0x13 0x46 0x2f 0xff – 0x00 0x00 0x00 0x00 0x8c  The assist lamp happens right after the 0x2f byte of data.  I’m not quite sure yet whether it is just timed or if there is another pin interaction.

Now to look at changing different parameters of the camera and flash and see their effect on the messages.

Stay tuned…

Sniffing Canon’s ETTL protocol

March 16, 2009

I have been trying to stabilize the results I get from sniffing the protocol (  Unfortunately, I’m finding the different approaches I’ve tried all seem speed limited and miss data.  I believe I have to have repeatable results before I can deduce any new information about the ETTL protocol.  For instance, I’ve finding similar messages to those reported in, but I’m also finding several messages that are both different and new.  Unfortunately, the new messages seem to change data values from sample to sample, so that it hard to deduce a parameter change dependency or even if the message was correct to begin with. 

I suspect some of my problems have to do with how I sample the data itself.  I’ve gone to a complex scheme that uses alternating change-on-pin interrupts.  First looking for an interrupt on rise of D1 and then a series of interrupts on rises of CLK for each data bit.  This scheme only has one of the interrupts enabled at a time, where each interrupt ultimately enabling the other interrupt while disabling its own.  I’ve learned that I had to flush pending interrupts on the disabled interrupt input.  Since there is some amount of time between bytes, I’m going to try staying in a spin-loop upon the first CLK rising interrupt and look for all of the bits within that event.  I hope this will allow enough time to still output the prior data bytes before the interrupt sequence resumes.

Here’s an example snap-shot of the data seen with normal settings on both flash and camera.  This snap-shot is the result of post-processing the original data.  The messages are NOT in the order they appear between the camera/flash; they are sorted by numeric message value instead and redundant messages have been eliminated.  For some messages I have the probable message meaning per interpretation at  The syntax of the messages are the command bytes followed by the response bytes for that message.  Response bytes have already been deskewed and associated to the associated message.  New message shown in this sample is “0xbe”.  I have also seen messages with “0xfc”, “0xfd”, “0xfe”.  Messages that I’m confident with are the “0xb7” for Aperture setting, “0xb8” for shutter speed, “0xbb” for ISO setting and “0xbd” for zoom setting (but I don’t yet know what the other bytes of the zoom response mean).


0xb3 0x12 0x46 0x2f – 0x00 0x00 0x00 0x00
0xb3 0x13 0x46 0x2f – 0x00 0x00 0x00 0x00
0xb4 0x1d – 0x8c 0x8c
0xb5 0x4c – 0xcc 0x8c
Aperture: unknown @ 0x00 – 0xb7 0x00 – 0x8c 0x8c
Aperture: F/4 – 0xb7 0x28 – 0x8c 0x8c
Shutter: 1/60 – 0xb8 0x68 – 0x8c 0x8c
camera mode: 0xb9 0x80 – 0x00 0x8c
ISO: 1600 – 0xbb 0x58 0xff – 0x00 0x00 0x8c
zoom: 24 0xbd 0x00 0x18 – 0x18 0x69 0x18
zoom: 24 0xbd 0x00 0x18 – 0x18 0x69 0x1c
zoom: 24 0xbd 0x00 0x18 – 0x18 0x69 0x23
zoom: 24 0xbd 0x00 0x18 0x99 0xff – 0xaa 0x59 0x00 0xff 0x8c
0xbe 0x20 – 0x8c 0x8c
0xf5 0xff 0xff 0xff 0xff – 0x53 0x49 0x5c 0x0f 0x00
0xf9 0xff – 0x55 0x8c
0xf9 0xff – 0x75 0x8c
0xfb 0xff – 0x02 0x8c

Canon ETTL protocol continued

March 10, 2009

I’m getting back to this interface and looking more closely at the signaling between the XSi and 580ex flash.   This is a continuance of the post:

I realized that I needed to look at how the flash informs the camera that it exists and is turned on.


This picture shows “D1” from the camera (on top) and the leading edge of “CLK” from the camera (on bottom).  It looks like the flash informs the camera of its “on” status by pulsing high right after the clock goes high.  This particular pulse starts about 1.6usec after the clock and last for about 11usec.

The flash also seems to indicate a ready concept using D1 as shown in the following picture.  This is a capture of D1 (on top) and CLK (on bottom).  D1 seems to go high before the camera starts to clock some data.  D1 stays high until the clock drops and then, for this example, changes for the first bit of the clocked data (in this example the data bit is “0”.    This D1 high before the clock is likely the flash ready to receive flag to the camera.  This also means that if the last data bit, for the current clocked byte, is “1”, then D1 has to drop to “0” so that it can rise again as ready later.


The following picture shows a chain of clocked bytes from the flash (D1 on top, clock on bottom).  Notice that D1 always goes high before the first clock of a new byte and then changes to whatever is the value of the first bit after CLK 1st falls.  Notice also at the point marked with an “X”; this is a case where the last data bit is a “1” and D1 returns to zero and later returns to one to indicate ready for the next byte.


So, you can see that there is a handshake between the flash and camera.  The camera can’t send another byte of data until the flash indicates it is ready to receive it.

I found no similar characteristics on the camera’s data, D2.

The nature of gravity

March 2, 2009

Actually, I’m referring to things dropping and how long it takes for that thing to drop a certain distance.  If you use this information along with controlling a camera then you can capture things that are falling in a repeatable fashion.  For instance, a drop of water as it just hits a pool of water, or maybe just a little later when the water pool splashes back up after reacting to the water droplet.

The favorite equation used for this dropping behavior is

distance, acceleration and time

where “s” is the distance, “a” is the acceleration rate, and “t” is the amount of time.  This equation assumes the object starts at rest and t=0.  The acceleration “a” can be assumed constant with a value of approximately gravity constant

I was able to build a simple setup that allowed me to experiment with Arduino controlling a Laser, a light sensor, and a camera (Canon XSi).  The experiment performed the following steps:

1.   Turn on a laser and insure that the light sensor detected the laser

2.   Drop an object through the laser-sensor beam

3.   Upon sensing the laser-sensor beam broken, start a delay

4.   Once delay has finished, take a picture

5.   Turn off the laser

6.   Look at the picture to evaluate object’s dropped distance

7.   Repeat with different delay amounts

Ok, simple enough.  The problem I had was how to release the object repeatedly from a fixed position and as close to already breaking the laser-sensor beam as possible.  The object I chose was as ruler, permitting me to visually see the distance traveled. 


My object (ruler) release was simple – a nail that I pulled back that released the ruler.  I carefully positioned the ruler to just before breaking the light between the laser and sensor.  I then release, recorded what the camera saw and repeated. 

I also changed the amount of delay.  After I had several interesting data points, I plotted the results.  I recorded 6 different results for the same delay, plotting the average/min/max.  I also plotted a curve-fitted line to determine the least-square best fit for the modified equation (instead of “t”, I used “(t + y)”, where “y” is the unknown amount of camera delay).  From this particular experiment, I determined that “y” is about 106msec, which is for some reason, different from other experiments for the same camera.


Here is an example picture taken:


The arduino code is:

#define shutter_close PORTD |= _BV(2);
#define shutter_open PORTD &= ~_BV(2);

#define focus_on PORTD |= _BV(3);
#define focus_off PORTD &= ~_BV(3);

#define laser_on PORTD |= _BV(4);
#define laser_off PORTD &= ~_BV(4);

#define nolight (PINB & 1)  // digital pin #8
#define ledon PORTB |= _BV(1)
#define ledoff PORTB &= ~_BV(1)

void setup() {
  pinMode(2, OUTPUT);  // camera shutter
  pinMode(3, OUTPUT);  // focus control
  pinMode(4, OUTPUT);  // Laser control
  pinMode(8, INPUT);   // light input
  pinMode(9, OUTPUT);  // led indicator
unsigned long amt = 0;  // 0 = no extra delay … just the inherent delay

void get_delay() {
  unsigned long delay = 0;
  unsigned char len = 0;
  while(1) {
    while(!Serial.available());  // wait for first character
    unsigned char c =;
    if (c >= ‘0’ && c <= ‘9’) {
      delay = (delay * 10) + (c – ‘0’);  // add in digit
    } else {
      if (len == 0) {
        Serial.println(“Have to enter a delay”);
      } else {
        amt = delay;
        Serial.print(“new extra delay of “);

void loop() {
  while(1) {
    Serial.println(“Command? (D, T, A)”);
    while(!Serial.available());  // wait for command
    unsigned char c =;
    switch(c) {
      case ‘A’: case ‘a’:
        while(!Serial.available()) {
          if (nolight) ledon;
          else ledoff;
      case ‘T’: case ‘t’: {
        Serial.print(“Delay is camera + “);
        while(nolight);  // wait for laser and sensor together
        delay(1000);  // pre-focus
        while(nolight == 0);  // wait for light trigger

        // turn off laser
        // laser_off;
        delay(amt);  // time to shutter
        shutter_close;  // close the shutter
        ledon;  // flag progresst
        delay(200);  // delay some amount for the shutter/flash to work
        shutter_open; // release shutter
        ledoff; // flag progress
      } break;
      case ‘D’: case ‘d’:
      case ‘F’: case ‘f’:


Characterizing shutter curtain delay of Canon XSi

March 2, 2009
I wanted to know the delay from closing the shutter of my camera to when the actual picture is taken. With this information, then it becomes easier to setup various stop-motion picture captures.
For this experiment, I needed three things:
  • A way of controlling the Canon XSi camera
  • A bright enough LED with a short flash time while the camera was in total darkness
  • An accurate accounting for delay from control of camera to LED flash

The LED I used was a Luxeon I, which was controlled via a simple transistor driver (2N2222 + base resistor). The flash time for the LED was chosen to be only 1msec. To get an accurate delay I found I had to write my own delay routines. The delay routines provided by the Arduino library were not really adequate for my purpose.
My software hardware algorithm was simple. Have the arduino close the camera shutter, have it delay a predetermined (but user variable) amount, and flash the LED at a piece of paper, for which the camera was taking a picture. I then manually looked at the resulting picture to see the amount of light that was exposed in the picture. I recorded the results and changed the amount of delay and repeated. Because the LED flash time was only 1msec, I had to shoot with an ISO of 1600.
I did two different sets of pictures. The first picture set was just of an arbitrary piece of paper I had laying around. It had some garbage writing on it, but this was to determine if the setup worked ok. The shutter speed was set at 1/100. I approximated from these pictures the actual shutter speed at 1/100.6, which is within 0.6% of the camera’s setting. Also the delay begins at 84msec through 86msec depending upon the position in the camera’s sensor.
Notice how the sensor is opened from the bottom and the 2nd curtain also starts at the bottom (as it should).
The second set of pictures was of a sheet of paper that had printed on it lines labelled from 0 through 10. This ruling would permit me to better estimate the delay time to % position of the shutter open or closed. I carefully positioned the paper and camera zoom so that the “0” line was just at the bottom and the “10” line was just at the top of the camera’s sensor.
Here is an example of one of these shots.
Lastly, I used the perceived % opening/closing of shutter to plot the delay of the shutter. I posted these as two excel charts, the first for the shutter opening, the second for closing.      

my_flash program