E-switch UI Development / FSM

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… ^:)

I pushed some fixes just now:

  • Added reversing to Anduril. Made EV_tick always send 0 while in “hold” state.
  • Rearranged some build options and made sure the build still works if some are turned off.
  • Fixed issue where double-click-from-off followed by double-click-to-true-turbo would overwrite memory with the ceiling level. (should make Agro happy)
  • Fleshed out build options to blink at floor, ceiling, and channel boundaries.
  • Adjusted bike flasher floor and ceiling: floor high enough to make sure it always blinks, ceiling can be higher than halfway up the ramp.

The reversing thing is slightly different than Narsil and Ferrero Rocher. I wanted to make it more predictable without having to remember anything, so if it has been more than a second since the last user input, a “hold” will always go up. However, if the last “hold” went up, there is a 1-second window where the next hold will go down instead. Also, “hold” at the ceiling level always goes down.

So… it reverses, but it doesn’t stay reversed long enough to confuse a goldfish.

I’ll probably leave it enabled by default, since it no longer has the issue with forgetting what direction it’ll go.

As for muggle mode, I’m thinking it’ll be similar to momentary mode where it has no exits (even for “off”). It’ll be very very limited. The tricky part is figuring out where to put its config settings, if it has any.

OTOH, momentary mode makes a pretty decent muggle mode if set to a medium level.

I’m not sure there will be room for extra glitch modes. At least, I’m not prioritizing those.

I think I like this. So after 1-second, reversing is still activated by a click then hold, but the first click ramps up a little bit first?

Nice! How about muggles get access to only on/off and ramping. No blinkies, strobes, or other complex operations.

I agree, but I can already hear my friends whining… “There’s only one brightness?” “Why do I have to hold the button?” :smiley:

I’ll hush up about the blinkies, just don’t take away lightning mode! :smiley:

The “click-release-hold” action is unchanged. It always goes down.

The regular “hold” action still goes up… unless:

  • The user completed a ramp-up less than one second ago.
  • … or the brightness is already at the ceiling.

I just reflashed a Q8 with this newest version of Andúril.

Sometimes a hold from off will remain at moon and not ramp. At first I thought this was only occurring shortly after powering off, but I’ve seen it happen after the light has been off for 30+ seconds. It seems intermittent. I can’t replicate this with my D1 running the previous version of Andúril. Could this be caused by the new ‘1-second’ ramping reverse rule, like it’s trying to ramp down from moon?

Other ramping functions seem normal.

I’m also getting some faint flickering during the ‘steady’ phase of bike flasher mode. It’s very faint, and seems to go away at some brightness levels along the ramp.

Hey, good catch. Fixed.

If turned off while reversed, it could then try to reverse a hold from off. The amount of time it was off doesn’t matter for that, since it doesn’t measure time while off.

About the bike flasher… it runs at ~4 kHz PWM now instead of 15.6 kHz, as a side effect of some power management changes I added a few days ago. I’m not sure if it’s worth fixing or not, since the fix would cost a fair amount of space. Basically, all interruptible “delay” operations run at 1/4 CPU speed. This affects modes which use those, such as biking, battcheck, and beacon. It doesn’t slow down PWM in other modes though, like ramping and goodnight, which have no need for explicit delays.

The upside of this is that things like beacon are now much more efficient for longer runtimes. The downside is that the PWM on a few blinky modes might be visible or audible in some circumstances.

:+1:

Eh, probably not. I only noticed the faint flicker while ceiling bouncing the Q8 to check out the new brighter bike flasher levels. I doubt it would be visible on a bike.

I just reflashed the Q8 again. It sure is nice not needing to fire up the soldering iron!

I’ve got some thoughts about it.

  1. How about clearing mode memory on lockout? You do this on physical lockout already and doing the same on software one seems logical.
    After all if I lock it out, I will probably not use it in a moment.
  2. Independently, time-related functions need to increase power consumption only when they are running. So when mode memory is cleared, you can go back to deep sleep.

Hi TK, can I have Andúril .hex file? I got tons of error when trying to build with Atmel Studio.
Thanks…

Most of the errors are probably due to missing header files.

The complier is looking for a several .c and .h files. You need to download these from TK’s repository.

Some are located here.

Some are located here.

You need to put these files in your project’s folder.

When you create a new Amtel Studio project, it creates a directory structure based on the name of your project. Right click the tab at the top left of Amtel Studio and click “Open Containing Folder.” Drop the .c and .h files into here and run the compiler again.

Another error you are probably encountering is, “Hey, you need to specify ATTINY” in the tk-attiny.h file. Double click the error, then scroll up a few lines and remove the // from one of the lines reading “#define ATTINY” and change the number to the proper ATtiny model number (13, 25, 85 etc.).

Hope this helps!

I’ve got Andúril running on a Q8, D1, and D4 now. I love having several lights with the same awesome UI!

I have an EagleEye X6R with a TA driver running Narsil that I’d like to reflash, too. It has a forward-clicky tailswitch and an e-switch on the head.

I’d like it to light up at the memorized level when powered up, so I can use the tailswitch as momentary.

I found this piece of code but I’m unsure what changes to make:

void setup() {
// blink at power-on to let user know power is connected
set_level(RAMP_SIZE/8);
delay_4ms(3);
set_level(0);
load_config();
push_state(off_state, 0);
}

Am I on the right track?

Also, how can I format code to read properly when posting here? It becomes a mess if I insert spaces at the start of a line.

For that, it will need to save the memorized level to eeprom so it can remember after power loss. And given how often that level changes, it should probably be wear-levelled. This means bringing in the EEPROM_WL code, which isn’t otherwise used in Anduril, and making changes in a few places. It’ll cost more than a few bytes.

Yes, that’s one of the places which will need changes. It’ll need “push_state(steady_state, value_from_eeprom)” instead of going to the “off” state. And, um, get rid of the initial startup blink. :slight_smile:

The other changes are larger though… I should probably add another compile-time option for it, because this is a request which will probably come up frequently.

As for posting code, BLF isn’t very good at that. It can be done, by using a <pre> in the fancy post editor, but usually I don’t bother.