E-switch UI Development / FSM

This sounds great! No turbo for muggles, right?

I vote to omit battery check, or make it a compile-time option. I can already hear my button-mashing friends… “WHY’S IT BLINKING?!” :person_facepalming:

Speaking of muggles, it seems the first thing they do when I hand them a new light is unscrew the tailcap to look at the battery. I’ll have to let them get that over with before I enable muggle mode. :smiley:

I know this, I have the same problem with Tom and the NarsilM cheat sheet. :slight_smile:

TK, I’d like to shorten (nearly eliminate) the delay before ramping when holding the switch from off. I want ramping to start almost immediately.

I poked around in several of the .c and .h files but couldn’t determine where I should make changes.

Could you point me to the code I would need to modify to accomplish this? Thanks!

Ramping starts after 48 frames by default. The first 24 frames allow for a regular click to happen (instead of holding to ramp). The next 24 frames are the window for long-press-for-moon. After that, ramping starts.

Look for EV_click1_hold in off_state, and remove the part about “if (arg >= HOLD_TIMEOUT)”. This should make ramping start about 24 frames sooner. However, it will also eliminate the ability to long-press from off to go to moon.

You could also try reducing the value of HOLD_TIMEOUT or the value of RELEASE_TIMEOUT to speed up the entire interface, but it’ll mean less time to do each click.

Or you could even make it start ramping before it hits HOLD_TIMEOUT, but that will also eliminate the ability to do any clicks of any type from off, unless you’re clever and do some much bigger changes.

If I recall correctly, the way Narsil does it is somewhat different:

  • Frames 1-18: Light is off, release for regular click.
  • Frames 19-41: Light is at moon mode, release for moon.
  • Frames 42+: Ramping.

At least, if I’m reading the code correctly.

In Anduril the sequence is:

  • Frames 1-24: Light is at floor level, release for regular click.
  • Frames 25-48: Light is at floor level, release for floor/moon.
  • Frames 49+: Ramping.

Eliminating the pause at step 2 is easy. Eliminating or reducing the pause at step 1 is not so easy.

I’ll try this. Thanks!

I use low modes frequently, but I might be willing to lose a shortcut to moon to get a slightly shorter delay in ramping up from off.

You could also just give it a smaller value, like 6 to allow a 6-frame window to stop at moon before ramping.

And to make the timing easier, you could make it not turn the light on until that window starts. Slower feedback from off, but it gives a timing hint for the shortcut. Tradeoffs…

I tried a few different values for HOLD_TIMEOUT in fsm_events.h on two Q8s. Here are my findings:

  • 6: can’t reliably power off with single click
  • 10: still some misfires with power off
  • 12: works great, can still shortcut to moon

12 it is! Ramping feels much snappier from off.

Thanks again for the help, TK!

It runs at 62 frames per second, or 0.016 ms per frame. So a value of 12 is just barely under 1/5th of a second.

People have had difficulty with a window of 18 frames on the Q8, and I’ve found that 31 frames feels too long, so I used a default of 24.

Zebralights, IIRC, use a window of 0.5s or 31 frames:

  • Frames 1-31: Light is at low, release to go to high.
  • Frames 32-62: Light is at low, release to stay at low.
  • Frames 63-93: Light is at med, release to stay at med.

Anyway, I just wrapped the definitions of HOLD_TIMEOUT and RELEASE_TIMEOUT to make them definable from the UI code instead of having to dive into headers. So, after this update is pushed, just stick an extra line in the main UI file and it’ll override the toolkit’s defaults.

The HOLD one is how many frames it takes to go from a “press” to a “hold”, or how long a single click can be. The RELEASE one is how many frames it waits after a click to see if another click will happen. To cause a full click event to be sent to the UI code, what happens is…

  • User presses button. “EV_click1_press” event gets sent to the UI code.
  • Anywhere from 1 to HOLD_TIMEOUT frames happens. Let’s say 12 frames.
  • User releases button. “EV_click1_release” event gets sent to the UI code.
  • Light waits RELEASE_TIMEOUT frames, and nothing happens. Now we’re at frame 36.
  • “EV_1click” event gets sent to the UI code, indicating that it was only a single click and it’s too late for a double click to happen.

The events aren’t quite immediate though… they go into a queue and get sent/processed later when the MCU is in an idle loop. In normal circumstances, this only delays things by a few microseconds… enough for the current interrupt (WDT, PCINT, ADC) to finish. I’ve generally been very careful to avoid anything time-consuming during interrupts, because those need to be serviced quickly and then go back to the regular code flow as soon as possible. The queue offloads the time-consuming parts to a safer part of the code.

I’m kind of just rambling now though, twiddling my thumbs while waiting for DHL to show up with new lights.

:+1:

Thank you for the detailed explanation.

With HOLD_TIMEOUT set to 12, I was having an issue where a hold while on would do nothing. I’ve changed the value to 15.

And please make the battery insertion double blink at moonight.

Yeah…it bothers me too. As well as voltage / temperature indication.

Hang on there a minute. On a bright sunny day blinking out temperature or voltage might be rather hard to see if done at moonlight levels. At the risk of adding ANOTHER configuration, it might be nice to be able to select the intensity of these blinks.

With moonlight configured to be really low, maybe, I don’t know. On my D1 / D4 with stock firmware moonlight is easy to see during a day. Actually with D1 it’s well above the threshold of being painful to look at, even during a day.

Though it may not be moonlight. My complaint about the current level is that the amount of light is disturbing.
If I shine it at my hand to avoid disturbing others, the reflection blinds me.
It doesn’t take moonlight to avoid the issue.

The nitecore MH20’s e-switch is blinking the battery voltage when tightening the tailcap, so why not doing the same with the D4’s front emitters and use the 3 clicks for something else ? A shortcut to 7135 100% for example.

Is there a hex file available of Anduril for a TA FET+1+16 (or 8AMCs) driver? I want to order 2 drivers from lexel and would like em to be flashed with anduril, Lexel can flash them for me with any kind of firmware but he needs/wants the hex file as he “can’t calibrate Anduril like he’s used to in Narsil”.
I myself have no clue what a HEX file is used for or if there is any difference between the hex file for a FET+1+8 and a FET+1+16 driver :person_facepalming:

I would like an Andúril.hex for TA L6 driver too.

I got this when trying to build Andúril .hex file

Can someone point me out what is this error means and how to solve it? I would like an Andúril.hex for 2Channel FET+1 driver.

Have you downloaded all of the .h and .c header files required?

See my post here.

Thanks goshdogit, yes I’ve downloaded all the files there and add to the AS project, I think the error is the fsm-adc.c file or its comments, never have this issue when compiling Narsil.