A question for TK and other flashlight coders.

The lights with Anduril software that I own, Q8, SP36, LT1, all use PWM to control brightness.
All 3 run about 15.9kHz when they are above the very lowest brightness. At minimum brightness, the PWM is slower.

I’m curious.
How is the code written to control the PWM frequency and duty cycle?
Is it something related to the timing of an internal clock in the chip?
Is the reason the lowest ramp brightness is a slower PWM because you can’t lower the Duty Cycle enough with the faster frequencies to get to the desired output level? Or is this a function of the driver design?
Could you post an example of the code?

Lights with current/voltage controlled brightness, at least as far as the few examples I own, do not have very fancy options as far as tricks they will play.

How is the code written for a current/voltage controlled light? Is it something that relates to a percentage of the full voltage/current?
An example of the code?

Thanks for the info.
All the Best,

Anduril is open source. Here you can browse it: ~toykeeper/flashlight-firmware/trunk : files for revision 249

There’s a prescaler for the timers in the MCU. It is also possible to change the waveform generation pattern (e.g. fast-PWM, phase correct PWM) which will change the frequency as well.

The reason for the frequency change is the efficiency and response of the AMC7135. They need some time to start regulating and thus have a minimum on-time when used with PWM. http://www.pratikpanda.com/amc7135-pwm-led-control-max-frequency-speed/

It slows down the MCU clock speed at the lowest levels, on PWM-based lights. There are multiple reasons why:

  • It reduces overall power use, making the runtime longer. On moon mode, this can increase runtime by about 3X.
  • It makes the output level more consistent across different voltages. The 7135 chip turns on slower at low voltage, and slowing down the pulses minimizes that effect.
  • It makes the lowest levels less sensitive to variations in the underlying hardware. Different 7135 chips and LEDs have different response times. On some, the rise time may be 3 clock cycles… on others, 5. And on some, it’s even as high as 10 cycles before the LED begins to produce light. This can make the difference between having a moon mode or … not. So it slows down the pulses at the bottom of the ramp, and it means moon is a lot more reliable even when the hardware isn’t consistent.

If it were to run at full speed the whole time instead, it would be really common for moon mode to not work at all… and it would use significantly more power (even in cases where it didn’t produce light).

For lights which use constant current-controlled output instead of PWM, the underlying mechanism is totally different. Instead of a digital signal which turns the LED on and off 16,000 times per second, the regulator chip receives an analog control voltage. This tells it how much current to pass through, from about 0% to 100%, with pretty much arbitrary resolution.

The MCU still generates a digital PWM signal, but it goes through an analog lowpass filter to smooth out the signal into a steady voltage. The MCU only needs to generate pulses fast enough to meet or exceed the frequency of the lowpass filter. If the pulses are too slow, it produces a ripple effect in the control voltage signal, which produces a ripple in the visible brightness. It’s not generally a big problem though, since ripple is much harder to see than full on/off pulses.

On this type of light, slowing down the MCU at low brightness levels isn’t necessarily helpful. It increases the amount of ripple, which can become problematic when it causes the signal to clip at zero. However, changing the MCU speed can still be useful sometimes, because it changes the amount of power being used… and that can have analog effects on other nearby parts of the circuit. For example, the KR4 sends out a steady “zero” signal for moon mode, but it manages to get two different levels of “moon” by changing the MCU clock speed. A faster MCU generates more electrical noise, which causes the regulator chip to slightly increase its output. So it allows the circuit to generate two different levels of “zero”.

Analog circuits are basically black magic.

Thank you for the replies.

Indeed, but where oh where in the 2600 or so lines of code do I look?
Since I don’t know squat about what’s where or named what…
About 500 lines in, my eyes cross and I start to talk in tongues.

Cool, I begin to grasp the concept - if not the execution.
With a rewrite of Anduril, After you get done adding in what everyone wants to see.
I guess you’ll need the driver to have a removable flash card just to hold all the code…

All the Best,

Nah, it’ll still hopefully fit on the same control chips.

The code is organized into two main pieces:

  • FSM: A microkernel, hardware abstraction layer, and UI toolkit. This handles the hardware details and provides an abstract API on which to build applications. It’s like a tiny operating system, like Windows or MacOS… sort of.
  • Anduril: An “application” written to run on top of FSM. This is the part I’m rewriting at the moment… because it has grown enough that it’s kind of a mess.

There are some other simple applications too, but nobody really uses them. Like, there’s a clone of the Olight Baton interface, and a clone of the ZebraLight interface, and a simplified Anduril fork made for Fireflies. Tom was thinking about building a new version of Narsil on top of FSM too, but I’m not sure if he’ll bother. I started on a Meteor UI clone, but got distracted halfway through… and have considered writing a Unicorn clone too, except I haven’t found detailed enough info on how exactly the interface works.

These things would all share the same base layer, so they would be able to run on any of the supported devices. Users could basically pick their favorite hardware and their favorite UI, mixing and matching however they like.

If you’re interested in learning more about how it all works, I’d suggest starting with a simpler UI, like the Baton clone. Or I have a thread here which gives an introduction with some examples.

If you’re still interested I can help you with that. Just send me a message what info you need.

I should probably just get myself a Unicorn. It’s a nice light and Inferion did a great job with it. Plus it’d give me a much better feel for how the UI works, so I’d be able to replicate that feel better.

But I’ve had way too many projects to do, so I have no idea when (or if) it’ll happen. Don’t feel like you have to wait for me; there’s a lot to be said for just diving in and making something. :slight_smile:

I’m inclined to at least finish the Meteor UI first, since I finally added the FSM feature I’d need to implement its 3-stage hold concept… click, short press, or hold. I stopped making the Meteor clone when I ran into that, and didn’t feel like adding a “short press” concept to FSM… but now (in the anduril2 branch) FSM finally sends the press duration as a parameter during button-release events, so the UI could implement that concept without any extra toolkit help.