E-switch UI Development / FSM

I got round to flash Anduril onto my D4S and I think I bricked it.
I just simply copied the command from the first post without reading more about it and now I wish I did…
That’s what I did. Now after pressing the button only aux LEDs blink in low mode.

After this MCU doesn’t respond to anything

Can I still rescue it somehow or do I have to replace ATTiny on the driver?

Forgive me if that’s something obvious but I’m really not too educated on this stuff…

You used totally wrong fuse bits
Only a high voltage flasher may reset the MCU

Doesn’t help if its not flashable anymore you got to replace it

I may send you from Germany a flashed MCU

Best is to carefully unsolder one side leg by leg then folding up a few times to break other side legs

I was gonna say I might be closer and could send you an MCU, but then I realized your in Poland lol.

Sorry, it sucks to brick an MCU. Been there, done that, you’re not alone at least.

You live and learn. Eh…
Could you explain how to do it correctly for the future reference?
Will probably use your offer Lexel and place that long overdue order for couple drivers and get MCU straight away.

Actually how would it work with new ATTiny, do they come preprogrammed or how does one place initial firmware on it?

Excuse stupid questions but have no experience with it.

there are 2 ways of programming
pre solder with a SOIC socket adapter
or past reflow with an SOIC clip pusching on the MCU from above the PCB

indutrially with a pre reflow flashing robot that may be also able to retube/rerail the MCUs after flashing for PCBA machines feeder

Lexel, can you also slightly modify the code of Anduril/Ramping IOS V2 in such a preflashed MCU? With a appropriate remuneration of course.
In Poland it seems almost no one is capable of doing ui flashing related stuff.

I always work with NarsilM and Anduril constantly doing small easy code modification regarding replacing numbers or switching features on or off

But I can not write code itself like changing original code sections

No, not yet. I was trying to find a method which would work for FW3A, but it can’t detect the switch until quite a while after power is connected… and I haven’t added it yet for other lights where it’s easier to do.

So far I only have it on my lightsaber.

Sorry about the bricked MCU. It sucks when that happens… and there’s no easy way to fix it.

Normally, it’s best not to set fuse values at all. Just let them stay as is, and there’s virtually no risk of bricking the MCU. But if you do flash them, I recommend using the bin/flash-*.sh scripts in the firmware repository. They have the correct fuse values; just pick a script which matches your MCU type.

It’s in a few parts of the code — anything which refers to dynamic underclocking. Since it’s a compile-time option, the exact relevant parts of the code are already marked.

Okay, may we see your lightsaber? I wonder if you lean towards the light, or a bit towards the darkness :slight_smile: It seems the darksiders have all the cool toys

I’ve not purchased/ made one yet, but I’m waning. Strangely enough, I feel it’s impractical. Doesn’t do anything more than be a cool thing. Of course I’m also the guy with a bunch of flashlights just sitting on a shelf in my office…



You mean this one?





Here’s a closer look at two sabers I use… green for the good days, purple for the not-so-good days:

The one I’m using a custom driver in, though, is a rainbow saber. It is all colors… sometimes even at the same time.

Good answer! Those are top notch.
Funny, I don’t remember seeing the middle one in the movies though

So, quick question… In the version used on the FW3A, assume ascending ramping… the first buzz in the pattern is 1 full 7135 and the second buzz is 7 full on 7135’s?

When ramping? Are those called buzzes? I think of them as blips, and the buzzes are when the light flutters during config modes.

As for your question, that’s a config option at compile time, but I’m pretty sure the stock firmware the first blip is a helper indicator to let you know you’re at moonlight mode, so absolute bottom of the ramp, barely using 1 7135, and the second blip, which in the default ramp config is also the top of the ramp, is max 7 7135s. I think.

Could be way wrong, but that’s how I understand it

The FW3A has 8 7135s.

It does have 8. 1 in a single channel and 7 in the other channel. It is a 1+7+fet driver. If starting at 1 level moon there is a blip fairly quickly, then another and then ramp top.

It may be just a terminology difference, but here’s how I’ve been using the words:

  • Frame: One timer tick, or about 16ms. There are ~62 frames per second.
  • Blip: Turning off for less than one frame, as a visual indication that something happened. For example, when passing a reference point on the ramp.
  • Blink: Turning on (or going to a brighter level) for a short time, to indicate that something happened. For example, when entering or exiting lockout mode.
  • Buzz / flicker: Switching between two brightness levels quickly (but still slow enough to clearly see). Similar to a strobe, but nowhere near as intense. This is used to indicate that the light is waiting for input from the user.
  • Strobe: Turning on and off completely at a speed of ~4 Hz to ~100 Hz. This is used to irritate people.

Anduril on the FW3A does up to four blips while ramping up from the lowest to highest level. Hold from off, and these blips may happen:

  • At ~0.4s, to indicate the button has been held long enough to count as a “hold” instead of a “click”. Let go immediately to stay at the floor level, or keep holding to ramp up.
  • At ~1.5s, when going from 1x7135 chip to 1+7x7135. Happens at ~130 lm.
  • At ~2.5s, when going from 8x7135 to 8+FET. Happens at ~900 lm.
  • At the top end of the ramp, to indicate the ceiling has been reached.

However, depending on where the floor and ceiling are configured, the two middle ones may or may not actually happen. Or they may be at exactly the same level as another blip, in which case only one happens. In the default configuration, the 8x7135 to FET blip is the same level as the ceiling, so only one happens.

It also buzzes or flickers in the ramp config mode, to tell the user when they can click to enter a new value. It goes for 3 seconds, or until the user stops clicking for at least 3 seconds. Each click is confirmed by a blink.

Unrelated question: I'm trying to set double click from off to turbo instead of max ramp.

I've taken this line from the double click from on section of the code: "set_level(MAX_LEVEL);"

And I've added it to the double click from off section of the code, to change it from this:

" else if (event == EV_2clicks) { set_state(steady_state, MAX_LEVEL); return MISCHIEF_MANAGED;

To this: " else if (event == EV_2clicks) { set_state(steady_state, MAX_LEVEL); set_level(MAX_LEVEL); return MISCHIEF_MANAGED;"

This seems to work, but I don't understand why. And I couldn't find any other references to MAX_LEVEL in the main code, though now that I think of it it's probably in FSM somewhere.. hmm.

Anyway, is this the correct implementation?

Adding a set_level(MAX_LEVEL) right after changing the state works right now, but it’s not guaranteed to work in the future. The reason why it works is due to a quirk of the execution order:

  1. set_state() tells FSM to replace the top of the state stack with something new.
  2. FSM handles this immediately, causing the new state’s EV_enter handler to be called.
  3. steady_state :: EV_enter calculates the brightness to use by calling nearest_level() . It also activates this brightness level.
  4. Control returns to the old state for just a moment, where it calls set_level() and overrides what steady_state just did.

But this isn’t guaranteed, because at some point the lower-level code might be changed to defer the EV_enter event handler until after the old state returns. Events are asynchronous, so their exact timing should not be expected to happen with any particular order or timing. It behaves in a synchronous manner in this case, but it might not always be that way. FSM probably should do this instead:

  1. set_state() tells FSM to replace the top of the stack, so FSM puts this change into the queue to handle later.
  2. off_state()’s code finishes running and returns.
  3. FSM handles the state change event. off_state :: EV_exit gets called, then steady_state :: EV_enter, in that order.

So it might instead be cleaner or safer to remove or change the clause which checks the brightness while entering the steady state. Like, if the EV_enter parameter happens to equal turbo, go to that directly instead of using nearest_level() to verify the values. This would work even if I fix FSM to make it queue state changes instead of doing them immediately.

Some recent updates which are now published:

  • Added a compile-time option to select between press-on and release-on, and between release-off and timeout-off. This determines when the light responds to a single click to turn the light on or off… responding at button press, at button release, or at the event timeout. This has been requested quite a bit.
  • Changed the default turn-on timing from press-on to release-on. This makes it easier to tell when to let go for staying at the lowest level, because the light doesn’t turn on before then. (when compiled with press-on, it’ll still have the moon timing hint)
  • Made the button release timeout a bit faster, so the light should turn off a bit sooner after one click. Also, any multi-click events need to be done slightly faster, but it should still be easy to do. The timing now matches Olight’s products instead of ZebraLight. (went from ~384ms to ~288ms, or from 24 frames to 18 frames)
  • Added a user-configurable runtime option to switch between automatic memory (default) and manual memory. Some people call this “no memory” or “forced preset”. In manual mode, one click from off turns on at the same level each time, regardless of what level it was in during the previous session. To configure it:
    • Turn the light on and ramp to the desired level, then click 5 times. This enables manual memory and saves the current brightness level.
    • To go back to automatic memory, turn the light on then click 5 times… but hold the last click. So, click-click-click-click-hold.
  • Added support for the Fireflies E01.
  • Added support for the BLF LT1 lantern. Included in this is support for tint ramping.
  • Rewrote thermal regulation. It doesn’t seem to need the hard turbo drop option any more, and it’s much more stable when it reaches its ideal level.
  • Made ramp-able strobe modes auto-reverse like the regular ramping mode. So, after holding to adjust, releasing and holding again within a second goes the other way.
  • Enabled fancy (2-level) momentary moon by default in lockout mode. The second click uses the other ramp floor. So if you need a bit more (or less) light during lockout, it’s available.
  • Made momentary mode support strobes. To do this, go to a strobe mode, turn the light off, then start up momentary mode. Or, to do a regular momentary mode, go to a regular ramp level, then turn the light off, then start up momentary mode. Basically, it’ll do momentary in whatever mode you were just using, as long as it was a ramp or a strobe-group mode. Momentary strobes are useful for light painting.
  • Made candle mode a little more calm but also able to burn a bit brighter sometimes.
  • Fixed a tiny bug in lightning mode (it didn’t use the top 7 ramp levels before).

New builds are up in the usual place. I count 19 different build targets now.

If anyone has the ability to reflash easily, testing is appreciated. :slight_smile: