E-switch UI Development / FSM

I like that idea. I don’t like the indicator toggle in Narsil when you ramp and quickly power off the light. When I want to ‘park’ the light and set memory, I tend to inadvertently disable the indicator. Don’t tell Tom! :smiley:

Yes. It seems intuitive that a solid indicator means ‘ready’ and a non-solid indicator means ‘locked.’

Do I remember you making reference to a ‘heartbeat’ or ‘breathing’ mode? Or something like a MacBook’s ‘sleep’ indicator?

I tried a couple other things. Running at 6.4 MHz seems to drop the PWM speed from 15.6 kHz down to 3 kHz. So that’s no good. I was expecting 12.5 kHz, not 3.0 kHz.

Turning off brownout detection reduces standby drain by quite a bit. Granted, it’s basically dropping from zero to even zeroer, but still. 24.7 uA with BOD enabled, or 0.35 uA without.

0.35 uA. That’s 0.00035 mA or 0.00000035 A. I had to use my Fluke to even measure it, since my regular DMM couldn’t.

So I think I’ll be leaving BOD off… It’s not really used in FSM and it increases standby power by a factor of 700.

It has no effect on non-standby modes though. So, I’m still at 3.6 mA or higher for firefly mode.

Dropping the clock speed to 4 MHz works. Moon mode is then 2.5 mA, but PWM runs at 7.7 kHz instead of 15.6 kHz. So I made it change clock speed depending on the brightness. The bottom ~dozen ramp levels run at 7.7 kHz and everything else runs at 15.6 kHz. This gives more stable and more efficient moon modes without making higher levels audible or strobey.

Long story short, I managed to decrease the lowest level from 5.6 mA to 2.5 mA, while also increasing the brightness from about 0.01 lm to 0.10 lm. This means a usable moon mode’s runtime went from 18 days to 50 days on a 3000 mAh cell. And standby time went from 14 years to 977 years. Not that the cell would last over a decade anyway.

@Toykeeper:

Why don't you use fast pwm with 4 Mhz clock speed all the time? You will still get 15.6 kHz pwm frequency then. I know the problem of not getting zero output with fast pwm and addressed it with:


#define PWM_FAST 0x03
#define PWM_7135 OCR0A
#define PWM_FET OCR0B
#define PWM_OUT_7135 0x80
#define PWM_OUT_FET 0x20

void output_on()
{
// In fast PWM there is a short output peak even when PWM set to 0,
// we just deactivate the PWM output override in this cases.

TCCR0A = PWM_FAST |
((PWM_7135 != 0) ? PWM_OUT_7135 : 0) |
((PWM_FET != 0) ? PWM_OUT_FET : 0);

TCCR0B = 0x01;
}

void output_off()
{
TCCR0A = 0;
TCCR0B = 0;
}

I’m not really worried about getting zero output on PWM=0, since it doesn’t apply to standby mode and it’s easy to add a clause to work around it in set_level(). I’m more concerned about getting a stable moon mode which isn’t voltage-sensitive. The activation time for the 7135 chip is long enough that 15.6 kHz doesn’t really work well at the low end. So, I normally cut speed in half on the lowest modes.

The difference here is that, instead of going from FAST to PHASE mode for moon, it’s going from 8 MHz to 4 MHz.

I don’t want to use fast PWM on higher modes since there’s an issue with PWM=255 not being completely on. It has a short “off” blip each cycle much like PWM=0 has a short “on” blip. And I don’t want less than 15 kHz on higher modes since it’s audible. So those really should be 8 MHz in PHASE mode.

However, it might be worth dropping the speed further at the low end, perhaps using fast PWM at 2 MHz to get 7.7 kHz with even lower power usage. Maybe that could save another half-milliamp or so at moon level.

Edit: Nevermind. That actually increased power use. It ran at the right speed, but using fast PWM also turns on the FET at each PWM pulse (even at 0)… so moon is significantly brighter and power use is higher too, despite the lower clock speed. I guess that’s the answer for “why not use fast PWM?” — because it tickles the FET.

Instead, I can run moon (and just moon) at 2 MHz, a few low modes at 4 MHz, and everything else at 8 MHz. All phase-correct. This gets moon down to 2.1 mA at 4.2 V or 1.3 mA at 3.0 V, and it’s still reasonably stable. Higher modes are unaffected.

So, runtime on moon should be up to about 73 days now.

Have you ever seen this blip at PWM=255 on a scope? According to specs it only happens at PWM=0 (in non inverting mode).

Nope, I don’t have a scope. But a few years ago I tested turbo output both ways and found it was slightly higher in phase-correct mode. That was on attiny13a though, not attiny85v.

In any case, can’t use fast PWM because it tickles the FET when it’s not supposed to be active.

Don’t know why the FET is involved in your setup. Checked my test setup (on breadboard, not a real light) right now with scope and couldn`t see anything unusual regarding the FET. Also programmed my BLF Q8 (own firmware) to use PWM=1 (7135 only) as lowest setting and measured 3.5 mA (at 4 Volt, 4 Mhz clock and fast PWM, CPU running normally, not idle). All LEDs glowing. When sleeping 23 uA (with BOD). Just for comparison.

I also measured about 3.5 mA. It was a downgrade from the 2.5 mA current I was getting before.

The FET is involved because the 7135 chip and FET share a counter. Pins 5 and 6 both do PWM, but they’re tied together. So in fast mode, they’re both affected by the quirk which turns the pin on at PWM=0. This might not be an issue on 3-channel drivers with the FET on pin 3.

The speed of the FET varies with different hardware though, so on some it won’t light up at all at level 0, while on others it’ll be bright enough to see by in the dark.

In my light the FET is not involved. In my code PWM (OC0A and OC0B) is disconnected from the output ports for PWM=0. There is no PWM signal at all in this case. The pins are constantly low when PWM=0.

But I did some investigation with my scope and I guess I found the cause for the difference in current at same clock speed and different pwm modes:

With PWM=1 and fast PWM the duty cycle is twice as long as with phase correct PWM. Due to the way fast PWM works the relationship of pwm value and duty cycle is not linear. So the higher power consumption we see with fast PWM over phase correct PWM is just the about 1.3 mA additional LED current caused by the doubled duty cycle.

I added some dynamic CPU speed management directly into FSM today, instead of doing it in only a few modes of Anduril. If the option is enabled at compile time, it’ll underclock the CPU to save power in a couple circumstances:

  • When the brightness is low enough that CPU power draw is a significant factor in efficiency. (or, low enough that the slower speed shouldn’t be audible)
  • When the UI uses a delay function, like between beacon blinks.

This makes moon mode and all other low modes (like beacon, lockout, goodnight, battcheck, etc) more efficient.

With stuff like this dynamic CPU underclocking, abstracted hardware support, and the multitasking framework, it really feels a lot like writing an OS kernel. It’s much simpler, of course, but still pretty similar.

TK, some time ago I suggested looking at Vf to read junction temperature.
It was a bad idea, I understand that now.
But how about using it as an indicator of temperature gradient or at least direction?

Got Haikelite MF02 today. This light has a really hopeless UI. I thought about reflowing the LED with XHP35 HI, but it won’t work, a full driver swap is needed to make it a good light.
But nevertheless it has a solution to one hardness that I have with D4 UI, which is shared by Andúril.
As a new user of this UI, I would frequently start turbo, want to step back, click once instead of twice and pollute the mode memory with turbo.
Now I don’t make this error, but nevertheless I often have problems to return from turbo. I keep double-clicking, the mode doesn’t change. I don’t really know why. Maybe I somehow have turbo memorized too? After a few trials I unscrew the battery tube.
MF02 steps down from turbo with 1 click. That’s way more natural for me. And if you want tu turn off, you just click again. You can do it very fast, a regular 2-click turns it off.

As we’re on it, I have another note.
I really like mode memory. But only as long as the light’s memory is not longer than mine. Today I blasted myself with a high level again. Not directly, but the reflection from the earth was painful nevertheless.
I believe adding a time limit to mode memory would largely solve the problem.

The driver already uses the temperature’s derivative to decide what to do. It works pretty well, especially in the newest version. That’s how it starts steering before reaching the turn.

I ran into some click-detection issues in the D4 code… issues which have been in every open-source e-switch light I’ve seen for years. In the D4 it seemed to have difficulty detecting very fast clicks or very fast double clicks. I’ve also heard about some similar issues in the Q8, where once in a while, on some lights, clicks just don’t register.

That’s part of why FSM is a complete from-scratch rewrite using different techniques. One of the things it fixes is click detection.

That doesn’t happen in Anduril. It was one of the first things I fixed. Double click to jump up, single click to turn off, and the next single click goes to the previously-memorized value… not turbo.

However, there is one caveat to that — if the ramp ceiling is lower than turbo, and the user does a double-click from off to reach the ceiling, then does a double-click to reach true turbo, it will then remember the ceiling level. This can be avoided though, by turning the light on with a single click and then doing a double click to true turbo. Or by setting the ceiling to the highest level.

I’m undecided on whether that should change, whether return-from-true-turbo should always return to the brightness the user was at before, or if it should specifically exclude moon and turbo from that.

The driver can’t measure time while it’s off, so making memory time out isn’t very feasible unless I increase the standby power significantly to keep the WDT active. There are features I’d like to try which require this though, like an alarm clock mode and a locator flash, so it’s on the todo list.

Thanks for the answers TK.
I’d like to add that the memorization of turbo when I wanted to return to regular mode only aggravated the problem that I had anyway - that the action that was natural for me did something different from what I wanted.
I trained myself to do it right now, but I strongly feel I would have been happier with MT02 style return from turbo.

I’ve been using Andúril on a BLF Q8 and an Emisar D1 for a few days now.

In short, I love Andúril and I want it on all of my lights! :heart_eyes:

I have some ideas for changes and additional features. I know nothing about programming or the time, effort, and space these features may require, so I’m not gonna hold back. :wink:

My favorite features

  • moonlight mode during lockout
  • adjustable momentary output
  • momentary disabled only by power cycling
  • double click from turbo returns to previous output level
  • memory for previously used strobe mode
  • adjustable brightness for bike flasher
  • ‘Lightning Storm’ mode

Ramping

  • option to disable click & hold for ramping down? (ramp changes directions like Narsil)
  • option to disable blink at max regulated output?

Good Night mode

  • option to adjust starting output level?
  • option to adjust time until power off?

Possible bug

  • dimming bike flasher to minimum enables an unbelievably low steady output

I’m not sure what TempCheck is telling me. On a Q8:

  • room temperature light - 8 long blinks
  • after 15 sec turbo - 1 long blink, 1 short blink
  • after 30 sec turbo - 1 long blink, 2 long blinks
  • after 1.5 min turbo - 1 long blink, 7 long blinks
  • after 3 min turbo - 1 long blink, 9 long blinks

More blinkies, please! I realize these are silly and may take up valuable space. If not implemented officially, I may need to learn some C. :smiley:

  • party strobe with random brightness / speed changes
  • defective lightbulb mode
  • candle mode
  • other fun blinky modes TK is holding out on :partying_face:

How about a ’Muggle Mode?’ I’d like to hand the light to someone and say “Click to turn it on and off. Hold the button to adjust the brightness.”

Part of the fun of owning awesome flashlights is sharing them, especially with muggles. I’ve discovered that many of them, even after training, will randomly mash buttons and enter config mode within seconds of holding the light. Some have been known to turn the light off and forget where they put it. An optional beacon mode at ‘power off’ would help shorten hide-n-seek times.

Some ideas for ‘Muggle Mode’

  • disabled only by power cycling
  • uses preset, adjustable ceiling level
  • disables true turbo
  • option to disable double-click shortcut, or become shortcut to ceiling
  • memory works the same as usual
  • disables click & hold to ramp down, holding the button allows ramping both up & down (like Narsil)
  • disables advanced features and config modes
  • disables blinks at max regulated output and at ceiling
  • option to disable power off, instead entering a beacon mode

If I knew anything about programming, my list of suggestions would probably be much shorter. :smiley:

Andúril is my new favorite UI, and I would happily use it as-is until TK’s next ’greatest UI ever.’

Especially for muggles I password protected config mode in my firmware. I don’t want the security settings (voltage, temperature) to be changed.

Neat idea!

I thought the double click being touchy was just me. Thanks for the info!

Thanks for the detailed feedback! :slight_smile:

Reversing — perhaps a compile-time option. After using reversing for a few years and non-reversing for a month or two, I’ve found I like non-reversing better. But it would be a good option at build time.

Blink at max — also a compile-time option. I already added one for blink at moon and blink at channel boundaries, so this fits right in.

Maybe, if there’s room.

Already fixed. This happened because it picks the burst ramp level by multiplying the steady ramp level by 2. At the very bottom of the ramp, though, levels 1 and 2 are actually the same thing, so the burst didn’t change the brightness at all. Easily fixed by using a floor level of 2 instead of 1.

I also increased the bike flasher ceiling so it can run brighter than before.

It should blink out the MCU temperature in C. So, it thinks your room temperature is 8 C, and after 3 minutes on turbo it got up to 19 C. The attiny85 sensor isn’t calibrated though, so this value can be off by quite a bit. Mostly it’s useful as a way to find out what the MCU sees, which can help with setting a temperature limit. But on a Q8, it’ll take quite a while to get hot enough for thermal regulation to activate.

If there’s room. Perhaps on an inconvenient click sequence, like 8 clicks from off?

It’s something I want to try, at least. Not sure if it’ll be in a build for production purposes.

You’re very welcome! Thank you for the excellent UIs!

I think I prefer non-reversing too. If it’s a compile-time option, would it be universal or could reversing be enabled independently for muggle mode?

I meant, “could the blink at channel boundaries be removed?” Compile-time option is fine. I think I’d prefer no blinks at moon, turbo, or boundaries but that’s just me. I know some folks are particular about knowing what circuit they’re on. :smiley:

That’s what I thought, but the scale and the short blink was throwing me off. I think I understand now that a short blink is a zero. One long, one short = 10 C?

Sounds good. Can it be disabled only by power cycling, like momentary?

Ok!

Thanks again for being open to feedback. As I said before, I’m more than thrilled with Andúril as it is! :+1:

You seem to have omitted any mention of additional blinky modes. I *know* you mentioned ‘defective light bulb mode’ somewhere but now I can’t find it… ^:)