I made a UI toolkit for e-switch lights. It makes new UIs relatively easy to create, makes porting UIs to new hardware relatively easy, and makes bugs relatively easy to avoid. But that still leaves a big question:
What makes a good e-switch UI?
So I’m hoping to get some discussion going about what people want in a UI. What’s good, BLF?
The UI toolkit is called Spaghetti Monster, or FSM for short.
(pictured: the [insert your preferred F-word] Spaghetti Monster)
FSM implements an event-driven finite state machine for cooperative multitasking, and attempts to abstract out most of the hardware-specific details so the main code can focus entirely in the interface.
The basic idea is that you #define some options, #include a single file, and then start writing a UI. The UI consists of one or more State objects for the finite state machine, a setup() function, a loop() function, and whatever else you need for the particular UI.
State objects are actually just callback functions. They take an Event type and a 16-bit integer parameter, and they are expected to return "EVENT_HANDLED" or "EVENT_NOT_HANDLED" depending on whether they do anything with the Event they're given. States can be stacked, so if the top-most State doesn't handle an Event, an underlying State gets a chance to handle it instead. The stacking also means it's possible to have utility States which do common tasks like "ask the user to enter a number, then return to the previous state". It can just pop() itself off the stack and return to the previous State without having to care what that State was.
The setup() function runs once every time power is connected. It should do things like loading eeprom and then pushing a default State onto the stack.
The loop() function runs repeatedly, whenever the MCU is otherwise idle. It's for doing long-running tasks, like blinking out a SOS pattern... or for tasks which shouldn't happen until the system is idle, like going into standby mode.
It can also have a low_voltage() function which runs whenever LVP activates, or this can be implemented by handling the EV_voltage_low Event on a per-state basis. Similar story for thermal regulation.
Otherwise most of the UI code ends up fairly similar to how I usually describe UIs. It's a list of States, and each State has a list of Events it accepts and the corresponding actions to take for each Event.
For example, let's say we wanted the following UI, similar to an Olight Baton:
The code would look something like this:
That's pretty much all it takes to implement a very basic Baton-like stepped ramping UI.
This example is only missing a couple small things to make it actually compile and run, like the config #defines and #include at the top, some declarations, and a ramp table for PWM values. It's intended as a simple introduction to how FSM works. Or for a more complete version which has more features, here is one which actually compiles.
I hope it's fairly easy to read, as far as C code goes, and easy to modify. The point of all this is to take the "spaghetti code" normally involved in writing firmware... and lock it in a box where you don't have to see it or care about it. All the spaghetti bits are hidden away under the hood.
The code is available in two branches... "trunk" for the stable version, or the "fsm" branch for more up-to-date development:
http://bazaar.launchpad.net/~toykeeper/flashlight-firmware/fsm/files/head:/ToyKeeper/spaghetti-monster/
Here’s a summary of FSM-based interfaces created so far.
Momentary
A simple on-off interface.
Mostly added as an example.
Baton
Similar to the Olight Baton series.
From off:
While on:
Soft lockout:
Includes LVP and thermal regulation.
DarkHorse
Nearly exact clone of Zebralight’s UI from 2016.
From off:
Low/med/high modes:
Battcheck mode:
Blinky mode:
Remembers a few things after battery change:
Includes LVP and thermal regulation.
Andúril
Fancy all-in-one UI inspired by Tom E’s fantastic Narsil. It’s still a work in progress, so it’s expected to change.
I should probably mention that the smooth and discrete ramps have independent floor/ceiling values. You can have one with the ceiling all the way up, and one with the ceiling at a comfortable safe level. Or you can have one with moon and one without.
Discrete ramp mode has anywhere from 2 to 150 steps, spaced evenly (or as close to “even” as possible with integers).
A “hold” always ramps up, and a “click-release-hold” always ramps down.
Sorry about the 5-click action for momentary mode. Too many states available from “off”.
Beacon and momentary mode use the last-ramped brightness level.
Momentary mode is permanent until power is disconnected.
“Good night” mode starts at low and slowly ramps down for an hour, then shuts itself off. Intended for tail-standing next to a bed at night.
I set the PWM levels to start at 1/255. Depending on the hardware, this may be too low to make any light. However, the ramp floor can be set to whatever level you think looks good.
Config modes are similar to bistro — they blink out a number, pause, then “buzz” for a while. Click during the “buzz” to set a new value. It’ll keep buzzing as long as you keep clicking. If you want to skip an option, just wait without clicking.
Settings which are remembered after a battery change:
Includes LVP and smooth thermal regulation.
Werner Dual-Switch
Since it’s a thing people might want, and since I think Lexel may have been requesting it, I took a moment to make a Werner-style momentary UI, side e-switch plus tail clicky-switch.
https://code.launchpad.net/~toykeeper/flashlight-firmware/fsm
The short version is:
While completely off (power disconnected):
While on (regular “on” mode):
In utility mode:
Battcheck mode: Blinks out battery voltage.
Tempcheck mode: Blinks out current temperature in C.
Ramp config:
Thermal config:
Includes LVP and smooth thermal regulation, copied directly from Anduril.
I think there’s 2 good types of UI:
1) one that is so simple that it works for everyone without thinking, on-off is one of those glorious UI’s, but ramp up-ramp down is another one. There’s no objection against safety measures going on in the background, like reverse polarity protection, LVP and thermal management.
2) a UI that can be configured to anyone’s preferred simple or difficult UI, so also the ones in 1) , but any variation should be possible. Key is that once it is configured, you just notice your simple UI and no surprises happen like unintended strobes or blasts in your face. I was very charmed by led4power’s LD3 user interface, although it is a clicky UI.
(If the BLF-A6 driver was available in just ramp up/ramp down with background safety stuff, I would swap all my drivers.)
link to djozz tests
I think NarsilM is close to be perfect,
if you like more options to play with and understand how to change the settings
also in modes its quite simple to operate
[Reviews] Miboxer C4-12, C2-4k+6k, C2, C4 / Astrolux K1, MF01, MF02, S42, K01, TI3A / BLF Q8 / Kalrus G35, XT11GT / Nitefox UT20 / Niwalker BK-FA30S / Sofirn SF36, SP35 / Imalent DM21TW / Wuben I333 / Ravemen PR1200 / CL06 lantern / Xanes headlamp
[Mods] Skilhunt H03 short / Klarus XT11GT, XT12GTS / Zebralight SC50+ / Imalent DM21TW / colorful anodisation
[Sale]
Drivers: overview of sizes and types
DD+AMC based drivers Anduril or Bistro OTSM 12-24mm, S42, 24-30mm L6, Q8, MF01(S), MT03, TN42
Anduril or Bistro 8A buck driver for 20-30mm, MF01/02/04, TN40/42, Lumintop GT, MT09R
UVC and UVC+UVA drivers
programming key
Remote switch tail DD board with FET
Aux boards:
Emisar D1, D1S, D4, D4S, D18, Lumintop FW3A, Fireflies ROT66, Astrolux MF01, Tail boards like S2+
I filled in the “reserved” posts #2 and #3 with a summary of the toolkit and a summary of what has been made with it so far.
I agree that NarsilM is pretty dang spiffy, to use some awkwardly mild words for it. I always wanted to change a few things though, which is how I ended up with the unnamed UI in comment #3.
I don’t know what to call it though. Maybe I should call it “Supafly”.
I’m not sure if it would interest you, but have you looked at Crescendo? It runs on a BLF-A6 driver and does smooth ramp up/down with background safety stuff like LVP and thermal regulation.
Also a bunch of blinkies, but those can be compiled out or avoided.
that deathstar moon…
May I ask, what is the Good Night blinkie mode?
May you be touched by its noodly appendages.
Keep up the great work
The “good night” mode starts at “low” and slowly ramps down for an hour, then shuts itself off.
It’s not really a blinky, but there wasn’t a more appropriate place to put it. And I like to do battcheck on the way to goodnight, so that puts them right next to each other. Perhaps I should call that group “specials” or something instead of “blinkies”.
Thumbs up to “unnamed” and crescendo. Both perfect
I really would like to see something like an HDS clicky UI.
I’m still using my HDS with SSC P4 (100 lumens) despite its dim LED just because of the excellent tint + CRI and very particular UI.
I didn’t play with most recent UI then I don’t know if HDS UI is still worth it.
The term ‘goddess’ is well-deserved. Wish i knew you in the everyday.
Nothing travels faster than the speed of light with the possible exception of bad news, which obeys its own special laws. – Douglas Adams
I hope “unnamed” makes it’s way into some drivers. I have some nice lights that have uninspired UIs, I would gut them all in a heartbeat for this.
It looks like a fast click always leads to OFF, that is great in case a user has a finger spasm or a non-flashoholic gets a hold of it and starts spazzing with the button.
Just turn it off.
I used to love the programming options of HDS and Liteflux but they have gotten way too expensive for me.
Beacons, strobes, the brilliant Good Night, they’ll all get used.
Some O-lights have a little 1 or 2 minute timer, I’ve always wondered why they didn’t make it longer. It’s pretty cool to put next to the bed at night…well… cool for 2 minutes. One that ramps down over the course of an hour would get used every night.
Maybe this will show up in the D1?
Great work TK!!
I decided to try cloning the Meteor M43 UI tonight.
First I cloned UI1 — no problem.
Cloned UI2 — no problem.
Started on UI3 and then I noticed… it has different actions defined for “short click”, “long click”, and “hold”. And different actions for “two short clicks”, “short click then long click”, and “short click, then hold”.
No wonder I could never get some of the actions to work reliably.
Otherwise it’s going well though. I’ll continue later when I get my palm unstuck from my forehead.
In SM: Unnamed
what is the difference between
from OFF: 2 fast clicks
from OFF: click, then hold ?
Are the tips of the two green arrows pointing right?
My guess:
from OFF: 2 fast clicks
go to a temperature secure level below TURBO.
If I want then TURBO I must double click.
from OFF: click, then hold
goes to the same line. o_O
maybe this should point directly to TURBO?
Joe
I’m really liking the looks of the unnamed UI. The user configurable floor and ceiling within the ramp range is a very nice feature. I also like the ability to switch between smooth and discrete ramping on the fly without going into configuration settings.
Awesome work as always.
If you double-click from off, it goes to the ramp ceiling level and stays there.
If you click, release, then hold from off, it goes to the ramp ceiling level and ramps down. It’s like a double click, except you hold the second click and it ramps until you let go.
Basically, it lets you navigate from the top or bottom from off. So, there isn’t really any need to configure whether modes are in low-to-high vs high-to-low order, because you get both.
Great work as usual TK!
Regarding the question “what is the best single side switch UI”, i share djozz comments.
Apart from my personal preferences the one thing that worries me the most is whether a non flashaolic can use a light without any explanation. We enthusiasts tend to forget about it, but most people only think about flashlights as something you turn on and off, providing a decent brightness level – not moon/firefly or blindingly bright turbo either. A mid level usually provides more then what they would expect anyway.
Some UIs offer different mode groups, including a ‘simple’ one, but you have to switch group and you may not be around to do so if someone needs the light on his own or in an emergency. So i think the above described behavior should be the default in any UI.
As a side note, i’ve witnessed that ‘people’ can easily resort to a long press if things don’t act has they expect. It seems natural to press a switch harder and longer when in doubt. That’s something to consider while designing a UI.
One of my favorite UI is the DQG Tiny 26650 3rd. Single click goes off/mid/off – providing 8 hours at 600 lumen. Long press from off goes to turbo then single click off. While on, long press cycles through modes.
I did also like the good old SRK style UI. off/high/mid/off all single clicks. Anyone can figure it out. I’d rather have off/low/mid/high/off but you get the idea. Double click goes disco on some.
These are awesome!
SupaFly is just that!
I would love to get Crescendo on a couple of my A6 drivers, but would never be able to accomplish this myself.
Since this is the proper place for it, my suggestion was to turn the double blink when installing a new battery to moonlight instead of something bright like now. Reason: If you unscrew the cap for lockout and use the light in the middle of the night, you have to see 2 bright flashes first.
Second was no memorized moon or turbo since shortcuts already exist (this was someone else’s suggestion which I liked)
Thank you!
My rookie input...
Make a simple from off, hold button to ramp ui, 1 click to memory and devote the rest of resources to a better Thermal regulation sampling system and smooth hiccup free ramp.
Going on the premise of heat is the worst enemy of durability/longevity/lumens,,,
Then maybe create an advanced ui/hardware that allows individual heat sensors for each led to show/control its individual performance, maybe helping troubleshoot a problem with that led circuit/dtp/etc, that makes it run hotter, lower lumen, etc, With a hardware/ui system that lets one turn on/off each individual led and regulate power level of each led...? this would be a flashoholic only Ui, or maybe just a pipe dream...lol
My only fear is on improving the heat reg is that the on chip heat regulation/sensor without remote sensor is not ideal for the fastest most precise, consistent, efficient heat regulation. So until a dedicated circuit/chip is used, maybe with a remote sensor soldered on the dtp, then all the software in the world won't help..?
jmo
Hi TK.
Is it possible to share the unnamed firmware?
Thanks.
Ah, thanks.
I couldn’t get that from the flowchart
The “good night” mode sounds great. If the timer in a flashlight is good enough for that kind of thing then I wonder if you could make an alarm clock mode that slowly ramps up the light after a programmed (with clicks) time.
https://davestechreviews.wordpress.com/ / Email: <my BLF username>@gmail.com
In general terms, I agree. The tricky part is translating that to specific implementation details — especially if the UI is intended to satisfy both enthusiasts and muggles.
The common 3-mode SK-68 UI (high, low, strobe) is very muggle-friendly but enthusiasts usually hate it. Or the HiveLD driver has lots of features for enthusiasts, but it requires a 9-page manual to operate, and setting config options requires a soldering iron and a metronome.
Getting both power and simplicity at the same time is somewhat tricky. The “unnamed” UI definitely errs more toward power and less toward simplicity. That’s kind of the point of it though — to be fancy and full of features that I want on my personal lights.
That was a thing I left alone in the D4 interface. On my custom UIs though, I generally do a single very-quick blink when power is connected. Very very quick. Unless it’s intended for a dual-switch light (e-switch and power cut switch), in which case it definitely shouldn’t blink at power-on.
The quick blink can be just as bright, but it doesn’t look as bright because it’s so short. Regardless, if you don’t want to be seen, it’s a good idea to cover the front of the light while tightening the tailcap.
It could perhaps be made optional, or I could maybe add a lockout config option to specify whether lockout blinks on exit or not. With soft lockout on 4 clicks, I usually go for that instead of unscrewing the tailcap. Perhaps it could have two or three modes: blink on exit, moon on exit, or no feedback at all.
I have some ideas for improving thermal regulation, and plan to try them soon. It won’t take the entire rest of the ROM though.
About the ramp blinks, those are there because people requested it. Before, the ramp was actually too smooth and left people feeling lost, with no idea how bright it was or how long it would run.
But if the space isn’t needed for other things, it would be relatively easy to add an option to toggle the ramp blinks.
Bingo. That’s not a software thing. The software has access to only one pixel, one button, and one poorly-placed thermal sensor.
Yes, but not quite yet. I’m still working out a few details. Mostly trying to coordinate with other people, which takes time.
The timer is pretty good (in my test, it timed an hour to a precision of less than a second), but waiting 8 hours before turning on is a little tricky. It would mean one of the following:
I don’t like that first one, because 5mA is really high for a mode where it isn’t doing anything. I may be able to make the second one happen though, and it might be kind of nice for other things too (like controlling an indicator LED during standby mode).
In any case, if you want a light to blast in your face each morning, that might be do-able.
(it’s just going to need a bit of plumbing work first)
(OTOH, timers exist which plug into wall outlets and turn on whatever they’re connected to at a specified time, so that’s probably a cheaper and easier way to do it)
TK, as you already stated, a refined thermal regulation would be a welcome feature. Perhaps the possibility to config in the ui it’s sensitivity to react to temperatures changes, and the correspondent amount of decrease and increase of power to the emitter(s), would permit a fine tune of this function to the many different setups that we use in ours lights (small and big hosts, single and multiple emitters, drasticaly different levels of driver current etc).
I have a SRK with Q8 driver, and a D4, and hopefully soon a D1, to test on. If I can make the thermal regulation “just work” on all those, it’ll probably be flexible enough for most purposes with no need to fine-tune anything. Hopefully the physical traits (like power level and thermal mass) will give the regulation enough feedback to adjust itself. Like, a big light heats up slower so it can react slower or in smaller steps.
However, that said, at a firmware level there are quite a few knobs to tweak, to make sure it reacts at the right speed and intensity without oscillating. And I need to test with tail-standing and no fan, since that was a scenario where the D4’s regulation would over-shoot and then take a long time to recover. It did fine with a hand to sink heat to, or with moving air, but the stagnant air case didn’t behave very well.
TK is it possible to add in the blinkies the heart beat and the sos like Crescendo have?
Sure, it would be easy to add heart beacon and SOS. I’m not sure it would add much though… It already has a beacon with adjustable frequency and brightness, and the momentary mode is good for sending Morse code.
Does anyone actually use SOS?
Pages