better low modes with dynamic PWM

Great firmware that got even better - Amazing! :beer:

Nope, there’s not much I can do about that. The regulation circuit is running way below its optimal level, and it takes a while to stabilize when things are that low… especially if the driver is hot from being on a high mode.

However, I did add something to make it turn on faster during hold-from-off for moon. It now pulses a higher level for a few milliseconds to “jump start” the regulation circuit and make it wake up sooner. Before adding this, when I needed moon in the middle of the night, the process was:

  • Aim light so I can see the aux LEDs.
  • Hold button until aux LEDs turn off.
  • Release button, and wait while moon warms up.

Now it’s more like other lights, where I can just hold the button and then let go as soon as I see light. It starts significantly faster.

Fixing it properly would require hardware changes, like adding a lower power channel which is more stable for these extra-low modes… but that hasn’t happened, so I tried to at least reduce the issue in firmware.

Due to hardware variability though, some lights will have steady output on moon, and some will have visible flickering. There’s nothing the firmware can do about that. And some lights will start a bit slowly on moon still, while others might have a bit of a “pre-flash”, because the jump-start thing isn’t one-size-fits-all. The jump start could potentially be configurable, but it’ll still start slower after the light was on turbo.

As for this dynamic PWM thing, it mostly just squishes the bottom end of the ramp downward to provide extra precision and smoother ramping for low modes. The results are something like this:

Before: (old KR4 firmware, 2020)

  • 1/150: 0.2 lm
  • 2/150: 0.25 lm
  • 3/150: 2.5 lm (default floor)
  • 4/150: 2.5 lm
  • 5/150: 4.2 lm
  • 6/150: 5.9 lm
  • 7/150: 7.6 lm
  • 120: ~1700 lm
  • 150: ~4000 lm

After:

  • 1/150: 0.20 lm
  • 2/150: 0.30 lm
  • 3/150: 0.45 lm
  • 4/150: 0.65 lm
  • 5/150: 0.90 lm
  • 6/150: 1.20 lm
  • 7/150: 1.55 lm
  • 11/150: ~2.5 lm (default floor)
  • 130: ~1700 lm
  • 150: ~4000 lm

As a side effect, it’s also finally more feasible to include moon in the stepped ramping mode, because the levels are actually spaced pretty close to visually-linear near the bottom. I’m getting pretty good results with a ramp from 1 to 130 in 8 steps.

Anyway, this change improves somethings, but it doesn’t eliminate the driver’s slow stabilization time at low modes. Much like how a human eye takes a while to adapt to darkness after seeing a bright light, the regulation circuit takes a while to adapt to very low power levels after it was burning bright. It’s slow when used at ~0.2% power or lower, especially after coming down from something bright.

Yes, that’s exactly what it’s doing now. It was 10-bit before, which was audible on some lights… but 8-bit is a high enough pitch to make it generally inaudible.

The exact numbers might vary over time as I refine the ramp calculator… but for now, it starts out like this on the DD FET + linear 5A model:

  • 0/16383, 0%
  • 1/16383, 0.006%
  • 1/11750, 0.009%
  • 2/14690, 0.017%
  • 2/9183, 0.021%
  • 3/12439, 0.024%
  • 4/13615, 0.029%
  • 5/13955, 0.035%
  • 6/13877, 0.043%
  • 7/13560, 0.051%
  • 8/13093, 0.061%
  • 9/12529, 0.072%
  • 11/13291, 0.083%
  • 12/12513, 0.096%
  • 14/12756, 0.11%

… but before it went like this:

  • 0/1023: 0%
  • 0/1023: 0%
  • 1/1023: 0.1%
  • 1/1023: 0.1%
  • 2/1023: 0.2%

The real-world numbers are a little more tricky than that, because zero isn’t actually zero… Sending the driver a “zero” signal actually produces about 0.011% of the maximum output. And there’s other error and approximation involved too. The ramp calculator tries to account for that stuff by factoring it into the calculation model, and the model isn’t perfect. But it seems to get close enough for a useful result.

The code running on the attiny chip is simple and easy. The hard part is making the ramp calculator’s model accurate enough to generate a good table of values.

There’s nothing I can do about the driver’s analog noise floor. It’s a property of the hardware. It can flicker randomly by +/- 0.2 lm, so increasing the digital PWM resolution beyond that is mostly pointless. What I did here is increase the digital resolution as far as the analog properties of the driver allow… and it turns out that’s about 12 or 13 bits.

… and then it decreases resolution smoothly to about 8 bits, as it gets brighter. Because higher modes just don’t need to be very precise. A difference of 0.3 lm is very visible when going from 0.3 to 0.6 lm, but it’s completely imperceptible when going from 1000.3 to 1000.6 lm. So it prioritizes precision for low modes, and speed for high modes.

Good to see improvements! Thanks for all your efforts Toykeeper.

Thank you ToyKeeper, that is a brilliant upgrade!

May I please also ask, there used to only be one 219 firmware for each light, to cover both 219c and 219b emitters. Now there seem to be both 219 and 219b. What is the difference and need for there to be 2?

Edit: I just flashed the nonFET to my E21A KR4. I noticed that the SOS mode is not there (not sure if it was before, just compared to some diagram I have).

AFAIK the SOS mode is only enabled for the LT1 build.

If the lights are really making noise I’d worry about the parts shaking themselves loose, particularly the inductor. Sometimes people glop elastomer over those to damp the vibrations, I think.

Anyway, this is great work, using these clever software methods to get the best from the limited hardware. I hope that the hardware can also keep improving.

It’s a capacitor (no inductor in the KR4 driver), and no it isn’t going to pop off.

The kr4-219 build uses 60% FET, while the kr4-219b version is 50% FET. Hank was experimenting with different levels when he started carrying 219B as an emitter option. I’m not sure which one he uses, or if it’s both. If it’s just one though, I’ll probably remove the other one.

This is a normal property of lights which use high-amplitude PWM to adjust brightness. It’s nothing to worry about; just an aesthetic inconvenience. On some lights, sound comes from a tail spring, on some it comes from other parts, and on some it’s not even coming from the torch itself. Rapid thermal expansion and contraction can be heard, even from nearby objects, thanks to the photoacoustic effect. Someone around here actually made a pillow play a song from Star Wars, using only high-intensity light pulses. The same could be done with an infrared laser, to turn arbitrary objects into makeshift speakers from a distance.

Thank you for the explanation. That is very useful to know.

I have modded a couple of Hank’s lights to Nichia 219b a long time ago and they have worked perfectly for a long time. I am sure I am not the only one. I would appreciate it if you kept the 60% FET version available regardless of whether Hank prefers the 50% or 60% FET.

I can't see the OP pics - not sure if you changed something already or not.

Thanks for these tweaks! This probably has usages in many of the newer CC drivers being developed.

I am thinking if this new configuration will work to provide a lower moonlight level for the Lume1 driver.

I can still see them. Strange that some can and others can’t. BTW, I’m using Safari on a MacBook.

I'm on Win 10 running chrome, but also verified they don't wrk for me in Edge. If I "view source" the links in the html source works fine. She hosts them on her http://toykeeper.net/ website.

It’s because of the mixed content policy of Chrome. The images don’t use TLS, but BLF does. In Firefox I just get a warning. Not sure if this is due to a setting or extension.

Just flashed from Anduril 1 to 2 (8-13-21). The low ramp is usable now! The PFM explanation is appreciated as well!

Yeah, sorry about that. It’s complicated, and I haven’t had a lot of time or energy lately since I’m dealing with some health issues. So I don’t end up with a lot of productive time I can use for flashlights or server maintenance. Have mostly had to use that time for seeing doctors, learning medical stuff, and basic life tasks which are now a lot harder than they should be.

But if I get a day or two to work on it, I really need to add https to my site(s).

Don’t worry about the images, take care of your self—your health is the most important thing so spend your energy with that.

One option might be using a free proxy that provides HTTPS termination like Cloudflare. It’s normally simple to set up (if you’re willing to hand over your DNS to them). As with anything like this it has pros and cons and may not fit your needs. If it does then it can be a 10 minute job.

As others have said, health is more important though.

On a KR4-nofet 5a driver (E21A), dynamic PWM seems to work quite well! It’s a much better approach than simply slowing down the ramp as I had tried.

Small heads up - in lockout-mode.c, the JUMP_START_MOON code doesn’t seem to apply to the “click and hold” moon there, which confused me at first as I use that most often (due to autolock).

In normal “off” mode, the jump start does give a noticeable boost to the speed of moon level waking up. Most of the time there’s still a ramp up, but it’s faster. Other times I see a subtle flicker to higher brightness, but nothing eye-searing - if anything, it feels like a nice “yes the flashlight is on” confirmation.

Given this, if anyone wants to compare with/without the moon jump start, try it in “off” (active) versus “lockout” (no jump start).