79 thoughts on “Canon EF-S Protocol and Electronic Follow Focus

    • An application I was thinking of: 3D photography.
      - Link two identical camera’s (say, cheap second hand 350d’s with kitlenses), connecting both 2.5mm wired remote ports (they work simultanuously as input and output for the shutter, I once tried). maybe isolate focussing pin.
      - Use info in your post to clone focussing behavior of the first lens for the second.

      How would you say to connect the second lens? I thought:
      camera 1 -> lens 1
      fully connected
      camera 1 -> lens 2
      connect Dout and Dclk pins
      camera 2 -> lens 2
      fully connected, except Dout, Din and Dclk

      • The idea is good! Unfortunately, the camera polls the lens and waits for the ACKs (Dclk pulled down). I’m not sure there wouldn’t be a conflict problem with the two lenses pulling the Dclk line at the same time (or worse, with a delay).
        Plus, each lens is calibrated and this calibration data is sent to the camera while focusing* (something that doesn’t appear in my chart). This will mess the communication and/or focusing when the camera will receive different data for the same command.

        *How focusing works: The camera measures the focus it sees with its cross-sensor. Then asks for the calibration data of the lens and calculates the difference between the actual focus and the ideal one (using also the zoom and aperture params. sent by lens). This difference is used to determine how much the focusing ring must be stepped (once again, using the lens parameters received such as the focal length, the focusing lens displacement per motor step and so on..)
        Once the focus ring is turned to the calculated value, the camera starts again the whole process to get the focus more precise (starting with rough calculation and measure and ending up with precise one, kind of feedback process between the focus sensor and the focusing ring rotation). That’s also why you have a minimum-focusing-distance switch on some long lenses: the camera doesn’t need to iterate the focus too much, it already knows the lower focus boundary for the calculation.
        I summarized the process, but it’s basically how it works.

  1. Great work! I very like it! Did you open the source code of firmware? Very interesting to read it! May be you can send me to email?

    • Thx!
      Unfortunately, the code I wrote is very experimental, uncommented and messy (plus,in ASM), I think it would be easier and faster to re-write it yourself. And to use an other microcontroller, mine was too slow to act well as man-in-the-middle (sending answers to the camera of received commands while sending commands to the lens)

  2. Great info !

    Working on a similar idea, and have disasembled my 12mm extension tube to try to hook into the connections between the camera and the lens. The connections on my unit are made up by spring loaded contact pins. This does not easily lend itself to connect wiring to, thus what make is the lens extender of that you used – and how did you manage to connect to the interface pins ?

    /hans

    • Yes, it was tricky to connect wires to my extender. For the contacts on the camera side (not springy), I just forced them out of the extender, soldered wires (smallest diameter possible, like those for wrapping, but more flexible) and forced the small round contacts back in. Then, I made a small piece of plastic sheet that could fit into the adapter, shortened the small springs, soldered wires and glued them on the plastic sheet. It was a mess to put everything back together, especially to align the springs with the contacts from inside, on the lens side. I had to re-adjust the glued springs and use a small dentist mirror. But it worked after several tries. I had to drill into the extender too, to make room for the wires and to make an exit, so they didn’t break because of the extender assembly pressure.

  3. Hi Jean
    Good stuff. In need a little more data on the comms itself.
    1. Sounds like the CLK is made by the body for 8 pulses to send the command byte(s) into the lens, with data stable at rising edge. Are there gaps between the successive bytes ? I mean, do you have to insert a gap or anything or for 2 bytes do you just clock in 16-bits back-to-back ?
    2. You mentioned that the motor power from the body only activiates when commands are send ? How did you work around this ?

    • Yes, the camera sends and reads bits on the clock rising edge. After eight rising edges, it waits for the lens’s ack on the clock line. This ack is a pull-down and usually happens 17us after the last clk rising edge and lasts for 17us.
      This ack could also be a busy state sent by the lens to the camera (even if there’s also one or several bytes the lens uses to say it’s busy, but at the camera’s initiative (the camera is asking if the lens is busy))
      The lens cannot generate the clocking (at least, I never saw it).
      When the camera needs to send more than one byte, it sends the first one and the second (or third and so on), repeating all the eight edges, waiting for the ack, waiting for the ack’s end. (you don’t get 16 clock pulses in a row). The first answer form the lens is read by the camera while it is sending the second one.
      It’s a good idea to work at the bit-level, as the clk line has to be both an output and an input.

      I stopped working on the project when I realized that the erratic behaviour of my software was not because of bugs, but actually because the lens didn’t get the motor power from the camera (I didn’t have this pin on my connector on the lens extender)
      I tried to work around that for a while and gave up. I figured out it’s possible to send a reset signal to the camera by pulling the clk line down (if I remember well). Then, the camera sends an initialization sequence to the lens, also feeding the motor power. It might also be possible to tell the camera “I didn’t finish to move the focus ring” so it keeps the power on.
      But probably the easiest would be to provide the power (8V, I think) directly yourself through the extender.

      When the camera doesn’t get the answer it expects form the lens, it resets quite fast (and pulls the mirror down if it was up)

      Having an oscilloscope (or digital analyser) with a memory (a lot) will really save you some time.
      You can put small resistors (1k) in series with the data and clk lines to see which side (camera or lens) is pulling it up or down. That’s how I got the ack signal sent by the lens.
      Good luck!

  4. Wow, excellent. Just what I need. I’m trying to control the aperture on a Sigma zoom lens btw. Plan to use a small PIC or Tiny AVR to send commands just to the lens to allow manual stop-down.
    Digital supply is 5V ? And motor supply is 8V you reckon ?
    And one last thing…the clock is normally high by the sounds of it (mode 3 SPI) which I guess allows the pull-down ACK (bit of a dumb question really :) )

    • If you need to control just the lens, without it being attached to the camera, you’ll need to provide the digital and analog power (5V). The motor power (maybe 6V afterall) is only used for the focus. Aperture uses the regular 5V.
      All the digital lines are up on idle. Don’t forget the pull up resistors.

  5. Hi Jean

    Some progress, but a little odd. I am generating the clocks and data using a micro off a USB port. The lens is replying with the ACK as you said (17us delay but about 40us wide).
    I send 3 bytes with a delay for the ACK after each byte…I send 0×07 then 0×13 then an incrementing byte just for testing. I send LSBit first and have scoped the waveform to check its OK and timing is correct. But nothing is moving. The clock is coming out around 70KHz with the timing I have configured.
    I have digital and motor power both wired to USB 5V.

    So I wonder if the lens needs a reset or expects some sequence before it will honour the commands.
    I tried also the 05 and 06 commands. Nothing.

    Currently I dont read back the Dout line.
    The busy pulse seems too long…wonder if that means timeout ??

    • Here’s a dump of data between the camera and two lenses, when switching the camera on. Co: Camera out. data line, Lo: lens output.
      I forgot the camera sets its data line to ground when reading an answer from the lens (as you can see in the dump)
      Good luck!

      Sigma Canon
      Co Lo Co Lo
      —————
      00 08 FF FF
      0A 00 57 07
      00 AA 00 AA
      0A 00 0A 00
      00 AA 00 AA
      80 00 80 00
      0A 91 0A 91
      97 A9 97 A5
      01 00 01 00
      00 12 00 46
      00 00 00 00
      00 32 00 C8
      00 05 00 05
      00 00 00 00
      B0 00 B0 00
      00 20 00 20
      00 20 00 20
      A0 50 A0 58
      00 00 00 00
      E4 12 E4 49
      00 25 00 20
      00 1E 00 BD
      90 00 90 00
      00 00 00 00
      00 80 00 00
      0C 00 0C 00
      0E 0C FF FF
      0F 0E 0F 0C
      0A 0F 0A 0F
      00 AA 00 AA
      B0 00 B0 00
      00 20 00 20
      00 20 00 20
      A0 50 A0 58
      00 00 00 00
      E4 12 E4 49
      00 25 00 20
      B2 1E B2 BD
      00 68 00 77
      00 00 00 01
      C4 13 C4 13
      00 07 00 16
      C2 00 C2 10
      00 00 00 01
      00 1E 00 08
      00 00 00 00
      00 1C 00 C2
      90 00 90 00
      00 00 00 00
      00 80 00 00
      0A 00 0A 00
      00 AA 00 AA
      B0 00 B0 00
      00 20 00 20
      00 20 00 20
      A0 50 A0 58
      00 00 00 00
      E4 12 E4 49
      00 25 00 20
      B2 1E B2 BD
      00 68 00 77
      00 00 00 01
      C4 13 C4 13
      00 07 00 16
      C2 00 C2 10
      00 00 00 01
      00 1E 00 08
      00 00 00 00
      00 1C 00 C2
      C0 00 C0 00
      00 00 FF FF
      00 00 00 00
      90 00 00 00
      00 00 90 00
      00 80 00 00
      07 00 00 00
      0E 07 07 00
      0F 0E 0F 07
      0A 0F 0A 0F
      00 AA 00 AA
      B0 00 B0 00
      00 20 00 20
      00 20 00 20
      A0 50 A0 58
      00 00 00 00
      E4 12 E4 49
      00 25 00 20
      B2 1E B2 BD
      00 68 00 77
      00 00 00 01
      C4 13 C4 13
      00 07 00 16
      C2 00 C2 10
      00 00 00 01
      00 1E 00 08
      00 00 00 00
      00 1C 00 C2
      90 00 C4 00
      00 00 00 16
      00 80 B0 10
      0A 00 00 20
      00 AA 00 20
      B0 00 00 58
      00 20 F8 00
      00 20 FF FF
      A0 50 03 2B
      00 00 90 00
      E4 12 00 00
      00 25 00 00
      B2 1E 0A 00
      00 68 00 AA
      00 00 B0 00
      C4 13 00 20
      00 07 00 20
      C2 00 A0 58
      00 00 00 00
      00 1E E4 49
      00 00 00 20
      00 1C B2 BD
      90 00 00 77
      00 00 00 01
      00 80 C4 13
      0A 00 00 16
      00 AA C2 10
      B0 00 00 01
      00 20 00 08
      00 20 00 00
      A0 50 00 C2
      00 00 C4 00
      E4 12 00 16
      00 25 B0 10
      B2 1E 00 20
      00 68 00 20
      00 00 00 58
      C4 13 F8 00
      00 07 FF FF
      C2 00 07 03
      00 00 90 00
      00 1E 00 00
      00 00 00 00
      00 1C 0A 00
      90 00 00 AA
      00 00 B0 00
      00 80 00 20
      0A 00 00 20
      00 AA A0 58
      B0 00 00 00
      00 20 E4 49
      00 20 00 20
      A0 50 B2 BD
      00 00 00 77
      E4 12 00 01
      00 25 C4 13
      B2 1E 00 16
      00 68 C2 10
      00 00 00 01
      C4 13 00 08
      00 07 00 00
      C2 00 00 C2
      00 00 C4 00
      00 1E 00 16
      00 00 B0 10
      00 1C 00 20
      90 00 00 20
      00 00 00 58
      00 80 F8 00
      0A 00 FF FF
      00 AA 03 2B
      B0 00 90 00
      00 20 00 00
      00 20 00 00
      A0 50 0A 00
      00 00 00 AA
      E4 12 B0 00
      00 25 00 20
      B2 1E 00 20
      00 68 A0 58
      00 00 00 00
      C4 13 E4 49
      00 07 00 20
      C2 00 B2 BD
      00 00 00 77
      00 1E 00 01
      00 00 C4 13
      00 1C 00 16
      90 00 C2 10
      00 00 00 01
      00 80 00 08
      0A 00 00 00
      00 AA 00 C2
      B0 00 C4 00
      00 20 00 16
      00 20 B0 10
      A0 50 00 20
      00 00 00 20
      E4 12 00 58
      00 25 F8 00
      B2 1E FF FF
      00 68 07 03
      00 00 90 00
      C4 13 00 00
      00 07 00 00
      C2 00 0A 00
      00 00 00 AA
      00 1E B0 00
      00 00 00 20
      00 1C 00 20
      90 00 A0 58
      00 00 00 00
      00 80 E4 49
      0A 00 00 20
      00 AA B2 BD
      B0 00 00 77
      00 20 00 01
      00 20 C4 13
      A0 50 00 16
      00 00 C2 10
      E4 12 00 01
      00 25 00 08
      B2 1E 00 00
      00 68 00 C2
      00 00 C4 00
      C4 13 00 16
      00 07 B0 10
      C2 00 00 20
      00 00 00 20
      00 1E 00 58
      00 00 F8 00
      00 1C FF FF
      90 00 03 2B
      00 00 90 00
      00 80 00 00
      0A 00 00 00
      00 AA 0A 00
      B0 00 00 AA
      00 20 B0 00
      00 20 00 20
      A0 50 00 20
      00 00 A0 58
      E4 12 00 00
      00 25 E4 49
      B2 1E 00 20
      00 68 B2 BD
      00 00 00 77
      C4 13 00 01
      00 07 C4 13
      C2 00 00 16
      00 00 C2 10
      00 1E 00 01
      00 00 00 08
      00 1C 00 00
      90 00 00 C2
      00 00 C4 00
      00 80 00 16
      0A 00 B0 10
      00 AA 00 20
      B0 00 00 20
      00 20 00 58
      00 20 F8 00
      A0 50 FF FF
      00 00 07 03
      E4 12 90 00
      00 25 00 00
      B2 1E 00 00
      00 68 0A 00
      00 00 00 AA
      C4 13 B0 00
      00 07 00 20
      C2 00 00 20
      00 00 A0 58
      00 1E 00 00
      00 00 E4 49
      00 1C 00 20
      90 00 B2 BD
      00 00 00 77
      00 80 00 01
      0A 00 C4 13
      00 AA 00 16
      B0 00 C2 10
      00 20 00 01
      00 20 00 08
      A0 50 00 00
      00 00 00 C2
      E4 12 C4 00
      00 25 00 16
      B2 1E B0 10
      00 68 00 20
      00 00 00 20
      C4 13 00 58
      00 07 F8 00
      C2 00 FF FF
      00 00 03 2B
      00 1E 90 00
      00 00 00 00
      00 1C 00 00
      90 00 0A 00
      00 00 00 AA
      00 80 B0 00
      0A 00 00 20
      00 AA 00 20
      B0 00 A0 58
      00 20 00 00
      00 20 E4 49
      A0 50 00 20
      00 00 B2 BD
      E4 12 00 77
      00 25 00 01
      B2 1E C4 13
      00 68 00 16
      00 00 C2 10
      C4 13 00 01
      00 07 00 08
      C2 00 00 00
      00 00 00 C2
      00 1E C4 00
      00 00 00 16
      00 1C B0 10
      90 00 00 20
      00 00 00 20
      00 80 00 58
      0A 00 F8 00
      00 AA FF FF
      B0 00 03 2B
      00 20 90 00
      00 20 00 00
      A0 50 00 00
      00 00 0A 00
      E4 12 00 AA
      00 25 B0 00
      B2 1E 00 20
      00 68 00 20
      00 00 A0 58
      C4 13 00 00
      00 07 E4 49
      C2 00 00 20
      00 00 B2 BD
      00 1E 00 77
      00 00 00 01
      00 1C C4 13
      90 00 00 16
      00 00 C2 10
      00 80 00 01
      0A 00 00 08
      00 AA 00 00
      B0 00 00 C2
      00 20 C4 00
      00 20 00 16
      A0 50 B0 10
      00 00 00 20
      E4 12 00 20
      00 25 00 58
      B2 1E F8 00
      00 68 FF FF
      00 00 07 03
      C4 13 90 00
      00 07 00 00
      C2 00 00 00
      00 00 0A 00
      00 1E 00 AA
      00 00 B0 00
      00 1C 00 20
      90 00 00 20
      00 00 A0 58
      00 80 00 00
      0A 00 E4 49
      00 AA 00 20
      B0 00 B2 BD
      00 20 00 77
      00 20 00 01
      A0 50 C4 13
      00 00 00 16
      E4 12 C2 10
      00 25 00 01
      B2 1E 00 08
      00 68 00 00
      00 00 00 C2
      C4 13 C4 00
      00 07 00 16
      C2 00 B0 10
      00 00 00 20
      00 1E 00 20
      00 00 00 58
      00 1C F8 00
      90 00 FF FF
      00 00 07 03
      00 80 90 00
      0A 00 00 00
      00 AA 00 00
      B0 00 0A 00
      00 20 00 AA
      00 20 B0 00
      A0 50 00 20
      00 00 00 20
      E4 12 A0 58
      00 25 00 00
      B2 1E E4 49
      00 68 00 20
      00 00 B2 BD
      C4 13 00 77
      00 07 00 01
      C2 00 C4 13
      00 00 00 16
      00 1E C2 10
      00 00 00 01
      00 1C 00 08
      90 00 00 00
      00 00 00 C2
      00 80 C4 00
      0A 00 00 16
      00 AA B0 10
      B0 00 00 20
      00 20 00 20
      00 20 00 58
      A0 50 F8 00
      00 00 FF FF
      E4 12 03 2B
      00 25 90 00
      B2 1E 00 00
      00 68 00 00
      00 00 0A 00
      C4 13 00 AA
      00 07 B0 00
      C2 00 00 20
      00 00 00 20
      00 1E A0 58
      00 00 00 00
      00 1C E4 49
      90 00 00 20
      00 00 B2 BD
      00 80 00 77
      0A 00 00 01
      00 AA C4 13
      B0 00 00 16
      00 20 C2 10
      00 20 00 01
      A0 50 00 08
      00 00 00 00
      E4 12 00 C2
      00 25 C4 00
      B2 1E 00 16
      00 68 B0 10
      00 00 00 20
      C4 13 00 20
      00 07 00 58
      C2 00 F8 00
      00 00 FF FF
      00 1E 07 03
      00 00 90 00
      00 1C 00 00
      90 00 00 00
      00 00 0A 00
      00 80 00 AA
      0A 00 B0 00
      00 AA 00 20
      B0 00 00 20
      00 20 A0 58
      00 20 00 00
      A0 50 E4 49
      00 00 00 20
      E4 12 B2 BD
      00 25 00 77
      B2 1E 00 01
      00 68 C4 13
      00 00 00 16
      C4 13 C2 10
      00 07 00 01
      C2 00 00 08
      00 00 00 00
      00 1E 00 C2
      00 00 C4 00
      00 1C 00 16
      90 00 B0 10
      00 00 00 20
      00 80 00 20
      0A 00 00 58
      00 AA F8 00
      B0 00 FF FF
      00 20 03 2B
      00 20 90 00
      A0 50 00 00
      00 00 00 00
      E4 12 0A 00
      00 25 00 AA
      B2 1E B0 00
      00 68 00 20
      00 00 00 20
      C4 13 A0 58
      00 07 00 00
      C2 00 E4 49
      00 00 00 20
      00 1E B2 BD
      00 00 00 77
      00 1C 00 01
      90 00 C4 13
      00 00 00 16
      00 80 C2 10
      0A 00 00 01
      00 AA 00 08
      B0 00 00 00
      00 20 00 C2
      00 20 C4 00
      A0 50 00 16

      • I just found this amazing blog and would like to post the following question that has to do with the use of old manual lenses on digital DSLR . Specifically the new Sigma SD1 .

        This digital camera , latest model from Sigma Japan, incorporated some new abilities over the previous models , such as Tethered control that are obviously lens dependent so the camera seems to be always polling for lens id and any attempt to use manual lenses that do not report back their id , create problems with the generation of a JPG for LCD Display . The RAW capture remains unaltered .

        This might be a bug of the Firmware that does not have an exit strategy for when there is no lens attached ( A non electronic lens is essentially invisible to the camera )

        Since for most people the LCD display and its Histogram are very important to achieve good Imagery I am trying to find a way to fool the camera into thinking that a lens is still attached .

        The previous models did not have this problem and the last lens ID and data was retained in non volatile camera memory. The new model does retain id and data of the last electronic lens that was mounted if swapped by a manual lens but it will loose it on shutdown .

        Any ideas to create persistence of the lens id ? I would not dare tinker with enigmatic Firmware code. My thinking is around the possibility of pulling some camera pins low or high , to tell the camera that the lens is busy doing something .Do you think that this might work?

        There are many Chinese lens adapters for Canon EF mount that incorporate a chip that apparently responds to the camera in some fashion to re-enable the AUTO FOCUS ASSISTANCE viewfinder LED light and Beep , that is lost when a non responding lens is mounted, forcing the camera into Manual Mode.

        Do you or anybody know how those chipped lens adapters work to make the camera focus assistance work? A similar concept might be derived from there to create a “Virtual lens”

        If I can understand how those chips work maybe I can use them in the Sigma SA bus that is very similar to Canon EF

  6. Hi Jean
    Many thanks for your willingness to share !
    I’m part of a little team that tries to lure some of the secrets out of the Canon AF system, with the goal of understanding as much as possible of how it works especially in terms of not published limitations. Amongst our methods are devising a variety of tests under repeatable conditions, observing the lens and body behavior. Certain aspects of the observed behavior however necessitate a look at the communication between the body and lens, to be fully understood. Thus, my interest is academic only, and I’m absolutely determined to share my findings if anyone is interested.

    As it will take me a little while to build my adaptor, I hope you don’t mind me asking for some additional dumps like the recently published, including lens focus action communication ($44xx, $05xx and $06xx) that you would possibly share (preferably from Canon lenses, with indication of the type)?

    Does the protocol, to your knowledge, include an “drive speed”- command?

    As I will also need an “observation platform” to interpret the communication, I was thinking along the lines of purchasing a demo/evaluation board for a PIC or a AVR microprocessor (I have the scope/analyzer stuff). You previously mentioned that the PIC model you used was not fast enough for acting as an “in between”. Did this limitation originate in your coding, or the command cycle time for the processor – it seems to be pretty fast? (IOWs do you have a recommendation for a suitable platform?)

    Best Regards
    Hans (hpjfromdk)

    PS: If you do not want to waste blog space or for other reasons do not want to post these dumps on your blog, you are more than welcome to mail them to me.

    • Hi!

      If by “drive speed” you mean the speed of the focus motor, yes, there’s a command changing the motor speed (0×50) but I don’t know how it works or what its exact purpose is (one of the lens’ performance is based on the focus speed, the faster the better and the more expensive, so why slow it down?)
      But you can slow the motor down by sending small step commands a lot of times, instead of just one big step (I tried, it works)

      My PIC was running at 40Mhz, which made 10 ASM instructions per microseconds. The clock’s half period is 6us. Ok, that’s 60 instructions, maybe I could have optimized my code, but still, I felt like it wasn’t much (especially if you have a lot of jumps or calls). I think the best solution would be to use a small and fast FPGA, as you have to read the instructions, memorize them and replace them with your own ones (to command the lens and answer to the camera at the same time)
      As for the PIC vs. AVR, I think there’s not a big difference, just take the platform you feel most comfortable with, especially if you just want to read the commands on the data lines.
      I’ll send you the dumps I have but be careful, they are byte-oriented, so you only see the line data, not line status behaviour (like pulling a line down or up for init or busy states)
      The ultimate way (but the longest too) to see every aspect of the communication is to observe and record it with an oscilloscope.

    • Hi Hans . I am very interested in your findings about the Canon EF mount.

      I have posted a question in different places in this blog but since there were no replies I am asking individually now.

      Basically my questions have to do with the use of old manual lenses on digital DSLR . Specifically the new Sigma SD1 DSLR.

      This digital camera , latest model from Sigma Japan, incorporated some new abilities over the previous Sigma models , such as Tethered control , that are obviously lens dependent so the camera seems to be always polling for lens id and any attempt to use manual lenses that do not report back their id , create problems with the generation of a JPG for LCD Display . The RAW capture remains unaltered .

      This might be a bug of the Firmware that does not have an exit strategy for when there is no lens attached ( A non electronic lens is essentially invisible to the camera )

      Since for most people the LCD display and its Histogram are very important to achieve good Imagery I am trying to find a way to fool the camera into thinking that a lens is still attached .

      The previous models did not have this problem and the last lens ID and data were retained in non volatile camera memory. The new model does temporarily retain id and data of the last electronic lens that was mounted if HOT swapped by a manual lens but it will loose it on shutdown .

      Any ideas to create persistence of the lens id ? I would not dare tinker with enigmatic Firmware code. My thinking is around the possibility of pulling some camera pins low or high , to tell the camera that the lens is busy doing something .Do you think that this might work?

      There are many Chinese lens adapters for Canon EF mount that incorporate a chip that apparently responds to the camera in some fashion to re-enable the AUTO FOCUS ASSISTANCE viewfinder LED light and Beep , that were lost when a non responding lens was mounted, forcing the camera into Manual Mode.

      Do you or anybody know how those chipped lens adapters work to make the camera focus assistance work? A similar concept might be derived from there to create a “Virtual lens” for my Sigma camera based on the similarity of the communication bus (SPI)

      If I can understand how those chips work maybe I can use them in the Sigma SA bus that is very similar to Canon EF

  7. Thanks Jean !

    One of my contributions to team effort is that I spent more than 3 years now reading up on Canons patents within this area.

    By “drive speed” – yes – I meant the speed of the focus lens-group motor.

    A number of patents detail that in case of large defocus, the lens will initially be accelerated to and driven at “high speed” performing repetitive defocus assessments until within a certain distance of the expected target. The remaining distance will be updated for each assessment, thereby incrementally reducing the drive calculation errors caused by mfg. tolerances, optical aberrations and the nonlinear relation between defocus amount, lens position and focal length. Once within said range the speed will be decelerated to a level that is safe for “touch down”.

    The motor speed both affects the stopping (breaking) range and the accuracy of the defocus measurement, as the SIR images on the AF sensor are blurred by the lens motion..

    If you have knowledge about other command codes, without currently knowing the exact working, and you don’t mind, please post these also. Maybe through a joint effort from those subscribing to this blog project, we can create a much more comprehensive table of commands.

    br/hans

  8. Hi Jean
    Quick update. Comms is still evading me! The 8 clocks always cause a nice ACK from the lens. I have connected both power supplies to 5V (just in case) and I try clocking data in (I have scoped the data to make sure its correct and even tried bit-reversing in case it was MSBit first…still nothing). Doesn’t matter what I send, nothing actually happens except the ACK. Even tried the sequence you posted above. Interestingly, the DLC (lens to camera data) *never* does anything. In fact, its a floating output. But it definately must be connected to something because if I touch with my finger to induce 50Hz, and measure with the scope probe, the normal large 50Hz waveform clips at about 5V top when I touch the scope probe to the lens pin and touch with my finger at the same time. So it must have an internal connection in there. I tried a pull up. It just sits high.
    I’m thinking there must be some init sequence to cause the lens to wake up/reset. Wonder if DCLK is held low for some period after power up ?
    I dont have a canon body to test with so I’m running blind here.
    That’s where I’m at.

    • I don’t think the init sequence is *so* important for the lens. As far as I remember, it was quite tolerant about the commands I was sending (it was the opposite with the camera).

      The data out from the lens should be pulled up.
      One thing to try (I think it might be the solution): For every command received, the lens answers. If it can’t answer, it probably ignores the command. And the lens can’t generate clocks, so it’s waiting for clocks from the camera until buffer full or timeout.

      What you can do is to add as many clock patterns (8 bits) as you’re expecting answers from the lens.
      If it still doesn’t work, try doing that, plus pulling low the camera data line during the clk patterns for lens’ answers. Third solution: the two above, plus when you send data with the camera data line, pull down the lens data line.
      It all fails, I’ll try to come up with a better answer ;-)

  9. Finally some progress :)
    Got desperate and looped, writing command 1, 2 ,3 etc . Suddenly the focus ring moves and DLC starts outputting real data. Looked like the values were up at around 0×60 ish. Odd.

    It is LSBit first isnt it ?

    So now have to figure what triggered the thing to wake up.

    • Cool!
      When you read the bits on an oscilloscope, the LSB is on the right. So yes, the first clock pulse you send will define the LSB. –>LSB first. (or at least, that’s how I was reading it and how my dumps are written)
      Try to send $06 00 or $05 00, it’s supposed to move the focus to max or min. Also, $0A 00 seems to be one of the first commands sent by the camera after a power up.
      Now I remember I could see a very short low pulse on the clk line (something like 1/10 of a regular clock half period) right after the power up, but I doubt it acts like a reset.

      • Right side of scope is last bit sent, so MSB surely…

        I’ll try the 05 and 06 commands. Did that quickly yesterday but…forgot the following 00 so that may have been the problem.

        Thanks for all the help.

  10. Sorted!
    Problem was the comms really is MSB first. So command B0 for example sends 10110000 on clocks 0 to 7, 0 being the first clock. I also had a silly start up condition that set clock low, then high…so I was also one clock out. Data coming out of lens is also MSB first. That’s why I was getting such odd results…all my commands were bit reversed. Took a bit of messing to figure it out.
    Now can move focus, aperture, get responses, etc etc.
    OK, now to try and get proper control of aperture steps :)

  11. All done.
    Made an adapter for my Samsung NX. EStoNX adapter picks up 5V from camera body and uses an Atmel Tiny44 (overkill) to generate the right SPI codes when I push one of 4 buttons in the adapter: Focus+ Focus- Aperture+ Aperture-.

    Couple of things:

    1. The Busy poll command 0x0A seems to be essential to get things started
    2. The aperture open/close command is simple 1′s complement so 0×07:13:01 for open by one, 0×07:13:FF to close one.
    3. The focus took a bit of figuring out. Finally got it. The 2 bytes carry a 1′s compliment offset shifted up by one bit and then the last bit (LSBit) seems to need to be set to do incremental steps. So 0×44:00:03 will do a single step one way, 0×44:FF:FD will do one step back. In the code, I used a step of 2 because a single step is tiny. I also build in a direction change detect so I could take out the focus backlash by just doing a fixed number of steps
    4. Pushing both focus buttons does a big step, both aperture buttons opens fully.
    5. Note the DCLK pull down by host is catered for by tri-stating with a pull up just after 8th clock.
    6. Harwin do some very useful 2 pin SMT contact blocks with gold plated round-ended spring probes that can be pushed out of their plastic body and mounted to connect to the lens contact pads.

    Code below (not optimized or the nicest but it all works and I’ve taken pics).
    Note that I connect by power pins on the lens (a Sigma 135 to 400mm APO zoom lens)

    Right…on to next project :)

    *******************

    #include
    #include

    typedef unsigned char uint8_t;

    #define FOCUSupR PINA0
    #define FOCUSdnR PINA1
    #define APERTUREdnR PINA2
    #define APERTUREupR PINA3

    #define DCL PINB0
    #define DLC PINB1
    #define DCLK PINB2

    #define PUSHEDFOCUSnone 0
    #define PUSHEDFOCUSdn 1
    #define PUSHEDFOCUSup 2
    #define PUSHEDFOCUSdnup 3

    //————————————————-

    uint8_t SendCommand(uint8_t dout)
    {
    uint8_t clk;
    uint8_t din;

    din=0;

    for(clk=0;clk<=7;clk++)
    {
    din <<=1;

    PORTB = (0×01 << DLC) | (0×00 << DCLK) | (((dout & 0×80) ? 1 : 0) << DCL); //NB: keep pull up on DLC
    _delay_us(20);
    PORTB = (0×01 << DLC) | (0×01 << DCLK) | (((dout & 0×80) ? 1 : 0) << DCL);
    if (clk == 7) DDRB = (1 << DCL) | (0 << DCLK); //tri-state DCLK ready for ack after 8th clk rising edge
    _delay_us(20);
    din |= (PINB & (1 << DLC)) ? 0×01 : 0;

    dout <<= 1;
    }
    _delay_us(200);
    DDRB = (1 << DCL) | (1 << DCLK); //un tri-state DCLK after ack
    return(din);
    }

    //————————————————-

    int main(void)
    {
    uint8_t keystates;
    uint8_t lastfocuspush;
    uint8_t focusct;

    lastfocuspush = PUSHEDFOCUSnone; //when we start, no idea which way backlash will run!

    PORTA = 0xFF; //force pull ups for all inputs and set all outputs high
    PORTB = 0xFF; //ditto. Note that DCLK is treated as open drain. Take care to keep pull up on DCL by writing a 1 during serial output
    DDRA = 0×00; //all inputs for push buttons
    DDRB = (1 << DCL) | (1 << DCLK); //configure both outputs for now

    _delay_ms(1000); //stabilize after power up
    SendCommand(0x0A); //this is essential…seems to kick start comms. Busy poll

    //first, ask for lens data
    SendCommand(0×97);
    SendCommand(0×01);
    SendCommand(0×00);
    SendCommand(0×00);
    SendCommand(0×00);
    SendCommand(0×00);
    SendCommand(0×00);

    //then, ask for aperture data
    SendCommand(0xB0);
    SendCommand(0×00);
    SendCommand(0×00);

    //then, fully open the aperture
    SendCommand(0×13);
    SendCommand(0×80);
    _delay_ms(200);

    //now, focus ring to max
    //SendCommand(0×06);
    //_delay_ms(200);

    while(1)
    {
    keystates = PINA & 0x0F;

    //aperture
    if ((keystates & ((1 << APERTUREdnR) | (1 << APERTUREupR))) == 0) //both pushed ?
    {
    SendCommand(0×13);
    SendCommand(0×80);
    }
    else if ((keystates & (1 << APERTUREdnR)) == 0)
    {
    SendCommand(0×07);
    SendCommand(0×13);
    SendCommand(0xFF); //one back (-1)
    }
    else if ((keystates & (1 << APERTUREupR)) == 0)
    {
    SendCommand(0×07);
    SendCommand(0×13);
    SendCommand(0×01); //one step forward
    }
    //focus. 1's compliment BUT last bit sent is a flag to say relative step if set
    else if ((keystates & ((1 << FOCUSdnR) | (1 << FOCUSupR))) == 0) //both pushed ?
    {
    SendCommand(0×44);
    SendCommand(0x0F);
    SendCommand(0xFF);
    _delay_ms(300);
    SendCommand(0×44);
    SendCommand(0×00);
    SendCommand(((0×02 << 1) ^ 0×00) | 0×01);

    //SendCommand(((0×10 << 1) ^ 0×00) | 0×01);
    lastfocuspush = PUSHEDFOCUSdnup;
    }
    else if ((keystates & (1 << FOCUSdnR)) == 0)
    {
    if (lastfocuspush != PUSHEDFOCUSdn)
    {
    lastfocuspush = PUSHEDFOCUSdn;
    focusct = 6;
    }
    else
    focusct = 1;

    while (focusct–)
    {
    SendCommand(0×44);
    SendCommand(0xFF);
    SendCommand(((0×02 << 1) ^ 0xFF) | 0×01);
    if (focusct) _delay_ms(100);
    }
    }
    else if ((keystates & (1 << FOCUSupR)) == 0)
    {
    if (lastfocuspush != PUSHEDFOCUSup)
    {
    lastfocuspush = PUSHEDFOCUSup;
    focusct = 6;
    }
    else
    focusct = 1;

    while (focusct–)
    {
    SendCommand(0×44);
    SendCommand(0×00);
    SendCommand(((0×02 << 1) ^ 0×00) | 0×01);
    if (focusct) _delay_ms(100);
    }
    }

    if (keystates != 0x0F) //any of them pushed ?
    {
    DDRA = 0x0F; //all outputs to re-charge filter caps for push buttons…there are 1Ks in series to buttons so no contention
    _delay_ms(300);
    DDRA = 0×00; //all inputs for push buttons
    }

    }
    }

    • Great work Peter !

      I am very interested in your findings about the Canon EF mount.

      I have posted a question in different places in this blog but since there were no replies I am asking individually now.

      Basically my questions have to do with the use of old manual lenses on digital DSLR . Specifically the new Sigma SD1 DSLR.

      This digital camera , latest model from Sigma Japan, incorporated some new abilities over the previous Sigma models , such as Tethered control , that are obviously lens dependent so the camera seems to be always polling for lens id and any attempt to use manual lenses that do not report back their id , create problems with the generation of a JPG for LCD Display . The RAW capture remains unaltered .

      This might be a bug of the Firmware that does not have an exit strategy for when there is no lens attached ( A non electronic lens is essentially invisible to the camera )

      Since for most people the LCD display and its Histogram are very important to achieve good Imagery I am trying to find a way to fool the camera into thinking that a lens is still attached .

      The previous models did not have this problem and the last lens ID and data were retained in non volatile camera memory. The new model does temporarily retain id and data of the last electronic lens that was mounted if HOT swapped by a manual lens but it will loose it on shutdown .

      Any ideas to create persistence of the lens id ? I would not dare tinker with enigmatic Firmware code. My thinking is around the possibility of pulling some camera pins low or high , to tell the camera that the lens is busy doing something .Do you think that this might work?

      There are many Chinese lens adapters for Canon EF mount that incorporate a chip that apparently responds to the camera in some fashion to re-enable the AUTO FOCUS ASSISTANCE viewfinder LED light and Beep , that were lost when a non responding lens was mounted, forcing the camera into Manual Mode.

      Do you or anybody know how those chipped lens adapters work to make the camera focus assistance work? A similar concept might be derived from there to create a “Virtual lens” for my Sigma camera based on the similarity of the communication bus (SPI)

      If I can understand how those chips work maybe I can use them in the Sigma SA bus that is very similar to Canon EF

      Thanks.

  12. Congrats and thanks for sharing Peter !

    I’m a bit curious to a couple of details that I would assume you might have taken note of during your work on the project.

    Here’s the startup log from my 30D with an EF70-300IS attached

    Co Lo
    01: 00 FF
    02: 0A AA
    03: 00 AA
    04: 0A 00
    05: 00 AA
    06: 80 00
    07: 0A 9C
    08: 97 EE EE= Canon EF 70-300mm f/4-5.6 IS USM
    09: 01 00
    10: 00 46 0046 = 70mm
    11: 00 01
    12: 00 2C 012C = 300mm
    13: 00 75
    14: 00 1A

    If you have a similar log, would you mind share the following Lo byte # from your tests:

    07: The answer to the 80 0A sequence or perhaps just (80), which maybe somehow also to relate to lens capabilities

    08: Lens ID ??
    13: Lens protocol info ??
    14: lens capabilities ??

    Also did you use a Canon body during your work if so, what was the sequence in Co bytes # 6, 7, 8 and 9 – more specifically 08: = 0×97 is used by the 30D…

    /hans

  13. Hi
    You guys are so great posting all this info in such detail.
    I have a fairly simple (possibly stupid) question:
    Can the USB port on the Canon DSLR report what focal distance it is currently focusing on?
    So that for example you could have an external device with a digital readout that says how many feet away the camera is currently focusing.
    eg. it may report that the camera is focusing at exactly 8 feet.
    Then, of example, you could press a button on your external device to “refocus at 7 feet distance instead”
    Are there commercial devices that already extract this focal distance data from the USB port of the camera?
    Sorry for my ignorance.
    Cheers
    Mark

  14. Researching a bit I found this:
    http://www.okii.net/Articles.asp?ID=238
    Which seems to indicate that there is a bit on an art to determining what distance the camera is currently focusing at.
    Not sure if I understand the limitations fully though.
    Sounds like you go out of calibration if the user does manual focusing or if you dial to infinity and back.
    I am really hoping there is a way that the camera can report the distance it is currently focusing at. Or at least you could manyally calibrate it (eg by focusing on something 1 meter away and hitting a “calibrate” button) then not loose calibration after that.

  15. I just did a bit more searching and partly answered my question.
    I found this site that reports the focus distance reported by different lenses:
    This site shows a breakdown of the data reported by different lenses.
    http://magiclantern.wikia.com/wiki/Focus_distance
    Now I am wondering if you could make a device that improves on this by calibrating the lens yourself.
    eg. the first thing you do is focus on objects at specific distances to build a profile for the lens. Once you have this look up table, could you simply calibrate one time (on something 1 meter away) and let your software work out the rest based on the delta that it records while filming a video?

    It would be great to work out a way to fill out this table and share calibration data with other users for every lens, so that you could get a readour of the distance that the lens is focusing at.
    Is that goal pie in the sky?
    I am not sure because my understanding of the system is very limited.

  16. Hi
    In your description you explain what you did to accommodate different lenses:

    “…..Then, I implemented a small function that allowed me to turn the focus ring using a digital encoder. … I had to increase the number of steps of the focusing ring for each of the encoder’s steps. That’s where the problems started to appear. The only solution I could come up with was to calibrate each lens at power-up by making it go across the full range of focus, counting the steps so I could use this number in my firmware…..”

    Is this startup procedure something that could be run by sending commands via the USB input? Or was that something you could only do because you attached directly to your lens extender.

    Please forgive my ignorance- I am not experienced in what control is possible via USB.

    • Hi!

      I was talking about the calibration of the number of focusing ring motor steps (how many steps from 0 to infinite focus), to be able to know when the focus ring hits the start or end of focusing (so, only mechanics related stuff).
      For the USB, the only site I know is the OKI one.
      And do you know you can’t use the focus info while in direct view/film mode? When the mirror is up, the AF sensor don’t see the picture, only the imaging sensor.
      The focusing algorithms work more by iteration, measuring the de-phasing of light/picture than distance. Maybe Canon improved that for the new E-TTL generation, but I have no info/data about it, sorry.

  17. Thanks for giving me this advice Jean…

    “…you can’t use the focus info while in direct view/film mode? When the mirror is up, the AF sensor don’t see the picture, only the imaging sensor. The focusing algorithms work more by iteration, measuring the de-phasing of light/picture than distance.”

    Just to clarify the context of my question – if someone made a separate hardware device to detect the focal distance to the subject, could they feed that focus data to the lens via USB, while videoing?
    Basically it would take over the task of focusing.
    I think what you are telling me is that the OKI can control focus via USB, but they can not get data back from the camera while it is recording a video, because no focus data comes from the camera while videoing?

    Is that right or have I misunderstood the limitations you are describing.
    Thanks again for putting up with my lack on knowledge.

    • Yes, when the camera imaging sensor is exposed to the light (photo shooting, video filming), there’s no focus info available because the mirror covers the focus sensor. What OKI does (and what my electronic follow focus was supposed to do), is to send commands to the focus ring motor to turn.
      Yes, you could use an external device to measure the distance but I’m afraid it will be very complicated to link that distance with the number of steps the focus motor has to turn to get the right focusing. Especially with long/wide lenses, which can sometimes have a focus zone of a few millimetres (ex: Canon 400mm f2,8).

      So far, the most automated electronic follow focus function I know is the focus memory (you set the focus, memorize it, change it, press a button and the ring gets back to the memorized position). See the Briger follow focus: http://www.birger.com/
      Well, if you *really* need a function like the one you describe, the easiest solution would be to install an other camera with the same lens next to the one filming and hack the two lenses in parallel, the second camera feeding the focus data to the follow focus of first one.
      But my knowledge on the subject isn’t infinite, so I might be wrong.
      Cheers!

  18. Jean, can I ask 1 more dumb question…

    If you set focus with an external device like the oki or the birger mount, and then the user manually zooms the lens. Would the image still be in focus?
    I guess this is actually 2 questions:
    - are most lenses designed so that zooing does not mess up the focus
    - or do canon lenses compensate by altering focus if the user zooms the lens.

    Thanks for generosity Jean

  19. No problem!
    I think with the most of lenses, you loose the focus when you change the zoom (I know the camera needs the current zoom value to calculate the focus and also by my photographer experience, when you zoom, you have to re-focus).
    It depends on the type of lens you’re using. With some, the focus won’t change so much, with others, you’ll clearly see the difference.

  20. Interesting discussion here. Has anyone looked into why old Sigma lenses won’t work on the new Canon DSLR bodies? They auto-focus ok but won’t actuate the aperture blades. A while ago, I hooked up a scope to look at the signals on my hacked 50mm lens and notice the old camera, EOS100 have a CLK at about 12kHz and the new one, 300D at about 16kHz, but I don’t believe that is enough to cause of the problem. I didn’t attempt to interpret the SPI data.

  21. Gerhard, thanks for the German link. It looks like “Slein” has solved the problem of new Canon vs. old Sigma. I will dig more into the ASM code. At a glance, it seems that his circuit waits for the aperture control command and changes a bit in the lens reply byte to make the camera happy.

    I have connected my hacked 50mm lens to an Arduino UNO board and thanks to the control commands listed on this blog, I can open and close the aperture. By the way, in $07$13+$xx command, $xx is xx steps (not stops) down and a step is only a fraction of a stop. Also, this command can be sent repeatedly to close the aperture progressively. Since I use the standard SPI code lib, my SCLK line is not bi-directional and that didn’t seem to bother the lens. I do have a 600 ohm resister in series to prevent direct collision with the acknowledge pulse.

      • Sorry – I don’t have any code. I received an already programmed ATtiny and now may Sigma is working fine!

        If you check the post you’ll find some assember code for the ATtiny and recently one member ported the code to a PIC.

        cheers
        Gerhard

      • I have the Arduino code but I am on ski holiday. I will post it after I return next week.

      • Here is my Arduino code using standard SPI library. Keep in mind the Canon EF protocol is NOT standard SPI. EF protocol uses the CLK signal also as acknowledge by the lens to let the camera know it’s busy.
        The busy can last a few hundred ms if it involves some mechanical operation like change aperture or focus. My code also runs the CLK at 125kHz as opposed to 80kHz in actual EF operation but that doesn’t seem to matter. The focus operation does not work in my set up because I do not have a separate power supply to the Vbat. I simply use the 5v from USB and that’s not enough to operate the focus. It will reset the processor if attempt to do that.
        Here is a link to some pictures of my set up.
        https://picasaweb.google.com/Panabiker/LensHack?authuser=0&authkey=Gv1sRgCODhxr2MlpH20QE&feat=directlink

        =========================================

        /* This is an experiment to control a Canon EF lens, and
        hopefully, understand the difference between
        old Sigma lenses and Canon lenses.

        Disclaimer:
        This is purely experimental for my own use and it may cause damage
        to your lens/camera if you use it.

        Created Feb 19, 2012 by G. Huang

        Lens control pins:

        DCL: pin 11
        DLC: pin 12
        DCLK: pin 13

        */

        #define DEBUG 1

        // the sensor communicates using SPI, so include the library:
        #include

        // message buffer 10 bytes
        byte message[10];

        void setup() {
        Serial.begin(9600);

        // start the SPI library:
        SPI.begin();
        SPI.setBitOrder(MSBFIRST);
        SPI.setDataMode(SPI_MODE3);
        SPI.setClockDivider(SPI_CLOCK_DIV128); // 16MHz / 128 = 125 kHz
        delay(100);
        busyPoll();
        delay(100);
        }

        void loop() {
        char inChar;

        if (Serial.available() > 0)
        {
        inChar = Serial.read();
        switch (inChar)
        {
        case ‘i’:
        getLensInfo(message);
        break;

        case ‘g’:
        getAper();
        break;

        case ‘o’:
        openAperture();
        break;

        case ‘s’:
        setFStop(0×04);
        break;

        case ‘b’:
        busyPoll();
        break;

        case ‘f’:
        focusRing(10);
        break;

        case ‘n’:
        focusRing(-10);
        break;

        }
        }
        }

        byte sendCommand(byte Cmd) {
        byte Ack = SPI.transfer(Cmd);
        delayMicroseconds(250);
        return(Ack);
        }

        // busy poll
        unsigned int busyPoll() {
        byte *msg_ptr;
        msg_ptr = &message[0];

        *msg_ptr++ = sendCommand(0x0A);
        *msg_ptr++ = sendCommand(0×00);
        #if DEBUG
        debugMsg(“busyPoll”);
        #endif
        return(0);
        }

        // Get aperture data
        unsigned int getAper() {
        byte *msg_ptr;
        msg_ptr = &message[0];

        *msg_ptr++ = sendCommand(0xB0);
        delay(10);
        *msg_ptr++ = sendCommand(0×00);
        *msg_ptr++ = sendCommand(0×00);
        *msg_ptr++ = sendCommand(0×00);
        #if DEBUG
        debugMsg(“getAper”);
        #endif
        return(0);
        }

        // Get lens info
        unsigned int getLensInfo(byte *info_str) {
        byte *msg_ptr;
        msg_ptr = &message[0];

        *msg_ptr++ = sendCommand(0×97);
        *msg_ptr++ = sendCommand(0×01);
        *msg_ptr++ = sendCommand(0×00);
        *msg_ptr++ = sendCommand(0×00);
        *msg_ptr++ = sendCommand(0×00);
        *msg_ptr++ = sendCommand(0×00);
        *msg_ptr++ = sendCommand(0×00);
        *msg_ptr++ = sendCommand(0×00);
        *msg_ptr++ = sendCommand(0×00);
        #if DEBUG
        debugMsg(“getLensInfo”);
        #endif
        return(0);
        }

        unsigned int setFStop(byte f_value) {
        byte *msg_ptr;
        msg_ptr = &message[0];

        *msg_ptr++ = sendCommand(0×07);
        *msg_ptr++ = sendCommand(0×13);
        *msg_ptr++ = sendCommand(f_value);
        *msg_ptr++ = sendCommand(0×00);
        #if DEBUG
        debugMsg(“setFStop”);
        #endif
        return(0);
        }

        unsigned int focusRing(int d_value) {
        byte *msg_ptr;
        msg_ptr = &message[0];

        byte low_byte = d_value & 0xFF;
        byte high_byte = (d_value & 0xFF00) >> 8;
        *msg_ptr++ = sendCommand(0×44);
        *msg_ptr++ = sendCommand(high_byte);
        *msg_ptr++ = sendCommand(low_byte);
        #if DEBUG
        debugMsg(“focusRing”);
        #endif
        return(0);
        }

        unsigned int openAperture() {
        byte *msg_ptr;
        msg_ptr = &message[0];

        *msg_ptr++ = sendCommand(0×13);
        *msg_ptr++ = sendCommand(0×80);
        delay(200);
        *msg_ptr++ = sendCommand(0×00);
        #if DEBUG
        debugMsg(“openAperture”);
        #endif
        return(0);
        }

        unsigned int debugMsg(char *note) {

        Serial.print(note);
        Serial.print(“: “);
        for(int i=0; i<9; i++) {
        Serial.print(message[i],HEX);
        Serial.print(" ");
        }
        Serial.println(".");
        return(0);
        }

  22. I just found this amazing blog and would like to post the following question that has to do with the use of old manual lenses on digital DSLR . Specifically the new Sigma SD1 .

    This camera incorporated some new abilities such as Tethered control that are obviously lens dependent so the camera seems to be always polling for lens id and any attempt to use manual lenses that do not report back their id , create problems with the generation of a JPG for LCD Display . The RAW capture remains unaltered .

    Since for most people the LCD display and its Histogram are essential to good Imagery I am trying to find a way to fool the camera into thinking that a lens is still attached . ( A non electronic lens is essentially invisible to the camera)

    Any ideas ? My thinking is around the possibility of pulling some pins low or high , to tell the camera that the lens is busy doing something .Would this work? How do those chip enabled lens adapters work to make the camera focus assistance work?

    If I can understand how those chips work maybe I can use them in the Sigma SA bus that is very similar to Canon EF.

  23. I have not used a Sigma DSLR so I’m not sure how they work. Are you saying that the camera LCD will not display the image you capture if the the lens is not electronically coupled to the camera? I know Canon cameras will take pictures and display the picture regardless of the lens.

    From the experience with Canon EF, I don’t think you can staticly “pulling some pins low or high” to fool the camera. If the Sigma protocol is similar to Canon’s, have you tried to use a Canon “AF confirm” chip on Sigma? These chips are widely available for use with manual lenses on Canon cameras.

    • No , the camera LCD will display a corrupted image , almost solarised. It seems that not knowing what lens and which apperture the displayed values got maximum . If you have the original lens mounted and you disconect the bus by using a piece of plastic between the pins same thing happens than if you mount a purely manual old lens.

      Sigma bus and its protocol is basically the same but commands and responses might be different. However is a good place to start so I have already ordered a programmable chip to give it a try . The problem started with a firmware upgrade that incorporated reading the lens ID and taking it into account for image generation. Previous versions didnt do that.

      • If the Sigma camera used to display the images properly before the update, it seems that Sigma is doing something deliberately to prevent the use of non-electronic lens, or there is a software bug. There is absolutely no reason that lens information is required to display an image. Many software on many computers can display beautiful images properly without knowing the aperture of a lens, and I don’t even know how the aperture data can help in displaying an image.

      • That thought has crossed many peoples mind , however nobody knows if this is an accidental “bug” that creeped in or if it is intentional . Most likely it is just a bug since Sigma do not have purely mechanical lenses in the SA mount, as Canon and Nikon have , such as the wonderful Perspective Correction lenses , so Sigma Programmers didnt have to think about manual lenses on the Electronic mount as Canon and Nikon had.

        The modern tendency is to have a Look Up Table of corrections in Firmware ,for each lens that they manufacture . Before the update you had to add separate updates to that list periodically . The new firmware update includes all the lenses Sigma currently manufacturers and, apparently , no provision for “Invisible” manual lenses.

  24. Hello Jean!!!
    Thanks for fine article. I without being the programmer has received a true pleasure from perusal of this article. The width of your sight imposes. Very pleasantly that there are people not without adducing any proof accusing monopolism of the companies and closeness in sphere of workings out the leader, at first sight, to braking of progress and, at the second sight, on an example of your actions to awakening of creative consciousness at individuals separate of crowd.
    I address to you for council and the help. As the fates decree I had lens ZeissVarioSonnar24-85 for Contax N an autofocal series. At me camera Canon 7d/Accordingly interface of this lens and the device also is a question essence.
    This point in question successfully dares the kanadsko-Hong Kong company http://conurus.com/conta x/buy-a-lens-that-has-already-been-modified/138-used-carl-zeiss-vario-sonnar-24-8535-45
    It expensively enough and long enough.
    I remove video, accordingly for today, the question of an auto focus not especially occupies me. And here a question possibility to operate an electromechanical diaphragm yes.
    And management in this lens is carried out from a ring on the lens.
    Question essence – management of a diaphragm, in the presence of a ring on a lens, is connected with other electronics of a lens or the step-by-step engine will work at giving on it pressure from a chamber body? (I understand that the question has many admissions, but nevertheless?)
    Manual of the chamber for this lens http:// global.kyocera.com/prdct/optical/support/manual/nx_eng.pdf
    Once again thanks for article, yours faithfully, Alexey, Russia

    • Hi Alexey!

      I’m not sure what your question is, but the people at conurus.com seem to be doing a very good job. With adapting lenses to an other camera brand the mechanical question is as important as the electronics one. The mount must be perfectly done in order to avoid focus/blur problems.
      In any case, you’ll need a protocol conversion to make believe the camera body the lens is OK and to translate the body commands to the lens. Maybe asking the people of conurus will help you more than me!
      Do svidaniya!
      Jean.

  25. I wonder if you can use one body to control two lenses. Piggyback one of fof the other. So, that way you have a body doing the video and the other body in AF-S mode so its always focusing. The adapter on the “video” body would prevent the lens from communicating with the body, maybe take power from it. Assuming two of the same lenses, the still body should be able to reliably focus them both. Probably have to opto-isolators or the like. Dunno. Just a thought.

    Awesome work though! As soon as the macro extension tubes come out from Kenko for my NEX, I’ll try and do the same for the NEX lens protocol.

    • Hi!
      That seems like a lot of trouble, just to have an autofocus. It’s probably cheaper to rent a professional HD video camera for the shooting than to buy two times the same rig and play with electronics. ;-)

  26. Hello Jean,

    It is s surprising to find that someone else has been thinking along the same path as I was with respect to controlling Canon lenses internal motors from an external devise.
    The need for that arose a few days ago after having acquired the new RED Scarlet motion picture camera Canon mount and immediately realized that the AF system is useless for any live purposes.
    Your project is very adventurous and requires an intense knowledge of pic programming; I am more of a mechanical engineer but I have a fair understanding of programming (only from leisure learning) and understood all of your steps.
    However, since I need to adopt an external drive for Steadicam usage, I might have to revert to physical external motor, still with a certain amount of electronics behind in order to allow presets memory.

    I have made a copy of the software as you left it just I case I should find time to play in the future because I think it’s a shame to have done all that good work having stopped just when you did.
    My compliments to you and, who knows, maybe thanks to your pioneering soon we will see something of the kind on the market ! (made in china of course……J

    Best regards

    Mauro Andreini

    • Ciao Mauro, non siamo italiani, e stiamo lanciando un prodotto che fa proprio quello che cerchi, abbiamo già anche un sistema follow focus per DLSR Canon, dai una occhiata qui: http://www.linkyfocus.com

      Il sistema per controllare le lenti tramite protocollo Canon EF sarà incluso del progetto Apertus.org che vedrà sviluppata una telecamera 4K con il nostro controllo per le lenti EF

      Fulvio
      LinkyFocus.com

  27. Interesting posts. I expected to find a lot more info about on this topic. My interest is a little different. I have developed an interest in Olympus Pens and would just love to use my eos full frame sigma 150 to 500mm zoom on it and be able to control the aperture. In this case there is plenty of room in the adapter and hopefully suitable power from the camera. It might even be possible to directly couple the aperture control to the camera. Auto focus and it’s powering would probably be a tough nut to crack. I’m amazed that some one isn’t already making suitable adapters. Olympus already do for their larger 4/3 none micro 4/3 lenses. As things stand people are stuck with the silly idea of an adapter with an iris in it – in the wrong place too. It would best be on the front if it’s not possible to get at the one inside. I’m toying with the idea of using a cheap mask to achieve F8 and maybe an F11 and F16 in my pocket.

    I have worked on abs development for (too) many years before retiring and have use spi in anger several times and other variants. Interesting to see it mentioned here. Many years ago motorola were over the moon when they started supplying micro controllers to Canon Cameras JP. Could well be that they still use them probably in asic form now. Motorola’s programmers ref manuals are very good and give an excellent description of what goes on and what can be done. It’s basically as all of the other variants a master slave system. There can usually be multiple slaves too on some. It should be possible to download data books from their web site, HC11, HC16 or maybe things have moved on but spi is a standard feature for many of their processors. One day it may be replaced by CAN. Any way these manuals will tell people what can be done, time limits etc etc etc. :-) Don’t ask me about them please. There has been far too much water under the bridge since I worked on these. I have hand cranked master and slave set ups through normal port pins but it’s really best to use dedicated hardware. When hand cranking the best way is to drive the slave side via an interrupt pin off the master’s clock signal but it gets rather messy,

    John

  28. Looking around further I came across this thread
    http://chdk.setepontos.com/index.php?topic=1331.0
    It includes a link to a pdf that gives some details on what goes on in this area. No protocol unfortunately but hardware details. They appear to use a master slave 3 wire set up where the master, the camera generates the clock with maybe the slave dragging the clock low to signal busy. i say maybe because I would want to check the spec of the spi interface if that’s what it is. Use that way is a new one on me. The detail relate to film eos by the look of it but as these lenses work on digital the info should still hold.

    I’ve also seen indications that the baud rate has changed with time. This suggests that the camera negotiates it before doing anything else. How I don’t know. It might be just by requesting info at a low standard rate and then changing or even by doing something strange to the lines which causes the lens to respond. A low baud rate request would be favourite as it’s closed and must work.

    I have also seen mention of logic analysers. Personally I would use another micro to monitor all 3 lines. The data will be stable on either data line some time after a transition of the clock signal. The easiest way to do this would be to add an external delay between the clock line and an interrupt pin on the monitoring micro. The delay needed can be found in data sheets. A few cmos gates might be all that is needed. I mostly work in assembler. The interrupt routine would use roll from carry or what ever to build up the transmitted bytes on both lines and run a bit counter so that the main can pick up completed bytes. The main program would simply stream these bytes out to say a pc terminal program etc but it would be worth looking for both text and hex. The lens and camera streams could also be kept separate. Complication come if the slave does drag the clock line low. Solutions to that really depend on how long that state lasts.

    There really shouldn’t be any problems hanging high impedance uP pins directly to any of these lines.

    If the data rate are too high to work as indicated above the simple solution would be to double buffer. The interrupt routine could for instance use say 2 stores and a flag that’s flipped at each complete byte to set which store is used. A more complicated solution would use a index to set where each byte is stored. The index might for instance be set to zero again every time it reaches 16 or what ever. My guess would be that the ideal number would match or exceed the longest number of bytes either sends as this will give most time to get the info to a pc. On byte style processors 255 is great as inc’s overflow to zero naturally and avoid wasting time in the interrupt.
    :-) Only problem for me really is that I don’t have the time at the moment but the above might help some one that does. Given the separate data streams it shouldn’t be too difficult to get a far idea of what is going on at least in part. The initialisation is likely to be the difficult bit but as C may have been used there might even be some ascii kicking about. That can help a lot with that sort of thing.

    If any one does it I hope they make the info freely available in several places in case canon arrange for it to be removed.

    John

  29. John

    Take your time, read the thread thoroughly from the top – and pay attention to the code posted by G. Huang on April 9′th. The code contains commands for both “open aperture” and “SetFstop”, which is what you’re after…

    /hans

  30. Hi Hans I had noticed that but having looked at a number of sources of information I concluded this isn’t setting an aperture it’s just changing the iris setting. That wouldn’t be sufficient to couple to another make of camera such as 4/3 transparently as that will want to set F stops. :-) There is also the problem of hacking 4/3 protocol. Sony wont pass it on to individuals. See here for more info and yet more code

    http://diydrones.com/profiles/blogs/arduino-control-of-a-camera-lens

    There is a translated link as well. Translation isn’t too good but it’s interesting to note “burnt” and the solution. If I had time to work on this I would want to know exactly what canon do. My 500mm sigma zoom wouldn’t be cheap to replace. I was just mentioning a cheap safe method people could use to get thoroughly into it.

    On G.Huang’s comment about not spi it’s hard to be sure. The camera is master so only gets responses and delays when it expects them. A master clock is used. There is nothing to stop it from tri stating the clock drive pin as appropriate. More likely the clock drive pin just uses a pull up or series resistor. SPI initially was a purely Motorola entity. I2C came from Phillips. They mostly used 12C in TV’s initially. Nowadays even looking at the wiki it points out that the terms means all things to all manufacturers. Generally though on most processors all will do the same thing what ever they are called. I worked with HC11 for about 5 years and then the company switched to NEC. Different name same functions. I worked with I2C for a while a long long time ago. Intel offer something similar too. They all do. Pass on pic level etc products but I would be very surprised if they couldn’t offer the same facilities too. In fact a pic was hung off the main processor in an abs controller I worked on. Not by me as I was working on an area in an American product at the time that communicated via the power supply line.

    I have only looked quickly at the hc11 data but as motorola point out under some circumstances it’s best to use open drain outputs see page 308

    http://e-www.motorola.com/files/microcontrollers/doc/ref_manual/M68HC11RM.pdf

    They might also use a series resistor as mentioned and sense both sides of it. The other option is a micro specifically produced for them. That happens a lot where volumes are large. Only the needed bits are put in it to keep costs down. The wiring diagram I linked to earlier may give some clues. As manufactures hate switching processor suppliers for a number of reasons mainly related to hardware they might just still be using motorola parts.

    John

  31. LOL Can’t help looking further. There is a strong suggestion that the processors shown in the wiring diagram on the coms lines are by Matsushita. Probably 4bit, application specific and very difficult to obtain data for. The circuit is old so they probably use something else now but these types of parts usually have open drain with internal pull up’s capability. It would be interesting to know any markings on chips in a newer lens.

    John

  32. I have a simple question, probably boring for most of you. We’ve been looking at autofocus accuracy with different camera lens combinations and have concluded the number of available ‘steps’ in position sensors and motor commands are an important part of that.

    Has anyone looked at the number of steps various lenses have available? I’ve got access to every lens current production – if someone can show me how to measure that I’d be happy to share the data.

    Roger

    • You can find some data here:
      http://redmodz.com/red-birger-lens-mount-unofficial-mini-faq-and-thread-compilation/
      Related to the Briger mount adapter. (question “”Erik, how many steps for the Canon 24-70 f2.8L and Canon 70-200 f2.8L IS?”” bottom of the page)

      I’m not sure the step size is *so* important for the focus accuracy. I’d start with the auto focusing measurement, then the lens calibration and quality, then the mechanical precision and number/size of the steps.
      You’ll notice the number of steps is bigger on L series. I think it’s related to the optical quality, the higher it is, the more you’re able to notice that the “out of focus” is made by the focusing precision and not by the lens itself. You’re also more likely to use the lens with wider aperture, which reduces the focus depth.
      Then, the number of steps is also bigger on long range zooms (seems logical) and on wide aperture lenses.

      As for the measuring process, The only way to measure it precisely is to count it and via a mount adapter with a processing unit (uController, FPGA, whatever).

      Now I think of an other method that might work: place a sensitive microphone on the lens, close to the motor, record the sound of the lens searching for the focus (it has to go both to min and max) and open the recorded file with a sound editor. If you’re lucky, you could be able to see the sounds made by the stepping of the motor (sound spikes in the file).
      It’s all hypothetical, especially because the motors are not real step motors and they have gearboxes. Plus, I never tried it myself. :-/

    • Roger

      As indicated by Jean, the number of motor steps are only part of the equation. The step size may be larger or smaller but is matched by the resolution of the encoder. The step size and the “gear ratio” in combination determines how much the focus lens(group) will minimally move. The amount movement needed for a given amount of phase difference seen by the AF sensor varies with the focal length.

      The amount of movement in steps is calculated by the camera from the phase difference seen by the AF sensor and a number of parameters read back from the lens. The value of these parameters mirror the design of the drive system and the optic system and change with focal length and position of the focus lens(group).

      The “lens accuracy” is hence greatly influenced by how well these parameters and the formula used for the calculation of the number of steps to take, “describe” the actual characteristics of the lens.

      On top of that comes the accuracy of the body AF system – where the double line staggered array layout used on the 5DIII and 1dX will greatly improve the “repeatability” part..

      By means of a suitable adapter, such as the one described at the start of this
      blog, you will be able to study the communication between the body and the lens.
      The first and most manageable hurdle is to understand “the language”, i.e. the protocol and command structure, where some help to achieve this objective can be found on the net. Next through a series of planned tests you can start to deduce such things as AF drive tactics under different conditions. The ultimate goal of determining the formula used to calculate the number of lens steps (and hence the accuracy) , is however a monumental task as the lens / body communication does not provide information about the actual phase difference value. The only way is hence to keep the phase difference constant and vary the lens parameters which will require that your adapter is able to “intervene” in the communication between the body and lens by substituting parameters on the fly. Surely patent texts and mathematical skill in determining formulas from the change in parameters will greatly help, but I gave up on this part after many a late night early this year.

      Thus in summary, even though by monitoring the lens / body communication you can determine the number of steps for a given lens (although not directly) and with a number of tests using a suitable AF target possibly a relation between the step size and it’s impact on the ideal focus I think there a easier ways.

      As you did not mention your reason for wanting an “expected accuracy per lens” figure, I will presume that your goal is to create some sort of accept criteria for assessment of given lens’ need to be calibrated – if this is the case I suppose building a statistical database based on testing each lens sample the way you already do with Imatest, would be one possibility. One could possibly expand this concept to include real target offsets also by creating an AF target usable by both the Imatest MTF tool and an angled ruler like in the Lens Align tool.

      ~ Hans ~

  33. Pingback: Anonymous

  34. Pingback: Как камера Canon EOS общается с объективом EF-S | Sainquake

  35. Great work!! I have a second-hand Canon 75-300 IS USM lens and am planning on putting a lens2scope (http://www.lens2scope.com/) adapter on the back to give me a compact zoom birdwatching scope (I use a Canon SX40 35x optical zoom for taking pictures). I can see the lens needs 6V to power up and has some other data lines. You seem to have worked out a lot about how the camera-lens comms works. What would I need to allow me to get the lens to image stabilise without a camera attached?? (A small battery powered box with a push switch sort of thing?) A stabilised compact birding scope would be a real killer!!

    Cheers

    PEter

  36. I’m using a Canon EF lens as part of a scientific experiment and want to control the focus as part of it. It’s great that you guys have worked a lot of this out already, so thanks for that.

    Since this page seems to have become the internet’s repository on the Canon’s EF lens control protocol, I thought I should add what I discovered today:
    http://www.oliford.co.uk/phys/canon-lens-protocol/

    It’s a Canon EOS 500N (ebay, 8€) hooked up to a ‘Canon EF 135mm f/2L USM’. The conversation seems to have only a little in common with what others are showing. When I get the Arduino talking to it, I’ll try your commands and see if they work.

    Did anyone else have any more protocol info that they didn’t post back here yet?

    Oliver

    • Oliver
      I believe your problem is not that the EF500 EF protocol you encounter is that much different from what’s shown further up in this message stack. I have been looking quite bit at the EF650 and although it has a slightly different startup sequence, the commands are essentially those detailed above.

      From looking at your images the culprit is likely timing / levels of your “protocol analyzer” – i.e. if you periodically misinterpret a bit, may well result in a log that seems to contain “new” commands.

      Essentially the protocol is a modified 8bit SPI where the clock (LCLK) has a 9’th bit or wait state used by the lens to signal its BUSY state. Said bit is active low and varies in length and thus you analyzer should be able cope with this. The state during of the two data signals DCL and DLC during the BUSY bit should be ignored.

      Although the body switches DCLK between active and passive drive, it’s safe to add a 10kom resistor between this signal and Vcc to improve the edge quality – which applies to DLC also.

      Hope this helps
      ~ Hans ~

      • Hi Hans,

        What I wrote about in that post was read manually from the digital scope at something like 200MHz sampling, so I’m pretty sure I didn’t miss anything. As an example, the camera uses 0×80 to request lens info, rather than 0×97,0×01 reported in table at the top. That is confirmed when I communicate with the lens from the Arduino. In that case I can send 0×97,0×01 and it doesn’t do anything.

        Later, I wrote two programs for the Arduino to record the protocol between the camera and lens and another to send commands to the lens directly. Both handle the bit clock and busy states properly, so they (should) know when they are in sync or not:
        http://www.oliford.co.uk/phys/canon-lens-protocol/canonEF-observe.cpp
        http://www.oliford.co.uk/phys/canon-lens-protocol/canonEF-control.cpp

        Some commands documented here, e.g. 0×44 and 0xC0 work, but are not used by the camera.
        How well they work seems to depend on what state the previous commands leave the camera in. There seems to be some subtle control of motor mode or speed or something that means in some cases I can’t use the focus after controlling the aperture.

        The camera uses many other command sequences, e.g. 0xC2 report the lens current absolute focus, even if it was manually adjusted.

        I have wondered myself if there is a problem with the bit pickup sometimes. The observation program very often sees the sequences 0×90,0xA9, but sometimes 0×10,0xA9 and sometimes 0×80,0xA9 (which should not work, because 0×80 is the lens info command). The clock line must be working, because the program notices if it misses a bit, or if the lens acknowledge is missing. It is possible that the DOUT line is a little slow, although it never looked like it on the scope.

        For my experiment, I can now do what I need with the original commands together with the ‘new’ 0xC2 command, so I will probably not do any more investigation. I have uploaded the full conversation files for the two lenses I have in case anyone is interested in dissecting them.

        Thanks for your help,
        Oliver

  37. Had a look in my log archive

    This is the a log from an EOS500 and a EF100LIS lens The lens is much newer than the Body, and it’s therefore expecting a “newer” startup sequence than used by the body
    You wil HENCE not find a lensinfo sequence like the one at the top..

    *Telegram DCL DLC
    0×000000 0A FF ;Sync command
    0×000001 00 AA ;Sync reply
    0×000002 90 FF ;Note the lens ignores
    0×000003 B9 FF ;all further coms until
    0×000004 00 FF ;the second sync command
    0×000005 12 FF ;@ telegram #13
    0×000006 80 FF
    0×000007 B0 FF
    0×000008 00 FF
    0×000009 00 FF
    0x00000A 00 FF
    0x00000B A0 FF
    0x00000C 00 FF
    0x00000D 00 FF
    0x00000E B2 FF
    0x00000F 00 FF
    0×000010 00 FF
    0×000011 00 FF
    0×000012 80 FF ;The body tries to ask for lens info
    0×000013 0A FF ;using 80 0A 00 00 00 00 00 00
    0×000014 00 AA ;but since the lens is not correctly
    0×000015 00 00 ;initiated according to a newer
    0×000016 00 00 ;version of the EOS protocol
    0×000017 00 00 ;it mistakes the 0A for a sync
    0×000018 00 00 ;command, replies with an AA
    0×000019 00 00 ;and starts up (replies with 00)
    0x00001A A0 00 ;The body ask for current Fl
    0x00001B 00 00 ;
    0x00001C 00 64 ;Lens answers 00 64 = 100mm
    0x00001D B2 00 ;Don’t know what the B2 command
    0x00001E 00 60 ;is but it relates to change
    0x00001F 00 00 ;in aperture on zooms
    0×000020 00 01
    0×000021 0C 00
    0×000022 C0 0C ;Request current posistion of focus group
    0×000023 00 00 ;reply is 16 bit signed int
    0×000024 00 00
    0×000025 F0 00 ;Unknown
    0×000026 00 60
    0×000027 0E 00 ;Some sort of init sequence id
    0×000028 0F 0E ;same…
    0×000029 0A 0F ;Sync command
    0x00002A 00 AA
    0x00002B 90 00 ;Status request command first byte
    0x00002C B9 00 ;same.. second byte
    0x00002D 00 00
    0x00002E B0 00 ;Aperture info
    0x00002F 00 30 ;Display Av
    0×000030 00 20 ;Min Av
    0×000031 00 58 ;Max AV
    0×000032 A0 00 ;Request Fl
    0×000033 00 00
    0×000034 00 64
    0×000035 B2 00 ;Unknown
    0×000036 00 60
    0×000037 00 00
    0×000038 00 01
    0×000039 0C 00
    0x00003A C0 0C ;Request focus posistion
    0x00003B 00 00
    0x00003C 00 00
    0x00003D F0 00
    0x00003E 00 60
    0x00003F F8 00 ;Best Focus Correction value
    0×000040 00 D3
    0×000041 50 00 ;Set speed
    0×000042 2D 50
    0×000043 0C 50
    0×000044 06 0C
    0×000045 0F 06 ;Search toward MFD @ set speed
    0×000046 0A 0F ;Sync command
    0×000047 00 AA
    0×000048 90 00 ;Status request command first byte
    0×000049 B9 00
    0x00004A 00 10 ;status reply: lens at end stop
    0x00004B B0 00
    0x00004C 00 30
    0x00004D 00 20
    0x00004E 00 58
    0x00004F A0 00
    0×000050 00 00
    0×000051 00 64
    0×000052 B2 00
    0×000053 00 60
    0×000054 00 00
    0×000055 00 01
    0×000056 F0 00
    0×000057 00 60
    0×000058 90 00 ;Status request command first byte
    0×000059 B9 00
    0x00005A 00 10 ;status reply: lens still at end stop
    0x00005B 0C 00
    0x00005C 05 0C
    0x00005D 0F 05 ;Search toward INF @ set speed
    0x00005E 0A 0F ;Sync command
    0x00005F 00 AA
    0×000060 90 00 ;Status request command first byte
    0×000061 B9 00
    0×000062 00 24 ;focus group is moving and accelerating
    0×000063 B0 00
    0×000064 00 30
    0×000065 00 20
    0×000066 00 58
    0×000067 A0 00
    0×000068 00 00
    0×000069 00 64
    0x00006A B2 00
    0x00006B 00 60
    0x00006C 00 00
    0x00006D 00 01
    0x00006E F0 00
    0x00006F 00 60
    0×000070 90 00
    0×000071 B9 00
    0×000072 00 04
    0×000073 C0 00 ;Request focus posistion
    0×000074 00 00 ;
    0×000075 E0 5E ;focus postsion = 00 5E
    0×000076 00 BC
    0×000077 00 15
    0×000078 C0 00 ;Request focus posistion
    0×000079 00 01 ;focus postsion = 01 CB
    0x00007A E0 CB ;Lens extension correction
    0x00007B 00 BC
    0x00007C 00 E4
    .
    .
    .
    .
    .
    As for the 44 command not being used (a bit further down in the same log):

    0x00014E 90 00 ;Status request command first byte
    0x00014F B9 00
    0×000150 00 00 ;status reply: focus group at rest
    0×000151 F8 00
    0×000152 00 AC
    0×000153 E0 00
    0×000154 00 BD
    0×000155 00 11
    0×000156 EA 00
    0×000157 00 A3
    0×000158 00 D7
    0×000159 00 8C
    0x00015A 00 04
    0x00015B 00 00
    0x00015C 00 00
    0x00015D E4 00 ;Lens extension factor
    0x00015E 00 A1
    0x00015F 00 C6
    0×000160 44 00 ;Move focus group
    0×000161 06 44 ;06 01 = 1537 steps
    0×000162 01 44 ;toward INF
    0×000163 0F 44
    0×000164 0A 0F
    0×000165 00 AA
    0×000166 90 00 ;Status request command first byte
    0×000167 B9 00
    0×000168 00 24 ;status reply: focus group moving + acc
    .
    .
    .

    For comparison here’s the start up of the same lens with a 650D DSLR body The key difference is that this body does not send the lens info 80 0A command until after it has sent the 0A sync command twice and the lens therefore does not mistake the second byte of the 80 0A telegram for a sync command…

    0×000000 00 FF
    0×000001 0A AA
    0×000002 00 AA
    0×000003 0A 00
    0×000004 00 AA
    0×000005 80 00
    0×000006 0A 81
    0×000007 98 FE
    0×000008 01 00
    0×000009 00 64
    0x00000A 00 00
    0x00000B 00 64
    0x00000C 00 77
    0x00000D 00 9A
    0x00000E 14 00
    0x00000F 7F 02
    0×000010 01 72
    0×000011 00 B9
    0×000012 94 00
    0×000013 41 FF
    0×000014 B0 00
    0×000015 00 21
    0×000016 00 20
    0×000017 A0 58
    0×000018 00 00
    0×000019 E4 64
    0x00001A 00 A1
    0x00001B 68 C6
    0x00001C 93 F0
    0x00001D 04 93
    0x00001E 05 93
    0x00001F 0A 93
    0×000020 91 93
    0×000021 86 00
    0×000022 00 00
    0×000023 00 04
    0×000024 0C 00
    0×000025 0F 0C
    0×000026 0A 0F
    0×000027 00 AA
    …….

    And btw, I do not think you are really seeing a C2 command as it relates to the TTL2
    distance used by much newer bodies than the EOS500

    ~ hans ~

  38. Good to see there’s still some action here! I’m working on controlling an EF-S lens (currently 18-55mm, later on a 15-85mm) using an FPGA and a modified EOS 500N body to breakout the signals. Had some trouble getting the electrical protocol to work; in the end I found out I was changing the data a little too late. I’m using a 62.5kHz clock signal and was changing data on the negative clock edge. Saw the lens sometimes interpreting x0A as a x05, so basically shifting right all the data by 1 bit. As it wasn’t consistent I suspected a timing error, which might also be influenced by the level translator (2.5->5V) being a little slow maybe. I then altered the timing by changing the data line a little earlier, halfway between the positive and negative edge. All seems to be working fine now :-)
    Got the aperture control working, this lens doesn’t seem to need the x07 before the x13 command. Guess it might be needed if the motors are powered down beforehand (with x08).
    Momentarily I’m working on the focus control. The basic stuff works (fully to infinity or nearby, doing some steps) but I was wondering whether someone has already found out how setting the focus speed works? Particularly how the two bytes following the x50 command should be interpreted.
    Cheers!

    • Hi Rene

      Yes, getting the protocol timing to work reliably can be a bit tricky – not only the slightly weird 9bit SPI but there’s also different bit widths (and thus rates) to deal with. So far I have come across 5, namely: 6us, 5us, 2us, 1.25us and 1us, depending on body and lens combination. The Canon patents even open up for switching to asynchronous comms during movie shooting.. (yet to be seen)

      Data ( DCL and DLC )should be setup on the falling LCLK edge and will be read/latched by lens and body on the rising LCLK edge.

      I cannot tell you the full story on the 0×50 command, but except for the 70-200LIS2.8 that takes two, all other lenses I have looked at, take one byte as parameter only – which in most cases is in the range 0x2C-0x2F, i.e. when used for still shooting. During live view, on a number of lenses the 0×50 parameter changes to the range 0×60-0x6F. So far I have not spent time on trying to decipher the meaning of the speed parameter, but it would be interesting if you figure something out and are willing to share that with us

      the 0x0C that follows the 0×50 0x2D command in the above example, is a single byte command on its own, which can be seen from fact that the lens returns a 0x0C in the subsequent telegram..

      ~hans~

  39. Hello, did you have time to pick the lens button ? On big tele photo lens you have a configurable button in the menu of many Canon dslr. You can set manual/auto focus, Focus single AI servo, etc. It could be great to add a connector and a chip into a Tc 2x producing this lens code sending data to the camera then we can an external push button. On my Sigma 120-300 I dont have this button so it will be helpfull.

    • Sorry, but I cannot help you on that one, as I do not have any long tele-lenses. I would not be surprised to find the additional lens switch bitcoded into the replies of either the 0×90 or 0×91 commands however, as that’s where the status of the lens AF/MF and IS on/off switches reside. Assuming I’m right and given that your target lens is an older Sigma design, it may also just be possible insert a small microprocessor in the DLC signal, that for the majority part just relays the original DLC bit stream and modifies the bit(s) of the relevant command replies in real time. Something similar has been done in regards to “resurrecting” older sigma lenses that require a 0×12 command for aperture control. The 0×12 was the command issued by older bodies whereas newer ones use 0×13. Canon lenses seem to be “immune” this change but it “crippled” a number of older Sigmas. You may want to head over to the German DSLR forum, where much of the pioneering work for the protocol interpretation can be found … and some of the members engineered a chip fix to circumvent the 0×13 issue along the lines mentioned above. If you do not speak German, you can try to post in English and kindly ask if some of the guys there have considered your suggestion. The thread you want to look into is this one:
      http://www.dslr-forum.de/showthread.php?t=649529 .
      Be warned however, that you will need soldering and programming skill, or friends that do and be willing to take the risk that comes with “hacking”..

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s