STAR Firmware by JonnyC - Source Code and Explanation

You can see the latest code here: https://github.com/JCapSolutions/blf-firmware/tree/master/MTN_momentary_temp

The only changes I've made to this is to changed the adc_temp_ticks to a 16 bit variable, and extend the time out. The momentary feature is commented out in my build, as well as the turbo timer.

Like Jon said, it all works, even with a 16 bit variable, until the temp ticks gets too long during the second temperature ramp down. I am feeding the adc with a temperature sensor through another voltage divider so I can use the 1.1V internal reference voltage to compare the temperature sensor against.

Initially I was just using the primary ADC voltage monitoring as a temperature step down, which worked alright, but then I got power hungry and wanted both to work at the same time!

So I think I have it working now. I just went about switching and polling ADC inputs poorly. If anyone else wants to give it a shot it's here...

https://github.com/JCapSolutions/blf-firmware/tree/master/MTN_momentary_temp

Sorry to break the train of thought here…

How much work would it be to almost completely change the UI of the momentary firmware? I am a fast learner (and have already learned alot in this thread), but have very little experience in this kind of thing.

I’m hoping to achieve something like this:

4 modes: Low ≤1, Medium 20, High 60, Turbo 100
90 sec Turbo timer down to High
Low voltage step-down
No mode memory

UI:
From off:
short click (<750ms) = power on low
long press (>750ms) = power on high
press&hold 3sec = short pulse at medium then “locked out” (3 short clicks from “locked” goes to low)

From on:
short click = advance to next mode (cycling L-M-H-T-L-M-H-T, with ‘off’ not in the rotation)
Long press = off

Thanks in advance

Doesn’t sound too bad to implement. I’m assuming you actually want long press while off = turbo, that seems much more sensible to me and is easier to handle I think based on what we already have.

  • Change the long press action while on. (add a conditional to the “//not pressed” else section like this: if mode_idx != 0 {mode_idx = 0;:smiling_imp:. You can’t just shove that behavior into prev_mode() because prev_mode() is used for low battery stepdown.
  • Change the looping behavior to skip the first mode (off) when you advance modes. You can look at the code for prev_mode() in order to figure out the logic for this behavior, it’s simple. (you’ll be implementing that logic in next_mode() of course!) Sorry, I made it more complex than it needed to be. Change the behavior of next_mode() so that the //Wrap around section reads “mode_idx = 1;”, duh!
  • oh, as I snipped your quote I see that I ignored the “lock out” portion of your UI. Right now I’m not sure I like the idea… what is the goal?

I would prefer the long press go to high instead of turbo, but if turbo is considerably easier to implement, I can make that trade-off.

I want to use this in an EDC side-switch light, so the lock-out would keep the light from turning on in my pocket. Alternatively, if I sat on the button in my pocket, it would turn on to high/turbo. With the lockout, sitting on it would either lock itself out, or simply remain locked until a successive 3 clicks.

Changing the UI can be simple or very complicated, depending on the details. If you’re interesting in programming, I suggest diving right into the code and changing it to your heart’s desire, since it can be a fun exercise.

Whenever I can get a couple hours, I’m planning to implement this UI for e-switch lights (using STAR-momentary as a base):

From Off:

  • Long press (~1/3rd second) press to moon
  • Quick click to last mode used
  • Double click to Turbo (or highest mode)
  • If there’s room, longer press to toggle lock

From On:

  • Quick click to Off
  • Press and hold to cycle through modes. (~1/3 second pause at each mode). Release to select mode.
  • Double click to beacon

… and hopefully with the red/green Ferrero Rocher indicator lights still working, or a compile-time option to add a battery check mode somewhere if those indicators aren’t available.

It might take a while to get it all to fit.

Definitely easiest to go directly to Turbo (highest mode). [Also, my opinion is that from off a long press and a short press in order to get into turbo would be a very strange UI decision.] The software lockout you want is more work. I currently use physical lockout for anything I don’t want to turn on by accident. AFAIK making the two changes I described above should cover your entire desired UI - other than lockout and the fact that a long press takes you to turbo.

In the UI you describe a person would be able to enable / disable software lockout only while the light is off? Just looking to improve my understanding of what you’ve described.

May I ask what you guys are using as a temp sensor? Is it the LM45 like Microa is using, a thermistor, or some other thing? I think I want to board this train. :wink:

Here's what Richard emailed me a little while back...

As it turns out, I had a bit of time tonight.

What I’ve implemented so far:

From Off:

  • Long press (~1/3rd second) to moon
  • Short click to last mode used
  • Double click to highest mode
  • Longer press to toggle soft lock-out (~3 seconds). On unlock, it will return to the last mode used before activating lock.

From On:

  • Quick click to Off
  • Press and hold to cycle in low-to-high order through modes (except moon). (~1/2 second pause at each mode). Release to select mode.

The red/green Ferrero Rocher indicator lights work for real-time voltage readout. Turbo step-down works if enabled. I think low-battery stepdown works too, but I haven’t checked yet.

What I haven’t implemented yet:

  • Double-click while on to enter beacon mode (or strobe or something).
  • Battery check mode (for lights without the red/green indicators), and the ability to turn off indicator support.
  • Fast PWM modes, and PWM=0 support. (currently uses only phase-correct)
  • General code cleanup.

The code (and a precompiled version) are available here: (Baton.c, Baton.hex)
http://bazaar.launchpad.net/~toykeeper/flashlight-firmware/trunk/files/head:/ToyKeeper/Ferrero_Rocher/

I should note that it’s built with the moon mode set to PWM=1, so it requires a pretty high-powered light for that to work. A FET or lots and lots of 7135 chips. For anything else, you’ll need to adjust the PWM levels for each mode and recompile.

In my experience more 7135 chips takes a higher PWM level to turn on than less chips. Has your experience been different?

I haven’t tried nearly as many hardware configs as RMM, but I’ve found that 2-8x7135 chips on a nanjg/qlite driver will light up at around PWM=6, while 32x7135 chips on a BLF-SRK driver will light up at PWM=1 (or even PWM=0 in fast mode).

It might not be the number of chips, but rather the design of the driver. I don’t know.

In any case, I haven’t seen a FET which won’t light up at PWM=1, though the output gets really dim at low voltage.

Are you using the 350mA or the 380mA chips on the SRK? The 350s with the rounded tab like you get from FT light up with a lower PWM number than the 380mA "38A" or equivalent chips do. The difference is pronounced enough that I have two different files for the 32x 7135 drivers depending on which binned 7135s are used.

Ah, I’m mostly using the 350mA model. It looks like the 380mA chips might give me a nicer moon mode though. I think ~0.2lm is the sweet spot for a moon mode.

I have data about these:

  • 32x350mA: ~1 lm at PWM=1 (phase-correct) (3xXM-L2)
  • 2x350mA: ~0.7 lm at PWM=6 (fast) (red XP-E2)
  • 4x350mA: ~0.5 lm at PWM=4 (phase-correct) (XP-G2)
  • 5x380mA: ~0.2 lm at PWM=6 (fast) (Nichia 219B)
  • 8x350mA: ?? lm at PWM=9 (fast) (old XM-L T6)

I had no idea the 7135 bin would have this effect, but I like the lower moon mode on the 380mA chips.

Also, old XM-L emitters need a significantly higher PWM level in order to light up. Not sure what the actual output is though, since I took that light apart before measuring it.

I don't know if it is the bin, or the manufacturer.

Hi vex_zg,

I had seen your first post in this matter and I found the idea truly intriguing.

But I lost track of what went on and did not notice your success. It seems your endeavour went widely unnoticed. :frowning:

Would you mind sharing what you added and/or changed in the code?
Did you keep the capacitor value the usual 1yF or did you use a larger one?

I’d be happy to read about it.

I’d like to see the code too. I finally got some drivers with an off-time cap, and am trying to decide how to design the UI for them.

I like short-cycle memory on drivers without the capacitor, and off-time would help with avoiding extra clicks to move from, say, mode 8 to mode 9, but I’m trying to decide if there are any other good enhancements to be made. (especially if I want instant access to both moon and turbo after being off for a while)

i didn’t monitor the thread for a while.
here should be the code:
http://www.codeshare.io/2Vlfm

changes in the UI:

the modes are not circular, instead when doing a short press while in the highest mode, the firmware keeps it in that mode. I wanted to be able to put it and keep it in the highest mode without accidentally missing it, with a few fast clicks.

3 commands you can issue though the reverse clicky switch:

short press->mode advance
long press (cca 1.5s in my case)->mode go back
longer press~~go back to the first mode (same state as turning the light after it has been off for longer than some time~~ 3s in my case)

notes:

5 modes: 2.5mA 25mA 250mA 0.9A 2.8A. These are aproximations from my memory using a 2.8A driver.

added another capacitor level constant to be able to distinguish between short and long presses. This is for a cca 5uF capacitor, so it should be tuned for whatever value you are using.

I might have disabled mode memory, dont’ remember. Also I might have hardcoded mode directions. You can take original firmware and take the snippets from my code.

so, as far as I rememeber, changes are from line 280-305, and in function next_mode(), and the added capacitor level constants

#define CAP_THRESHOLD_SHORT
#define CAP_THRESHOLD_LONG

next step I plan to do: implement and hide modes (strobe) “before” the first (moon) mode so that they can only be accessed immediately after the light has been switched on, using “go back” / longer press of the switch.

edit: if there is interest I can make it more “tidy” so that this is a generic change while keeping all the other regular Star features I might have disabled while researching. I know it can be frustrating to do this yourself for somebody who’s new to this, it was so for me.

edit2: coding detection of a doubleclick is possible, but then how would you distinguish between two short clicks which should advance by 2 modes, and a doubleclick. I think having doubleclicks in the same UI with short clicks would make UI non deterministic.

Now that is a very interesting idea. :slight_smile:

I think “backward from moon” might be a great way to access what I call “impress mode” on a stupidly-bright light I’m making. I wanted something to give me quick access to its brightest mode without interfering with EDC-style use, and that might work really well.

@vex_zg

That’s a really nice adaptation.
I just looked into it and I think I saw what you did.
I perfectly understand that you alter and hardcode the stuff, it’s so much easier if you program it anyway.
A tidy version would certainly help, if you find the time. But you already were extremely helpful.
So thx again.

EDIT: Your code went blue :bigsmile: