E-switch UI Development / FSM

A thought just struck me, and I have to put this out there…

Imagine a website that can build a custom anduril.hex file for you :heart_eyes:

Imagine a GUI, with some simple drop down menus and boxes to tick.
Select host, select emitter. Select or deselect what extras you want.

Perhaps an advanced menu where you could rearrange what 3 clicks, 4 clicks does, etc.

And then boom, it spits out a freshly assembled .hex :slight_smile:

I would wish that in the ramp config of the stepped ramping there was a forth option to adjust the speed of the ramp. I would like it to be a bit faster.
I would also like a way to adjust the button release timeout from a menu for the light to turn off way faster. Like with computer mouse, I prefer quite fast double click, with anduril I tend to activate turbo while I don’t need it.

I kind of think a cool option would be to adjust the turbo level in the software, rather than having to flash a lower turbo version. I think it’d be useful to be able to lower the turbo level to the same as max ramp, meaning double click from off OR on would go to max regulated mode. Basically disabling the FET channel. For the FW3A, the light is really too small to sustain turbo for more than a few seconds anyway, so the option to disable the fet altogether would be interesting. Sort of a better muggle mode, since the FET channel is really what muggles need protecting from.

ToyKeeper, one thing that doesn’t feel right for me with anduril both in stepped and stepless ramping but particularly in stepless ramping is when I’m ramping up and stop too soon (“a tad more light should be just fine”), there is no way to immediately go a bit up.
When inside the window delay, 1H goes down but 1C + 1H also goes down.
Would it be possible to change this ?
I know that I would prefer 1H to always go up and 1C + 1H to always go down because it is how it works outside of the window delay, but to not confuse people who got used to how 1H actually works, would it be possible to have 1C + 1H to go up immediately ?

This is controlled by the compile-time option USE_REVERSING. If you are able to compile Anduril yourself, you can comment that option out in anduril.c (or #undef it in the model config).

IMHO the timeout should be shortened from 1s to maybe 1 or 2 times hold time.

I agree that it could be a useful feature to be able to set the limit of turbo on the fly. Disabling the FET all together probably isn’t feasible as it is used for all unregulated modes, just PWMed to achieve the desired brightness.

Coincidentally, I have a few BLF A6 drivers I’m looking into doing just that (reducing turbo level in the firmware though) so I can use them in single emitter lights without risk of frying the emitter.

@SammysHP, thank you.
I compiled a few times in the past so I should be able to do it again. I changed computer since, so I probably need to reinstall some stuff and read again a few BLF threads to refresh my memory.
I definitely need to dig in the compile time options to make anduril works like I would like. Currently it’s pretty fine except the delayed off to be way to long. I prefer the delayed off over immediate off mainly for not turning off LED (short blink) with a 2C or 1C+1H.
I also need to change the ramp levels. When set to stepped ramping and 5 modes, the steps in brightness doesn’t feel right. The second level after the floor (when set to the lowest (1)) is too bright for me.

With Inferion’s post about using DSM to control output, I’ve been pondering how to possibly add this to FSM. I’m not sure if it will be feasible though. It seems like it would probably require doing the ramp-shape math on the attiny instead of using a full-fledged computer to calculate that… and doing arbitrary power roots in an attiny takes up a lot of space and computing time.

More importantly though, using DSM requires very precise timing on an interrupt which fires off tens of thousands of times per second, and that might not be possible in C. Basically, it changes the PWM duty cycle on every cycle, which allows it to hit in-between levels.

The upside of this is that it could have totally smooth and totally arbitrary adjustment across the entire brightness range, with pretty high resolution. It could potentially also improve thermal regulation, since it’d be doing power calculations in linear space instead of perceptual space. And it should also then be easier to make the turbo level adjustable.

There are a few downsides though:

  • Lots of math required on the attiny chip, to calculate the right values for a multi-channel light with a perceptually-linear ramp.
  • Very tight code loop required, possibly beyond what a C compiler can handle.
  • Probably wouldn’t be feasible to adjust the ramp shape in detail, like how the existing ramp calculator works. For example, on many FET+N+1 drivers, the +N part needs to start significantly above zero, to avoid making the ramp appear to stall at the boundary. This is relatively simple to work around in the current design, but would likely be quite difficult or complicated when using DSM.
  • May be difficult or impossible to get the stepped ramp to exactly hit the channel boundaries.
  • Requires rewriting quite a bit of code, both in the FSM library and in the applications which run on top of it.
  • Requires rewriting the thermal code too, and coming up with completely different abstractions for how the low-level and app-level code interact.

So it’s interesting and I’d like to at least find out if it’s feasible. But I can’t make any promises yet.

A couple months ago, I changed the release timeout from 24 to 18 WDT ticks. This might be enough to make it feel better. If not though, feel free to reduce it more. :slight_smile:

That is largely due to the ramp shape being inconsistent at the bottom end. The effective resolution is not low enough to get the exact levels desired, and I didn’t want to repeat the same level too many times in the ramp, so the lowest part is shortened.

This is something which DSM might help with, but I don’t really know yet. In theory, it might be able to increase the resolution of the bottom end and potentially even make the lowest level lower. But in practice, it might not work.

I think, to start with, I’ll probably refactor the interrupt handlers. It currently handles the logic of those inside the interrupt itself, which is a bit sloppy. If I reduce the interrupts to just setting a “something happened” flag, I can move the logic elsewhere and handle it at a more convenient time. This, in turn, might make it feasible to have the DSM interrupt running all the time without nearly as much timing jitter.

Basically, the DSM interrupt needs to happen every 256 clock cycles, out of the 8 million which happen each second. Or maybe every 137 cycles, or perhaps every 512 or 274. I can work out the exact details later. It’s roughly 30,000 to 60,000 times per second. In any case, this means the MCU must never get stuck in an uninterruptible state for more than ~100 clock cycles, because it would break the DSM timing. So I need to go through and reduce all uninterruptible states to be extremely short, and if necessary, move the longer portions of that code to a less critical place.

It’d also probably improve things in general, and as a side effect would make the sleep code able to react better by knowing what woke it up. This should, for example, eliminate the occasional short blinks in the aux LED blinking mode.

So… that’s step 1.

Then I should be able to at least test the DSM idea to see if it’ll work in C. If so, I can work on all the other steps… and if not, at least I improved something along the way. :slight_smile:

Anyone know how to keep the switch / indicator LEDs the same brightness regardless of main LEDs? Specifically on a SP36. Currently the switch LEDs have low brightness while the main LEDs are in regulation and high when the FET is engaged.

Apologies if asked before, I searched and couldn’t find the answer. Also looked in the code and couldn’t find anything.

I want to highlight this comment. I agree that switching from smooth to stepped in Anduril is a bit too easy, and a 3H might help with that, and really like the idea of 3C as a shortcut to moon. That’s the shortcut to moon on an HDS, so it’s natural for me. I don’t know if there’s a feature vote option, but I think this idea deserves some thought.

[quote=primarycell]

[quote=d_t_a]

I would be in favor of these changes as well.

I tried to implement it yesterday, turned out pretty easy, although I don’t know if it’s such a useful feature for me… will test for some time. Anybody wants to test it with me - save this diff to anduril.patch file next to anduril.c file and run

I finally think I have Studio 7 ready to go, did a test complile on the latest Anduril with the config target being the D4V2. I finally managed to get the full repo on my windows 10 machine. But, at build it is complaining about a missing version.h file and a error in the make file.

The logged errors are:
recipe for target ‘main.o’ failed
version.h: No such file or directory

Indeed, I do not have a version.h file and I cannot find it on the repo.

When I click the main.o error, it loads the makefile and highlights this line…
@echo Building file: $<

Can someone point out what I am doing wrong?

UPDATE:
I did get it to build by commenting out this line:
#define USE_VERSION_CHECK

Right, that file is normally created by the build script.

Since not everyone is using the build script, I added a default version.h file just now. It should clear up the compile error.

I’d love to modify anduril to be like this

–4 clicks from OFF or ON: lockout
–4 clicks from lockout: disable lockout and turn on in last used brigthness

and as it has already been said: change 3 clicks from on to change from stepped/ramping to 3 clicks and hold

That’s in fsm-ramping.c in the USE_INDICATOR_LED_WHILE_RAMPING sections. It’s kind of a mess, honestly. I need to refactor that part of the code to make it cleaner in light of some recent additions.

Ah I see it. Thanks TK :beer:

So in order to keep the switch led on low, am I correct in saying that I can’t just un-define USE_INDICATOR_LED_WHILE_RAMPING but would need to set indicator_led(0)?

Sorry for the delay.

I think you could probably just replace indicator_led((level > 0) + (level > MAX_1x7135)); with indicator_led(level > 0); . That should keep it on low whenever the main LEDs are on.