E-switch UI Development / FSM

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.

Thanks, TK! I’ll wait for a possible compile-time option for ‘power on at memory.’

In the meantime, would a ‘power up on turbo’ option be less complicated? Possibly something I could add/modify myself? Lexel enabled that in the previous install of Narsil when I ordered the TA driver.

I pushed an update with dual-switch support. It costs 172 bytes, if enabled at compile time, mostly due to bringing in wear-levelling functions.

The current method goes to the memorized level at boot, unless the e-switch is held. Then it goes to moon instead. (er, the bottom of the current ramp, whatever level that is, so it varies per-ramp)