Jump to content


Photo
* * * * * 1 votes

My Strobe Controller Blog


  • Please log in to reply
26 replies to this topic

#1 giffenk

giffenk

    Wolf Eel

  • Member
  • PipPip
  • 131 posts
  • Gender:Male
  • Location:Toronto

Posted 01 March 2016 - 09:22 AM

I started a thread over on Scubaboard a while ago and finally realized that it would make sense to replicate it here as well.

 

I have been working on a scuba related personal project for a while and thought I would share some of my findings in a series of posts. My intent is to give regular updates (every few weeks?) as well as to respond to any reply posts that interest me. My intent is to present content at an introductory level where ever possible.

Bear with me. I am lazy. And maybe not very good at this...

-------------------------------
 

My problem is how to happily control my scuba camera strobes.

 

And by Strobe I mean Flash. Don't ask me why, but scuba divers refer to an external camera flash as a strobe. Maybe you learned something today? Strobes are a very important scuba photography tool since it gets dark underwater. Very dark. Ambient light gradually reduces as you go deeper, but even worse, you lose certain colors. Things get green real quick. Strobes provide light and restore proper color balance. Google it to learn more.

 

Fish move. Often and quickly. Like squirrels. One technique I use underwater is continuous burst mode. I aim my camera, press the shutter and take a burst of pictures. As fast as the camera and strobe can go. Hopefully at least 1 shot will NOT feature fish butt. Depending on your camera gear, your burst speed can range anywhere from 1 frame every 5 seconds (painfully slow) to 1 frame every 2 seconds to 1 frame every second to 4 frames per second or even 20 frames per second. Burst speed depends how fast your camera AND your strobe can recycle and get ready for the next shot.

 

The recycle time of a strobe depends upon how much power it dumped and your battery charge level. Full dump means a longer recharge time. Low battery charge means a longer recharge cycle. Common consumer strobes are powered by 4 AA batteries (or equivalent) and generally recharge in 2 to 3 (or much longer) seconds. Partial dumps (less than full strobe power) means the strobe will ready for the next shot much sooner. Partial dumps are your friend when using continuous burst mode.

 

The recycle time of the camera depends upon several items. Some can be fiddled with. The camera must capture the image, process it and write it to memory card. I will ignore camera image performance. Do your own research. BUT: the onboard camera flash (yes the onboard flash is called a flash) can be an issue. If you are using optically triggered strobes (see next paragraphs), you must wait for the onboard flash to recharge before the next picture can be taken. Cameras generally have small batteries and low power onboard flashes. Without external help, this situation is not good for burst mode.

 

So we provide illumination help in the form of external strobes. The strobes need to be controlled by (or at least co-operate with) the camera so that the strobe discharge is synchronized with the camera shutter. Current popular technology relies upon an optical connection (fibre optic cable) to allow the strobe to act as a slave to the onboard camera flash. Old technology relied upon a physical wired sync cable connected to the camera hot shoe to fire the strobe. Optical control relies upon (and is limited by) the recycle time of the onboard flash. Sophisticated cameras realize the onboard flash is simply a trigger device (and not an illumination device) and support minimal flash power setting in order to increase the recycle speed. Non sophisticated camera don't. Wired strobes only depend upon the strobe recycle time.

 

So what's my problem? I bought a new camera. My new camera burst mode is worse than my old camera burst mode. Partly because my strobes optical trigger performance is poor. But the camera is also stupid.

 

My primary set of strobes are Sea & Sea YS110's. They support optical slave operation. But not very well. They are excellent as wired sync strobes. I used them via wired sync cables on my old camera and could achieve 4 frames per second in continuous burst mode.

I purchased a new camera in order to get better super macro performance. The hot shoe on my new camera (Canon G16) does not support continuous burst mode (more detail on this in later posts).

 

The G16 onboard flash does work in continuous mode, but not for long. After about 20 frames the camera pauses for 20-30 seconds. Likely a built-in flash overheat protection mechanism to allow the camera flash circuitry to cool down?

 

What to do...buy new strobes...fiddle with the camera...?



#2 TimG

TimG

    Sperm Whale

  • Moderator
  • 2017 posts
  • Gender:Male
  • Location:Amsterdam
  • Interests:Sunlight reefs, warm seas, fine wine, beautiful women. And Manchester City Football Club - English Premier League Champions (again) for 2017-18

Posted 01 March 2016 - 10:20 AM

Interesting....

 

How about getting rid of burst shooting as an option, giffenk? You don't need to worry then about recharge times. To an extent fish movements - at least for some species - are reasonably predictable. If the problem of shooting fish backsides is due to shutter lag, maybe that's the way to approach it? Move to something that cuts the shutter lag and lets you shoot what you want?


Tim
(PADI IDC Staff Instructor and former Dive Manager, KBR Lembeh Straits)
Nikon D800 and D500, Nikkors 105mm and 16-35mm, Sigma 15mmFE, Tokina 10-17,  Subal housing

http://www.timsimages.uk
Latest images: http://www.shutterst...lery_id=1940957


#3 giffenk

giffenk

    Wolf Eel

  • Member
  • PipPip
  • 131 posts
  • Gender:Male
  • Location:Toronto

Posted 01 March 2016 - 10:49 AM

Interesting....
 
How about getting rid of burst shooting as an option, giffenk? You don't need to worry then about recharge times. To an extent fish movements - at least for some species - are reasonably predictable. If the problem of shooting fish backsides is due to shutter lag, maybe that's the way to approach it? Move to something that cuts the shutter lag and lets you shoot what you want?

Juvenile spotted drum...

Their long fins flap around as they dart about.

#4 oskar

oskar

    Eagle Ray

  • Member
  • PipPipPip
  • 397 posts
  • Gender:Male
  • Location:Stockholm

Posted 02 March 2016 - 09:59 AM

You could trigger with a led flash whose only purpose is to trigger and uses own battery without any recharge time. Third party mini flashes are most often manual mode only, which is fine with me

#5 giffenk

giffenk

    Wolf Eel

  • Member
  • PipPip
  • 131 posts
  • Gender:Male
  • Location:Toronto

Posted 03 March 2016 - 09:36 PM

You could trigger with a led flash whose only purpose is to trigger and uses own battery without any recharge time. Third party mini flashes are most often manual mode only, which is fine with me

Agreed! But my YS110 strobes optical trigger performance is less than wonderful. Well it is abysmal. Actually it sucks big time. But they are wonderful via a wired sync cable. And I already paid for them. And I have no information that indicates any other brand / model of strobe will economically solve my problem.

 

The optical trigger from the G16 is not a complete solution since the G16 gives up relatively quickly in burst mode (within 2 seconds) and refuses to continue to fire (see above).

 

I also get bored easily and do not have much money to buy other nice stuff but seem to have way too much time on my hands so maybe I can fix it by spending way too much time programming an embedded controller? Hence this series of posts.

 

My old DX-1G could do 4 fps. My YS110s could keep up on low power settings. But this was an open loop system (see later posts for more info on open vs closed loop...) and sometimes the strobes failed to show up when the camera was faster than the strobes.

 

The G16 is advertised as being able to do 9 fps. I have tested it with both a Canon and non Canon (Meike) flash and the camera will slow down to allow the flash to recharge between shots as required. Digital eTTl is king!

 

My ultimate goal is to support continuous mode via the G16 with the camera waiting for the strobes as required via the Canon digital eTTL protocol. I may not achieve this...but I think I may learn a thing or two as I struggle along...



#6 giffenk

giffenk

    Wolf Eel

  • Member
  • PipPip
  • 131 posts
  • Gender:Male
  • Location:Toronto

Posted 03 March 2016 - 09:40 PM

Canon Hot Shoe

My problem: trying to control scuba strobes from my new Canon G16.

 

I have ruled out optical control because my YS110 strobes work poorly in optical mode AND the G16 cuts out after about 20 onboard flashes in continuous burst mode. So now I am focused on wired sync control of my smart analog strobes via the camera hot shoe.

 

But I had a technology mismatch. The G16 hot shoe was capable of supporting either a dumb analog flash or a full featured Canon digital flash. The YS110 is a smart analog strobe, but capable of being operated as a dumb analog strobe.

 

Dumb is fine. My previous Sea & Sea camera hot shoe was dumb AND supported continuous burst mode. It would "fire" the strobe each time the camera recycled and captured a new image. It was dumb in that it would fire even if the strobe was not ready. The camera did not consider any feedback from the strobe. This worked fine since my strobes could cycle faster than the camera. No problems mate! Life was good.

 

The G16 hot shoe in analog mode is even dumber. Continuous burst mode is not supported in analog flash mode. The hot shoe X contact only fires once at the start of the burst in analog mode. Life is not so good. So analog control in continuous burst mode is a non-starter.

 

So let's do a quick review of the control of analog strobes based on the Nikonos protocol (I am not aware of any digital protocol scuba strobes). The strobe raises the X contact to 5 volts when it is fully charged and ready to fire. The camera shorts the X contact to ground when the shutter opens. If TTL is employed, the camera shorts the Q contact to ground when proper exposure has been achieved which instructs the strobe to stop discharging. Once the strobe has recharged it raises the X contact to 5 volts to indicate it is ready to start over. In dumb analog control the camera only has an X contact (it ignores the Q contact) and causes the strobe to perform a full dump on each shorting of the X.

 

The G16 does support continuous burst mode for compatible digital flashes. But this depends upon the flash knowing Canon's digital eTTL protocol supported via a proprietary Cannon hot shoe interface. There is a small number of compatible flashes. None are waterproof.

 

Time to investigate Canon's digital eTTL protocol? 


Edited by giffenk, 03 March 2016 - 09:41 PM.


#7 giffenk

giffenk

    Wolf Eel

  • Member
  • PipPip
  • 131 posts
  • Gender:Male
  • Location:Toronto

Posted 11 March 2016 - 09:12 AM

Canon eTTL Protocol

 

The Nikonos analog TTL protocol is relatively simple and has been reverse engineered by a number of scuba strobe manufacturers. The X contact is used to start the strobe dump and the Q contact is used to stop it. That's about it.

 

But it is rather limited in what it can accomplish. Advanced everyday things like zoom head flashes can not be supported. The answer to this problem is "digital". Different camera manufacturers developed their own camera-to-flash digital protocol. A quick skim of this Canon patent might help to give you an idea of the potential complexity of the digital protocols.

 

These protocols are closely guarded trade secrets. The camera manufacturers do not publish any details or respond to enquiries. This makes it very hard for a third party to produce a compatible flash. Have a Nikon camera? Buy a Nikon flash. Have a Canon camera? Buy a Canon flash.There are a few third party manufacturers ( Yongnuo is an example) that have reverse engineered portions of the digital protocol. This normally results in flash products that are not full featured and may not work with all camera models.

 

The following image depicts a modern Canon digital hot shoe. It has different contacts than a Nikon digital hot shoe.

512px-EOS_350D_Hot-Shoe.jpg

So what do the various contacts do?

 

A web search turns up very little relevant hits. After sifting down through the results I discovered the following gold mine of information authored by Bill Grundmann way back in 2009. Bill wanted to do something similar and had worked out some of the basics. He has a series of blog posts that cover his investigation into things like the electrical interface, contact use and the digital protocol. His work was based upon some earlier work that is no longer accessible on the web. I also found a page which provides information on the hot shoe contacts.

 

One thing Bill noted is that his protocol findings differed from the results of the earlier work. He was finding both new and altered messages. It makes perfect sense that as time progresses, new messages would be created to support new features. It also makes sense that some features may be camera / flash specific.

 

So with Bill's work as a starting point, all I had to do was create an eTTL decoder...



#8 giffenk

giffenk

    Wolf Eel

  • Member
  • PipPip
  • 131 posts
  • Gender:Male
  • Location:Toronto

Posted 19 March 2016 - 08:08 PM

Canon eTTL Decoder

The path was clear. If I wanted to control my underwater strobes from my G16, I would need to create a magic decoder box. It would translate between Canon eTTL digital protocol and Nikonos analog TTL protocol. Simple in concept: digital goes in, analog comes out.

 

This is a problem calling for a microcontroller solution! Easy enough, There are several readily available hobby boards to choose from. Seems like a perfect excuse to spend some time and money playing with technical gadgets.

 

I quickly realized that the prime considerations were size and packaging (and then maybe power...). From a packaging perspective I had 2 choices

  • Create an external water proof container for the decoder
  • Jam the decoder inside my camera housing

Let's ponder the external container option for a moment. Creating a waterproof container that will survive the immense pressures exerted on it by the extreme depths of the oceans is actually trivial: a baggy full of oil is sufficient. The oil does not compress, so there are no pressure concerns. The baggy is "water proof" so it will keep salt water out of the innards.(I learned this from my Uwatec dive computer, thin plastic shell, oil and electronics inside.) Unfortunately my current world was more complex. The controller requires power. This generally means a user replaceable battery. Which means I need to be able to open and reseal the container. There is also the issue of the wired strobe connections. For practical purposes you need to be able to detach the strobes from the decoder and the decoder from the camera. The most practical solution for this is using industry standard Nikonos style bulkhead connectors and cables (and I already own a bunch of them). I also projected that I would want some kind of control switches. Water and pressure proof ones.

 

Constructing an external decoder housing seemed daunting. One option would be to re-purpose an existing housing. And they exist! Sea & Sea has several (out of production) models of TTL converters. These beasts are analog to analog decoders. They are hard to find and the owners believe they are gold plated ($400 USD). Ikelite also made an external strobe controller. Much harder to find. I think I have seen 2 on eBay in the last few years. (I might discuss external TTL converters in future posts?)

 

So I decided to go internal for my decoder.

 

This eliminated all waterproofing issues as well as the cost / complexity of bulkhead connectors. I have already installed a Nikonos style bulkhead connector in my housing and have cables to connect to my strobes.

 

Size now became the issue. The controller and all its gubbins had to fit inside my housing, tucked around the camera somewhere. This imposed a rigid set of real physical constraints. I needed a very small microcontroller board. Off the shelf, since I am lazy.

 

I was vaguely familiar with the Arduino project so I looked there first. And was horrified at the size of the boards. They were huge! A quick check of some other common hobby boards revealed the same largeness. On reflection, it made sense. These were general purpose hobby boards that were designed for people to tinker with. They needed to be large enough to provide a wide range of sensor connections.

 

So I investigated further and discovered the Sparkfun Pro Mini Board. Game on!



#9 giffenk

giffenk

    Wolf Eel

  • Member
  • PipPip
  • 131 posts
  • Gender:Male
  • Location:Toronto

Posted 09 April 2016 - 08:08 AM

Arduino Development Setup

 

Time to learn how to program an Arduino! How hard can it be? In my early years I was involved in real-time process control and embedded controllers. I even created a patent for weighing garbage. So this was familiar ground, just repackaged and modernized for the hobby crowd. Bonus! Makes my life easier.

 

The main attraction with the Arduino world was multiple models of boards that all shared the same base functionality and development tools. For prototyping I purchased an Arduino Uno. It is designed to be the hobby starter board. It is. Good stuff.

 

Next step was to prove that I could make the Uno do something special. All I needed was an IDE and I would be off to the races. Simple.

 

But I got confused by a shiny pebble distraction. My web searches turned up an Arduino based software oscilloscope. Awesome. I may need one of those. Off I went and downloaded a bunch of stuff, figured out it was "too new" for the OS on my old laptop that I had dragged out of the closest for this project. So I reverted to older software, finally got it working and THEN discovered I was playing with Processing not Arduino. Oops.

 

Start over.

 

This time I grabbed the proper IDE and was off to the races in a few minutes. It was advertised as Eclipse based so I was expecting a plugin that I could add to one of my existing Eclipse IDEs. Not so. It is a standalone app built on Eclipse. Not an a plugin, it provides its own look and feel and has lost a bunch of features that I was used to. Not perfect. But workable.

 

The UNO IDE provided a library of sample "sketches" that I was able to download and exercise on my UNO board. The simplest demonstration of my new found power was to hack the Blink example. I made an LED flash differently. I was also able to display debugging output to a monitor window. I was elated! Upon reflection, this accomplishment was trivial when compared to the task ahead of me.

 

I also had to take care of some housekeeping issues. After creating a series of unique files for each custom version of Blink I realized I really needed my standard IDE ecosystem that the UNO IDE seemed to exclude. I needed a proper source code control system. A workable compromise was to use a copy-paste transfer from UNO IDE into my Eclipse CDT tool so that I had standard source code control (SVN for this project) and other advanced IDE features like code formatting and cross file search.

 

Now it was time to get to the business at hand: hook my Arduino to my Canon G16...



#10 giffenk

giffenk

    Wolf Eel

  • Member
  • PipPip
  • 131 posts
  • Gender:Male
  • Location:Toronto

Posted 12 April 2016 - 11:29 AM

Arduino eTTL Protocol Sniffer

 

The easiest way to investigate the Canon eTTL protocol was to eavesdrop on the conversation between the camera and a flash. This approach would allow me to observe a real working system. I needed to learn about the Cannon eTTL protocol supported by my G16. There was some reference material available on the web but they all cautioned about model differences and misunderstood features. So a sniffer was the way to go.

 

This required a couple of things I did not have:

  • a means to connect my Arduino to the hot shoe contacts
  • an appropriate flash

Getting access to the hot shoe contacts meant tearing something apart. No guarantee it would go back together afterwards. So cheap is best. eBay yielded a Canon hot shoe compatible flash extension cable. About $20. I placed my order with the supplier in China and waited.

 

The flash was easy: rent one for a week from my local camera shop: Henry's. All I had to do was make sure I obtained the proper flash. I took my G16 into the retail store and tested it with a number of different flashes. The low end 270EX II did not support continuous burst mode. Time to go upscale. I ended up with a 430EX II flash, $400 retail. Or $40 a week to rent.

 

I had my ducks in a row. Time to get to work on my Arduino sniffer.

 

Based upon the prior work and a few hints in the Canon patent, I suspected that Canon used the industry standard Serial_Peripheral_Interface (SPI) as the digital interface. And the Arduino also supports SPI. This is a simple electrical protocol used to support bi-directional data exchange between a master and a slave device. Only 3 pins are required: CLCK, MOSI, MISO.

 

This seems to good to be true. It was. No free lunch. First obstacle was that the voltage levels were off by a few volts - some external circuitry may fix that? After some additional fiddling research I ultimately determined that the Arduino SPI hardware was unsuitable for use as a sniffer. It was not designed to eavesdrop on 2 different data signal lines. It was designed to receive as a Slave device or drive as a Master device. It could only "eavesdrop" on 1 side of the conversation. IF I could get it to work, I could only sense either the camera data or the flash data. Not both.

 

This meant that my only remaining option was to monitor the 3 digital lines via low level bit bashing. My next step was to create a bit bashed sniffer program.



#11 giffenk

giffenk

    Wolf Eel

  • Member
  • PipPip
  • 131 posts
  • Gender:Male
  • Location:Toronto

Posted 27 April 2016 - 09:40 AM

Arduino Bit Bashing Canon eTTL Protocol

 

I needed to be able to sniff the digital data exchange between a Canon G16 camera and a 430EX II flash. Prior work had determined that the Canon digital eTTL protocol interface was VERY close to SPI. Mostly. Except for signal voltage levels. I had already determined that the Arduino SPI interface was not suitable for sniffing.

 

My ultimate goal was to discover how the Canon eTTL protocol supported burst mode flash control - so that I could mimic that small part of the protocol. The camera was smart enough to detect the presence of a Canon flash and then control it via digital commands.

 

So I was forced back to basics. Fortunately Bill Grundmann had already started down this avenue and provided a sample bit bashing program. I used this code as a starting point and then many late nights expanding the program. It basically relies upon detecting change of state of the 3 SPI signal lines. An interrupt service routine is hooked to the CLCK line which then samples the current state of the 2 data lines. Low level brute foirce programming. Very timing dependent. 

 

One of the first issues was inconsistent behaviour of the sniffer program. It took several experiments and large amounts of head scratching to discover that bit bashing and slow blocking operations did not mix well. The obvious culprit was the standard debugging output via Serial.print. This depended upon serial interrupts. Some basic timing calculations revealed that the camera / flash data exchange operated at a higher data rate than the debug output. A dumb debug output dump of all traffic was doomed to failure. The camera - flash exchanged more data than the debug monitor could dump.

 

The next clue to success was based upon a general observation of the SPI interface. It was bi-directional, but not really full duplex. There was a single clock signal controlled by the Master. The Master (camera) and Slave (flash) both transmitted at the same time. Under control of the Master driven clock. The Slave can not initiate data exchange. This meant the data exchange was highly constrained. The Master could transmit a command to the Slave at any time. The Slave could not initiate a data transmission. The Slave was also constrained to transmit data at the same time as the Master, before it had received current information from the Master. These constraints result in a very chatty protocol.

 

Examination of the data revealed that the flash tended to continually spew status messages at the camera. This made sense since each multi-byte data exchange was initiated by the camera. The flash has not yet read the information from the camera, but is required to provide data back to the camera. So the flash often transmitted a standard "general status" message. This meant that in a steady state, with no button pushes on the camera or flash, the digital interface was constantly spewing data back and forth.

 

Next step was to figure out what it all meant (or at least learn enough so I could trigger my strobes).



#12 adamhanlon

adamhanlon

    Harbor Seal

  • Admin
  • 2209 posts
  • Gender:Male
  • Location:Lancaster, UK

Posted 27 April 2016 - 09:53 AM

This is a great topic!

 

Thank you for sharing all your hard work so freely.

 

Adam


Adam Hanlon-underwater photographer and videographer
Editor-wetpixel
web | Flickr | twitter | Linkedin | Facebook


#13 giffenk

giffenk

    Wolf Eel

  • Member
  • PipPip
  • 131 posts
  • Gender:Male
  • Location:Toronto

Posted 16 May 2016 - 08:20 AM

Canon eTTL Protocol Investigation

 

Having established an Arduino based sniffer complete with an IDE I was finally ready to do some actual real investigation of the Canon eTTL protocol - as spoken by my Canon G16 and a 430EX II flash.

 

My prior work had indicated that there was constant chatter between the camera and flash. Even in an idle state.

 

The constant traffic stream meant it was very hard to locate messages related to specific camera or flash functions. My initial sniffer program dumped a continuous stream of data to my debugging monitor window. Too much chatter. This meant I needed to develop code to get rid of the chaff. I needed to identify and discard the repetitive data. That would allow me to easily identify distinct data exchanges based upon operation of specific camera and flash controls.

 

This was accomplished via a large number of tedious and repetitive sessions. I took the approach of restarting each experiment from the known state of camera and flash powered off. I started sniffing and powered them up.

 

The first challenge was identifying and building a list of messages. Bill Grundmann's work provided a solid (but incomplete) starting point. As expected, each message is multiple bytes long. Different messages are different lengths. Some message turned out to be variable length (ouch!). The constant chatter meant it was very difficult to locate the start and end of a message as my initial sniffer program dumped a constant stream of data. Even when I was not touching the camera or the flash.

 

I first inspected the data dump of the camera to flash exchange in a powered up idle state and manually looked for repetitive byte sequence patterns. I altered my sniffer to look for and filter this repetitive idle chatter. Success! I ended up with an unknown spew of data at power up, followed by blissful silence. If I changed a control I received another spew of unknown data followed by silence.This approach was very rewarding and enabled me to concentrate on the unknowns in the protocol.

 

I slowly enhanced the sniffer program to identify the sequence of startup messages, but then discovered a major problem with my initial approach.

 

My first filter was very crude - it simply discarded repeats of a list of "common" messages based upon "opcode". A common message structure (in any protocol) is to use a leading opcode byte that identifies the type of message that is then followed by a series of data bytes that report information specific to the purpose of the message. A simple example is the camera reporting its aperture value to the flash. Bill Grundmann provides an example here that illustrates 2 byte exchange of aperture information.

 

Filtering based solely on opcode was a bad decision. My idle chatter eliminator was suppressing too much. Changing aperture on the camera went unreported. I enhanced the filter to remember the last "state" of each message type and then had it report on every state change.

 

Armed with this knowledge I settled in to a series of sessions over the next 2 weeks (I extended the flash rental by 1 week) and worked up a sniffer program that fairly reliably reported camera - flash data exchanges.

 

Game on! I now had insight into the behaviour that the G16 expected from a flash. Most important, this included the data exchange for continuous flash operation.



#14 giffenk

giffenk

    Wolf Eel

  • Member
  • PipPip
  • 131 posts
  • Gender:Male
  • Location:Toronto

Posted 25 May 2016 - 08:25 AM

Pivot! Decoder -> Quench

 

My prior work had established a reference set of data messages exchanged between my Canon G16 and a 430EX II flash. Now all I had to do was workup an Arduino program to mimic a 430EX II to the G16 and mimic a Nikonos camera to my Sea & Sea YS 110 strobes.

 

So far I had been focused on the Canon G16 digital side of my problem. I considered the strobe side to be simple. So I had ignored it. I had focused on developing a Sniffer program that would characterize the G16 to 430EX II protocol. Next step was to think about the big picture decoder problem.

 

My work on the Sniffer revealed that I was pushing the speed limits of the Arduino (at least the way I was using it...more on that later?). My sniffer was bit bashing and sometimes gave inconsistent data values for the same operations. Adding analog control of the strobes on top seemed risky.

 

I utilize my strobes in manual mode so that I can dictate the light output. I adjust the power output of each strobe via a knob on the back of the strobe. My strobes are mounted at the end of long arms on each side of my camera housing. This means that I have to reach left and right to each strobe for every power adjustment. A single power level knob located close to the camera would simplify my life.

 

An interesting eBay opportunity provided the nudge for me to rethink my problem. I managed to acquire a used Sea & Sea TTL converter. My interest in this device was only for the physical housing and controls. The behaviour of the internal microcontroller would not be compatible with my G16 camera. But it was big enough to hold an Arduino so I could replace the controller with my own.

 

So I did a pivot and changed direction. Slightly. I split my problem into 2 distinct slightly less complex problems:

  • controlling the strobes
  • handling Canon's eTTL protocol

First I needed to be able to control the strobes. Controlling them intelligently from my G16 could come afterwards. I switched my attention from the bleeding edge digital world of Canon G16 eTTL protocol to the archaic world of analog Nikonos TTL protocol.

 

My next step became creating an Arduino controller that would replace the obsolete "smarts" inside the Sea & Sea TTL converter. In theory strobe control should not be that difficult. Just 2 analog signal lines. Fire the strobe, then when enough light has been produced, quench the strobe.

 

Simple...All I needed was a small Arduino program to fire and Quench the strobes



#15 giffenk

giffenk

    Wolf Eel

  • Member
  • PipPip
  • 131 posts
  • Gender:Male
  • Location:Toronto

Posted 09 June 2016 - 08:24 AM

Strobe Quench Basics

 

My focus now switched to creating a simple Arduino based controller that would allow me to manually adjust the power (light) output of my Sea & Sea YS110 strobes from a single control on my re-purposed Sea & Sea TTL converter housing.

 

Let's talk theory first. My strobes (and many others) still support the ancient Nikonos analog TTL protocol via a wired connector. The Nikonos protocol depends upon

  • only 3 wires: X, Q and Ground
  • 0 to 5(ish) volt signal levels.

The behaviour of the protocol is well known with an excellent detailed explanation available here courtesy of Cameras Underwater in the UK. Thanks!

 

The Coles Notes version of the important parts of the Nikonos protocol are:

  • Strobe asserts X when it is ready to fire
  • Camera shorts X to ground to cause the strobe to fire
  • Camera Asserts Q to stop the strobe from firing (critical for TTL operation)

In the TTL world the camera controls the protocol and requires a bunch of smarts to control the image exposure. After firing the strobe, the camera measures the amount of light received and when it has had enough the camera instructs the strobe to stop providing light by quenching the strobe via the Q signal line.

 

A manual (non TTL) controller utilizes the same concepts but manipulates the strobe to provide a "consistent" power (light) output. This can be done either open loop or closed loop.

 

An Open Loop control system utilizes no external feedback and causes the strobe to emit a consistent amount of light based only upon elapsed time. The longer the strobe is "on" the more light it will emit. The basic algorithm is: fire the strobe and then quench it N microseconds later. Smaller values of N means a smaller amount of light, large values of N means a large amount of light. This concept totally ignores how much of the produced light is usable (i.e. reflected back to the camera).

 

A closed loop control system relies upon a light sensor to provide a consistent level of "reflected' light. It is based upon the concept of the strobe delivering light until a consistent amount has been reflected back to the light sensor. This tries to emulate true camera based TTL behaviour with the light sensor posing as a substitute for the camera. This idea has merit as the light reflected back to the camera is the only thing that counts. The light that goes off into the deep is wasted. There have been multiple commercial strobes that included a variation of this behaviour. The feature is often labeled by the manufacturer's marketing team with a term something like "TTL auto". It is not true camera TTL, but it does deliver a consistent amount of "reflected" light.

 

The type of system required depends upon your needs - and often upon your intended photographic effect.

 

I was striving for a simple open loop manual power control system that would deliver a consistent amount of light.



#16 giffenk

giffenk

    Wolf Eel

  • Member
  • PipPip
  • 131 posts
  • Gender:Male
  • Location:Toronto

Posted 20 June 2016 - 03:08 PM

Strobe Quench Controller Operational Theory

 

I now needed to transform my Sea & Sea TTL converter into an open loop manual power controller for my YS110 strobes. This would provide a single point of power level control so that I did not need to individually adjust the built-in power knob on both of my strobes. Supporting the Canon eTTL protocol was shuffled to the back burner for a while.

 

The physical TTL converter provided the following features:

  • 2 Nikonos bulkhead connections for my strobes
  • a user replaceable battery compartment
  • a power level control
  • 2 "strobe type" selector controls

This converter does not have an optical sensor of any sort, so creating a closed loop system was not easily feasible. I also preferred an open loop system that delivered a consistent amount of light. This would allow predictable results as I altered other physical aspects like strobe position, orientation and distance from the subject.

 

At first glance the settings required to use an external manual controller seemed counter-intuitive. External manual control is actually fairly simple:

  • set the strobes to TTL mode (what??)
  • quench the strobes from the controller based upon the controller power knob setting

Setting the strobes to TTL mode seemed wrong. My goal was manual control. Seems like everything should be set to manual?

 

Nope! Setting the strobes to manual means that you have instructed the strobes to ignore any external control signals (other than fire) and to rely upon the built-in power setting knob of the strobe. In order to centrally control the strobes they must be placed into an operational mode that allows external control. That would be TTL mode. In TTL mode the strobes expect to be controlled by an external source - generally a camera.

 

In manual mode the strobes only monitor the X line and then deliver power according to their built-in power knob setting. Any external control signal via the Q line is ignored. So the strobes need to be set to TTL mode for external manual control. In TTL mode the strobes will respond to both the X and Q signals and will (mostly) ignore their built-in power knob. My YS110 strobes support a feature where the built-in power knob provides "micro adjustment" of power output when using a fibre optic sync cable in TTL mode. The built-in power knob is totally ignored when using a wired sync cable in TTL mode.

 

This reduces our manual controller to a few simple concepts:

  • monitor the strobe X lines (pass this to the camera X)
  • monitor the camera X line
  • monitor the controller power level control (more on this later...)
  • when the camera asserts X, assert the strobe X
  • delay based upon the controller power level and then assert the strobe Quench line

Sounds simple! But not really.

 

I was fortunate to have some spare ancient YS50 strobes as well as a spare DX-1G camera that I could punish use in my research. I whipped up a quick Arduino program and hooked it to a YS50 strobe. The initial results were less than awesome. I had some practical learning to do...



#17 giffenk

giffenk

    Wolf Eel

  • Member
  • PipPip
  • 131 posts
  • Gender:Male
  • Location:Toronto

Posted 18 July 2016 - 08:02 AM

Practical Arduino Real-Time Control - Part 1

 

My Arduino Quench program was intended to provide control of the power level of the attached strobe(s). My initial attempt had a few challenges: the majority of them related to timing issues. I had lost my real-time control mojo.

My problems stemmed from a few areas:

  • unfamiliarity with the Arduino runtime environment
  • uncertainty over control timing of the Sea & Sea strobe(s) (see later posts...)

This post will focus on the first issue: real-time Arduino programming.

 

The Arduino comes with a basic bootstrap framework that allows you to ignore the microcontroller chip details and get started quickly. The framework initializes the chip and then has 2 user hooks: a setup routine and a loop routine. The setup routine is invoked once at program start. The loop routine is then called repeatedly as fast as possible. The framework provides timers and serial communication services (useful for debugging if you are careful...). The runtime is not multi-threaded or multi-tasking. It is simple and only provides a single thread of execution.

 

There are numerous trivial sample programs that illustrate the use of a single hardware feature. For example, the Blink program consisted of a loop that turns on an LED output, blocks for a time delay, turns off the LED, blocks for another time delay and then returns. The blocking time delay prevents any real-time control ability over multiple inputs / outputs. 

 

Lack of multi-tasking support meant that I had to design a single monolithic loop routine that would handle everything. This is were things started to get confusing.

 

In order to monitor and debug my efforts I was dumping (Serial.println) status information to the monitor window connected back to my IDE. As I carried out various experiments I slowly began to realize that things that used to work no longer functioned properly. My program became erratic and undependable. My old stuff was broke. As I added new features (and associated debugging output), features that used to work stopped working. It was time for some cause and effect thinking...

 

It took several more experiments before I finally realized that as I modified my diagnostic Serial.println calls the behaviour of my program changed. My lazy programming was the source of my problems. My control logic was solid. But its timing was being thrown off due to the delays and overhead of my Serial.println diagnostic output. My monolithic control loop was handling an ever increasing number of inputs and outputs. This meant that the loop needed to execute quickly and consistently.  The Serial.println diagnostic was not suitable for real-time use. A diagnostic report regarding one item would affect the timing of others.

 

A second issue was framework overhead. There are multiple different Arduino boards. The Arduino framework provided consistent, easy to use, board independent, high level routines to accomplish things like setting an output or reading an input. These routines are portable across boards and safe. They also introduced delay due to execution time overhead. My first approach to reading external camera and strobe signals had been to blindly poll all inputs every loop cycle. The input reading overhead combined with the delay of diagnostic Serial.println meant that my control loop became erratic. It did not execute within a consistent time period. Which destroyed my ability to provide a real-time controller. The loop timing was inconsistent which meant my output controls were inconsistent. I got random strobe behaviour.

 

Until I fully understood the Arduino timing issue, I was not sure if my program or the creaky ancient YS50 strobe was to blame. Additional research was required...



#18 giffenk

giffenk

    Wolf Eel

  • Member
  • PipPip
  • 131 posts
  • Gender:Male
  • Location:Toronto

Posted 23 July 2016 - 06:27 AM

Practical Arduino Real-Time Control - Part 2

 

Inconsistent test results meant that I needed to step back and examine how I was using the Arduino. Due to the single threaded nature of the runtime environment, I was forced to use a single loop function to handle all inputs and outputs. I now needed to make the loop execute on a consistent basis in order to provide real-time behaviour.

 

his caused me to adopt a more sophisticated approach to my Quench control program loop:

  • I redesigned the diagnostic output (Serial.println is not your friend!)
  • I made the loop actions time based
  • I made the loop actions priority based
  • I used direct chip control

Serial.println diagnostic output during a critical time event was not possible as it caused excessive delays which prevented real-time response. Since I was still on the initial strobe control learning curve, I needed the diagnostic information in order to understand my YS50 strobe and the TTL converter controls. A simple solution was to store each piece of diagnostic data into a dedicated variable and output all the diagnostic data at a suitable idle point. This complicated the code, but was workable. Having the slow Serial.println code all fire at a consistent point in time meant there were no timing side effects on time critical code. I was able to reliably dump the diagnostics at the end of each strobe fire cycle after the strobe had recharged. The delay became annoying as the batteries lost power and the recharge time took longer. But it worked.

 

My initial design copied the Arduino code samples and I read all of the inputs every loop cycle. Reading all of the inputs every cycle introduced extra overhead that slowed down responsiveness (especially when using the standard high level routines - more below). So I altered the design to only read an input when it was required. My first change was to read each input every N loops. This approach made a huge improvement in the responsiveness of the controller. I was no longer wasting time during critical events reading unneeded inputs. But I had a hard time guessing appropriate values for N. Especially since there was several different N's. This concept needed refinement.

 

Every N loops needed to be replaced with every D microseconds (where each input had a different value of D). The Arduino provided a real-time clock so it was easy to track elapsed time. This required a simple mechanical code transformation. Instead of setting a loop counter to 0, I grabbed the current timestamp. Instead of comparing a loop counter to N, I compared elapsed time to D. This change made the responsiveness of the controller stable and (mostly) predictable.

 

My next design change was required in order to deal with the single threaded nature of the Arduino. In my past I had relied upon a suitable blend of multiple real-time tasks and interrupt service routines to segregate code for different actions. I now had to pile all of my code into a single Arduino thread. There is a simple rule: higher priority code has to run first. This meant that I needed to introduce a set of flags - 1 per action - and arrange the loop code so that lower priority code was skipped if a higher priority action was active. Only the highest priority active code was executed each loop cycle. For example: if firing of the strobe was in progress, then the code to read the power level setting was skipped. Not elegant, but effective.

 

My last change was a simple optimization to reduce the overhead of interacting with the Input and Output controls. The Arduino IDE provided a set of portable digital read, digital write and analog read functions. These were "safe" functions that accounted for differences in port hardware across different Arduino boards and also made sure that the ports were set up properly to support the desired operation. This extra portability and safety cost important execution time. I replaced these routines with direct port access commands. Not portable. Not safe. But fast.

 

I finally had a stable and understandable Arduino based control system. Now all I had to do was learn how to make it control a strobe.



#19 giffenk

giffenk

    Wolf Eel

  • Member
  • PipPip
  • 131 posts
  • Gender:Male
  • Location:Toronto

Posted 07 August 2016 - 05:57 PM

Practical Arduino Quench Control - Part 1

 

Now that I had determined how to properly structure my real-time code for the Arduino, it was time to start controlling my strobe.

 

The obvious first step was to be able to detect when the strobe was ready to be fired. This should be easy. The strobe raises the X line when it is ready. A digital input should do the trick. But a pure digital input may float high or low when nothing is connected. I was hesitant to resort to using the Arduino internal pull up (or pull down) resistors as I had no idea how that would affect operation of the strobe since the X signal is used for multiple purposes.

 

The strobe raises the X line when it is ready. To about 5 volts when the batteries are fully charged (less than that when the batteries are not at full charge). I was unsure what voltage value would be presented in a low battery situation. Would it be detected by the Arduino as a digital HIGH or a LOW? So I resorted to using an analog input to sample the voltage presented on the X line. I could then arbitrarily decide what voltage "HIGH" was.

 

Next step was firing the Strobe. Simple stuff, just short the X signal line to ground. I had manually done this with a paperclip so I knew it worked fine. How to short something to ground via the Arduino? A digital output should work. But there is the issue of the X line being a bi-directional signal line. Is it an input or an output? The strobe pulls it HIGH to signal ready, the camera pulls it LOW to signal fire. 2 different sources of control for the same signal line. A split personality digital line should work! I attached the X signal to a digital pin which I normally left in input mode (the strobe is in control). To fire the strobe I flipped the digital pin to output mode and set it to LOW (the camera is in control). The strobe fired! Success. Mostly. But sometimes it fired multiple times.

 

My trigger system was the culprit. I had wired in a pushbutton switch to another digital input to act as a manual trigger signal - no need to complicate my life with trying to hook up a camera just yet. But I failed to add debounce logic to my program. So I was reading multiple trigger switch contact closures each time I pressed the pushbutton. At low power settings the strobe was capable of firing faster than I could push and release a switch. So I went back and added debounce logic to all of my inputs - including the X analog signal from the strobe as it had some overshoot on it.

 

The next item to refine was how long to assert the low X? I wanted it to be as short as possible so that it would not interfere with the strobe trying to signal it was ready and so that it would not impact the cycle time. If X was permanently held low the strobe would automatically re-fire every time it recharged (my debounce issue from above). Worst case I needed to let X float before the strobe recharged. A few very rough experiments indicated that 250 microseconds of LOW assertion seemed to work fine. For the YS50 strobe. This is something that I may have to revisit for different models of strobes.

 

At this point I had a working Arduino controller that could trigger my strobe to perform a full dump (the YS50 does not have a power level control). Next step was to add some Quench logic so that I could control the power output of the strobe.



#20 giffenk

giffenk

    Wolf Eel

  • Member
  • PipPip
  • 131 posts
  • Gender:Male
  • Location:Toronto

Posted 24 August 2016 - 08:06 AM

Practical Arduino Quench Control - Part 2

 

The next step was to be able to control the power output of the strobe. The Nikonos TTL wired interface provides a Q (quench) signal line. This is used to instruct the strobe to stop firing. If the Q line is unused the strobe will fire a full dump each time it is triggered. If the Q line is dragged low after the X line then the strobe will stop firing. The longer you wait to assert low on Q the longer the strobe dump is. If you wait too long to assert low on Q then the strobe will perform a full dump. This all works when the strobe is in TTL mode. If the strobe is in manual mode, the Q signal line is ignored.

 

The logic to control the Q line was easily duplicated from my X line control logic. The tricky part was figuring out the time delay for the Q signal in relation to strobe power output. This took a series of experiments were I added some Arduino code that would automatically step through a range of Q delay values. This allowed me to establish minimum and maximum Q assertion delays. The minimum delay always allows the strobe enough time to consistently fire. The maximum delay occurred at the point where the strobe did a full dump. The full dump point was easy to detect as the YS50 strobe has a builtin "TTL" indicator (well not really). A green LED is turned on if the strobe thinks it performed proper TTL. It isn't a true TTL indicator. The strobe has no idea if TTL was achieved. The LED is turned on anytime the strobe does NOT perform a full dump. So the LED is really a not-full-dump indicator.

 

I now had a basic Arduino Quench control program that could be triggered via a push button switch and a means to have the strobe provide different levels of power. But no external control over the power level - we will get to that in a later post.

 

Next on the list was continuous fire mode. This is required if I wanted to support burst mode in the camera. I needed to be able to repeatedly trigger the strobe in rapid succession.

 

The concept was simple: press and hold the push button - have the strobe fire, recharge, fire, recharge, fire, repeat until the button was released. So I added some simple logic to to support this cyclic firing. And once again a simple concept presented a nasty edge case.

 

On a full power setting the YS50 strobe was taking 2 to 4 seconds to recharge (depending upon battery charge level). So it could cycle once every 2 seconds at the fastest. Push the button, hold it for 3 seconds and I would get 2 fires of the strobe. Push and release it quickly and I got a single fire of the strobe. All was well - it works as expected. I then tried it on a low power setting and found I was getting an irregular number of strobe fires each time I pressed the button.  I was unable to achieve just 1 strobe fire at low power. The strobe could fire, recharge and fire again faster than I could press and release the button. My finger was not fast enough to release the push button before the strobe fired several times.

 

The only viable solution was to implement a minimal strobe re-fire interval. I arbitrarily picked 10 flashes per second as a maximum fire rate, which meant a minimum interval of 0.1 seconds. This mostly fixed my problem, but this is definitely an open problem that I will need to readdress once I switch to camera control of the strobe.