MY Strobe Controller Blog

  • Thread starter Thread starter KeithG
  • Start date Start date

Please register or login

Welcome to ScubaBoard, the world's largest scuba diving community. Registration is not required to read the forums, but we encourage you to join. Joining has its benefits and enables you to participate in the discussions.

Benefits of registering include

  • Ability to post and comment on topics and discussions.
  • A Free photo gallery to share your dive photos with the world.
  • You can make this box go away

Joining is quick and easy. Log in or Register now!

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.
 
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...
 
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.
 
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 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...
 
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...
 
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.

This 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.
 
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.
 
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.
 
Practical Arduino Quench Control - Part 3

The next step was to hook my Arduino Quench program to a real power level control switch. Seems easy, but once again I hit some interesting potholes along the way.

The Sea & Sea TTL converter housing came with 3 rotating controls:

  • Left - A, B, C, D
  • Right - A, B, C, D
  • Power Level - OFF, Manual, 1, 2, 3, ..., 12
Each of these controls was a multi position rotating switch. Turns out they were all just potentiometers. The OFF setting on the Power Level control was not actually a mechanical off switch. It was just the lowest (or highest) setting on a potentiometer. This made wiring the controls simple. 3 connections needed per control: +5, ground and an analog input connected to the center tap of the pot. For now, I was only interested in the Power Level control. I would read the analog value and use software to interpret what the various switch position settings meant.

A potentiometer is just a variable resistor and they burn energy. Precious energy when you are powering the circuit via a battery. I did not want my pots hooked directly to the battery power. The solution was easy - power them via a digital output pin. I only needed to provide power to the pot any time I wanted to take a reading. Assert a digital output pin just prior to taking a reading and then let it float afterwards. I was worried about getting stable readings but it worked like a charm first time out. I was able to assert the digital output, read the analog input and obtain stable consistent readings. As long as I did not change the switch setting...

The pot featured a set of mechanical detents that corresponded to the different power level settings marked on the exterior of the housing. Rotating up gave a series of consistent values. Rotating down gave a different set of consistent values. Depending upon the direction of rotation a specific power setting gave a different value. Likely due to back lash in the mechanism. Time to deal with the real world. I had to make my code a little more sophisticated and map a range of pot values to each power setting.

Next up was making my Quench program responsive to Power Level control changes. BUT: I wanted to read the pot as few times as possible in order to conserve battery power From my radio communication background I knew vaguely remembered that most humans generally could not perceive changes faster than about 250ms. In other words a 250ms delay appears instantaneous to the majority of people. So there was no need to attempt to read the Power Level control setting every cycle of the Arduino control loop. Reading the potentiometer once every 100ms to 200ms should be often enough to track changes in the control.

I added some logic to flash the red LED on the converter each time the Power Level setting changed. Some experimentation showed that reading the pot every 200ms was fast enough. The LED appeared to flash instantly after I changed the Power Level setting.

I now felt I had the basics under control. Time to add a camera and some real strobes.
 
Don't Forget the Camera!

My test rig and YS50 mule strobe were all working fine. It was now time to get serious and start to hook it up to real equipment.

At first I thought I should tackle jamming the Arduino into the Sea & Sea TTL converter housing. But I decided that I needed 100% confidence in my setup before I started to solder wires to the Arduino. Soldering was a final commitment.

So the next step was to include a real camera into the setup. This required more brain power than I anticipated.

My test setup used a simple pushbutton switch that I used to simulate the camera X signal. The camera drags X to ground to fire the strobe. Simple. My test rig was also simple. I used a digital input in INPUT_HIGH mode and then used the pushbutton switch to short it to ground. This had been working reliably. But only after I had added debounce logic. I could press the switch once to get a single strobe fire, or I could hold the switch closed and the strobe would continue to re-fire as soon as it recharged.

Adding a real camera meant that I needed to provide more sophisticated X signal handling. In the real world the X signal line was a bidirectional control. Both the strobe and the camera signaled information on the same line. The strobe raised the X signal when it was re-charged and ready to fire. The camera shorted the X signal to ground to trigger the strobe to fire. So I needed to provide the camera with a signal that mimicked the strobe X signal. First challenge was how to mimic a signal that was both an output (strobe is ready) and an input (camera shutter activation to fire the strobe). I need to provide the camera with a HIGH X signal so that it could pull it LOW when the camera shutter fired.

The dual purpose (output then input) nature of the single signal line appears to be contradictory. How can a signal line be both an input and an output? It can, but not at the same time. This temporal change in function is the secret sauce. All you need is a single digital input: but you need to flip it between INPUT_HIGH and INPUT mode at different points in time. This split behaviour is somewhat similar to the digital output used to power the Power Level control pot.

I need to pass a HIGH to the camera when the strobe was HIGH and then detect that the camera had pulled it LOW when the shutter was activated. In INPUT_HIGH mode a digital input line will provide a (low current) HIGH signal to the outside world. In normal INPUT mode the digital input provides a LOW signal.

Handling the Camera X was reduced to the following set of simple rules:

  • put the camera X digital input to INPUT_HIGH mode any time the strobe was ready
  • if the strobe is not ready then set camera X digital input to INPUT mode
  • ONLY read the camera X input if the strobe was ready
  • and remember to include the appropriate delay and debouncing logic
My initial efforts required some tweaking to get consistent results. A short delay after flipping to INPUT_HIGH mode was required to avoid getting false LOW readings from the prior INPUT mode. I also needed to reduce the debounce interval as the camera X signal settled much faster than the manual pushbutton contact switch from my test rig.

Initial tests using an old camera worked perfectly. My Arduino Quench logic was fast and stable enough to consistently trigger the YS50 strobe while the camera shutter was open. Substituting my Canon G16 gave the same results.

Time to package it up and go diving!
 
Back
Top Bottom