STAR Firmware by JonnyC - Source Code and Explanation

1335 posts / 0 new
Last post
wight
Offline
Last seen: 1 year 8 months ago
Joined: 11/27/2013 - 16:40
Posts: 4969
Location: Virginia, USA

chiefinspectorfinch wrote:
I am aware of voltage limitation but in practice attiny works without problem. Most likely atmel was a bit conservative with voltage specs. Perhaps in extreme conditions (hot or cold) there might be a problem, but in those circumstances I would worry much more for the battery itself…
That’s just not my take on it.

Reading your post it’s almost (but not quite) like you’re looking for an excuse to run out of spec. I’ve seen the tests successfully running other Atmel’s far out of spec. Sure Atmel is conservative! Sure it would take something special to make it not work while slightly out of spec!

… but that brings in the possibility of undefined behavior, and I don’t see a good reason for us to run at 9.6Mhz. A workaround is already present for getting PWM to act the way we want.

Still fine, still on a break. One day I’ll catch up with you folks! previous wight catchup Wink
list of my drivers & variants (A17DD, FET+1 stuff, WIP stuff, etc)

bdiddle
Offline
Last seen: 3 days 15 hours ago
Joined: 12/14/2012 - 14:36
Posts: 814

I am experiencing the whining from PWM on wight’s SO8 and DD+7135 driver. Also on the BLF17DD.

Here is a link to what I am running for the dual-pwm DD+7135 light.
Buzzing dual PWM

I only have the whine in medium and high. Low is using the single 7135 and does not have an audible whine.

I am using the default fuses of 0×75 and 0xFF.

I have tried setting the FAST_PWM_START to 200 so that no set modes would use fast pwm, no change.

Only thing that has worked was setting F_CPU to 9600000 and using the fuse of 0×7a. I guess that can affect the low voltage operation of the Attiny in a negative manner.

Thoughts or suggestions?

Newb

pilotdog68
pilotdog68's picture
Offline
Last seen: 7 months 2 weeks ago
Joined: 05/30/2013 - 23:31
Posts: 6422
Location: Held against my will in IOWA, USA

wight wrote:

  • 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;}). You can’t just shove that behavior into prev_mode() because prev_mode() is used for low battery stepdown.

From Post #620

So where in this section do I add that?

Quote:
//Not pressed if (press_duration > 0 && press_duration < LONG_PRESS_DUR) { // Short press if (low_to_high) { next_mode(); } else { prev_mode(); } } else { // Only do turbo check when switch isn’t pressed #ifdef TURBO if (modes[mode_idx] == 255) { turbo_ticks++; if (turbo_ticks > TURBO_TIMEOUT) { // Go to the previous mode prev_mode(); } } #endif

My Favorite Modded Lights: X6R, S8 , X2R , M6, SP03

Major Projects:  Illuminated Tailcap, TripleDown/TripleStack Driver

pilotdog68
pilotdog68's picture
Offline
Last seen: 7 months 2 weeks ago
Joined: 05/30/2013 - 23:31
Posts: 6422
Location: Held against my will in IOWA, USA

The goal is to have long_press from ‘on’ go straight to ‘off’, not prev_mode
I put it where I thought it belonged, but I’m getting an error when I try to compile

My Favorite Modded Lights: X6R, S8 , X2R , M6, SP03

Major Projects:  Illuminated Tailcap, TripleDown/TripleStack Driver

wight
Offline
Last seen: 1 year 8 months ago
Joined: 11/27/2013 - 16:40
Posts: 4969
Location: Virginia, USA

This made me laugh out loud. I really have absolutely no clue what we were talking about, I’ve got to go back and look.

… OK, so that’s probably the wrong section to put that in. My mistake, I think. More like the “// Long press” section. And my suggested format for the conditional is probably wrong. It should probably be more like this:
if mode_idx != 0 {mode_idx = 0;} else {prev_mode();}

		if (press_duration == LONG_PRESS_DUR) {
			// Long press
			if (low_to_high) {
				if mode_idx != 0 {mode_idx = 0;} else {prev_mode();}
			} else {
				next_mode();
			}			
		}

Note that this only functions with the mode order in one direction. That should be pretty obvious.

Still fine, still on a break. One day I’ll catch up with you folks! previous wight catchup Wink
list of my drivers & variants (A17DD, FET+1 stuff, WIP stuff, etc)

pilotdog68
pilotdog68's picture
Offline
Last seen: 7 months 2 weeks ago
Joined: 05/30/2013 - 23:31
Posts: 6422
Location: Held against my will in IOWA, USA

Thanks, I’ll give it another shot in the morning

Quote:
Note that this only functions with the mode order in one direction. That should be pretty obvious.

I’ve come to like off-time no-memory for most applications, and I think this should operate similarly while still allowing direct access to turbo from off. Moving backwards through the modes isn’t a priority.

My Favorite Modded Lights: X6R, S8 , X2R , M6, SP03

Major Projects:  Illuminated Tailcap, TripleDown/TripleStack Driver

wight
Offline
Last seen: 1 year 8 months ago
Joined: 11/27/2013 - 16:40
Posts: 4969
Location: Virginia, USA

pilotdog68 wrote:
Thanks, I’ll give it another shot in the morning
Quote:
Note that this only functions with the mode order in one direction. That should be pretty obvious.

I’ve come to like off-time no-memory for most applications, and I think this should operate similarly while still allowing direct access to turbo from off. Moving backwards through the modes isn’t a priority.

I meant that it only works for the normal L -> H mode order. Fine for what you are trying to achieve.

If someone attempts to use my advice verbatim after reversing the mode order to H -> L they will not be happy with the result. I don’t see that as a very sensible thing to do, but I thought I’d mention it anyway.

Still fine, still on a break. One day I’ll catch up with you folks! previous wight catchup Wink
list of my drivers & variants (A17DD, FET+1 stuff, WIP stuff, etc)

Microa
Offline
Last seen: 7 hours 49 min ago
Joined: 06/29/2011 - 21:20
Posts: 251

Dear dthoang,

I like your UI which can very quickly select the mode you want. Thank for your sharing.

ToyKeeper
ToyKeeper's picture
Offline
Last seen: 8 hours 10 min ago
Joined: 01/12/2013 - 14:40
Posts: 10811
Location: (469219) 2016 HO3
pilotdog68 wrote:
I’ve come to like off-time no-memory for most applications, and I think this should operate similarly while still allowing direct access to turbo from off. Moving backwards through the modes isn’t a priority.

In C, conditionals go in parenthesis. The general syntax is:

if (something is true) {
  then do this;
} else {
  do this instead;
}

In any case, I agree about off-time no-memory. I prefer my lights to be stateless, mostly. It should respond in a predictable manner from off, instead of doing something different depending on what the user did last time it was on. On clickies, I often don’t even store the last mode in eeprom any more, so it’s truly stateless after it has been off for at least half a second.

For e-switch lights, I think my favorites are UIs which give direct access to min, max, and the last-used mode.

It sounds like you might want to try “Baton” or “Ramping_UI_table”, which both use a short press to turn the light on or off, a long press to ramp while on (or to access moon from off), and a double press to access turbo. One ramps between a few fixed levels, the other ramps smoothly. They’re both under ToyKeeper/Ferrero_Rocher/ at the link in my sig.

Unfortunately, I don’t have anything like STAR-momentary but modified to allow direct shut-off from a middle mode. The closest I have is one which ramps down and shuts off while the button is being held. It’s called Ferrero_Rocher, if you’re curious.

wight
Offline
Last seen: 1 year 8 months ago
Joined: 11/27/2013 - 16:40
Posts: 4969
Location: Virginia, USA

Oops. Sorry for posting code in that sloppy way. If I’d actually tried to compile I’d have caught on eventually…

Still fine, still on a break. One day I’ll catch up with you folks! previous wight catchup Wink
list of my drivers & variants (A17DD, FET+1 stuff, WIP stuff, etc)

pilotdog68
pilotdog68's picture
Offline
Last seen: 7 months 2 weeks ago
Joined: 05/30/2013 - 23:31
Posts: 6422
Location: Held against my will in IOWA, USA

thanks guys, it’s working like a dream!
I also shortened the long_press duration and changed the wrap to mode 2 so moon is only available from off.

My Favorite Modded Lights: X6R, S8 , X2R , M6, SP03

Major Projects:  Illuminated Tailcap, TripleDown/TripleStack Driver

wight
Offline
Last seen: 1 year 8 months ago
Joined: 11/27/2013 - 16:40
Posts: 4969
Location: Virginia, USA

pilotdog68 wrote:
thanks guys, it’s working like a dream!
I also shortened the long_press duration and changed the wrap to mode 2 so moon is only available from off.
What’s your UI structure now?

Still fine, still on a break. One day I’ll catch up with you folks! previous wight catchup Wink
list of my drivers & variants (A17DD, FET+1 stuff, WIP stuff, etc)

pilotdog68
pilotdog68's picture
Offline
Last seen: 7 months 2 weeks ago
Joined: 05/30/2013 - 23:31
Posts: 6422
Location: Held against my will in IOWA, USA

wight wrote:
What’s your UI structure now?

From Off
Click = Next mode (moon, L->H)
Long press = High/turbo

From On
Click = Next mode (L->H, ‘off’ and ‘moon’ are not in the cycle)
Long press = Off

*Long press is only about 1/4 second.
……………
I’m still pondering a lockout function of some sort, but haven’t decided how I want to implement it.

My Favorite Modded Lights: X6R, S8 , X2R , M6, SP03

Major Projects:  Illuminated Tailcap, TripleDown/TripleStack Driver

wight
Offline
Last seen: 1 year 8 months ago
Joined: 11/27/2013 - 16:40
Posts: 4969
Location: Virginia, USA

That sounds fairly simple and reasonable.

Still fine, still on a break. One day I’ll catch up with you folks! previous wight catchup Wink
list of my drivers & variants (A17DD, FET+1 stuff, WIP stuff, etc)

pilotdog68
pilotdog68's picture
Offline
Last seen: 7 months 2 weeks ago
Joined: 05/30/2013 - 23:31
Posts: 6422
Location: Held against my will in IOWA, USA

wight wrote:
That sounds fairly simple and reasonable.

Whereas a reverse-clicky can be hard to learn for a “muggle,” this should be easier because the momentary switch is just 1-position. Clicking always advances modes, and holding turns it off no matter how long or short you hold it.

My Favorite Modded Lights: X6R, S8 , X2R , M6, SP03

Major Projects:  Illuminated Tailcap, TripleDown/TripleStack Driver

wight
Offline
Last seen: 1 year 8 months ago
Joined: 11/27/2013 - 16:40
Posts: 4969
Location: Virginia, USA

pilotdog68 wrote:
wight wrote:
That sounds fairly simple and reasonable.
Whereas a reverse-clicky can be hard to learn for a “muggle,” this should be easier because the momentary switch is just 1-position. Clicking always advances modes, and holding turns it off no matter how long or short you hold it.
Hmm, I see what you are driving at. Rules which are always true. Much easier to learn (not to mention initially comprehend).

Still fine, still on a break. One day I’ll catch up with you folks! previous wight catchup Wink
list of my drivers & variants (A17DD, FET+1 stuff, WIP stuff, etc)

vex_zg
Offline
Last seen: 3 years 5 months ago
Joined: 08/10/2014 - 11:08
Posts: 420
Location: Sweden

having hard time blinking out some numbers (i.e. to blink out results of ADC or voltage or some state variables).

The blink out function works fine, but for some reason, invoking it in while(1) loop in main function causes big lag and sometimes unresponsiveness. I tried to put in inside WDT_off / WDT_on, but with similar unpredictable results.

Has anybody implemented this with success?

This is how I implemented the blinking function:

void blink_single_digit(uint8_t digit)

{

if (digit==0) digit=11;

uint8_t i=0;

PWM_LVL=0;

ALT_PWM_LVL=0;

do { ALT_PWM_LVL=0;

_delay_ms(400);

ALT_PWM_LVL=10;

_delay_ms(400); i++;

}

while (i<digit);

}

This is where and how I invoke it:

while(1)
{ // We will never leave this loop. The WDT will interrupt to check for switch presses and // will change the mode if needed. If this loop detects that the mode has changed, run the // logic for that mode while continuing to check for a mode change.

if (mode_idx != last_mode_idx) {

* blink_single_digit(3);

_delay_ms(1000);

blink_single_digit(3);*

ToyKeeper
ToyKeeper's picture
Offline
Last seen: 8 hours 10 min ago
Joined: 01/12/2013 - 14:40
Posts: 10811
Location: (469219) 2016 HO3

pilotdog68 wrote:
thanks guys, it’s working like a dream!
I also shortened the long_press duration and changed the wrap to mode 2 so moon is only available from off.

From Off
Click = Next mode (moon, L->H)
Long press = High/turbo

From On
Click = Next mode (L->H, ‘off’ and ‘moon’ are not in the cycle)
Long press = Off

*Long press is only about 1/4 second.
……………
I’m still pondering a lockout function of some sort, but haven’t decided how I want to implement it.

This really is very similar to the Baton interface (which already has lock-out implemented), except with long and short presses sort of reversed. Baton does the following:

From off:

  • Short press: go to last-used mode
  • Double press: go to turbo
  • Long press: go to moon mode
  • Longer press: soft lock-out

While on:

  • Short press: turn off
  • Double press: not yet implemented (turns off then on)
  • Long press: next mode (keep holding to keep cycling, skips moon mode and “off” mode)

While locked:

  • Press for 3 seconds to unlock

The default long press is 1/3rd second, but it’s easily tweakable in a #define along with several other options.

I haven’t found a place to put a battery check mode yet, but it does at least support realtime voltage indicator lights. I’m thinking perhaps the lockout mode could be used for battery check if the use sets a #define, and the double-press while on should probably go to another blinky mode like beacon or strobe.

ToyKeeper
ToyKeeper's picture
Offline
Last seen: 8 hours 10 min ago
Joined: 01/12/2013 - 14:40
Posts: 10811
Location: (469219) 2016 HO3

vex_zg wrote:
The blink out function works fine, but for some reason, invoking it in while(1) loop in main function causes big lag and sometimes unresponsiveness. I tried to put in inside WDT_off / WDT_on, but with similar unpredictable results.

What you’re trying to do is basically threading or other parallel programming. This is not going to be easy to do on such a minimal processor.

If it’s in the main loop, that entire loop will be blocked until the blinking readout is done. If you do it in an interrupt handler, you either have to disable interrupts until you’re done (and ignore events) or risk re-entering the handler while it’s already running.

You could do it with threads, but I doubt there’s a preemptive threading library for attiny (and if there is, it probably wouldn’t fit). So, your best option is probably to implement your own cooperative threading or to work both threads into a single logic stream in the main loop. Perhaps build a task queue which gets processed in the main loop but can be interrupted by other events, and the blink digit function would simply add tasks to the queue?

In any case, what I’m saying is it’s probably going to be a bit of a pain since the MCU is designed for only specific types of parallelism and I don’t thank that’s one of them.

pilotdog68
pilotdog68's picture
Offline
Last seen: 7 months 2 weeks ago
Joined: 05/30/2013 - 23:31
Posts: 6422
Location: Held against my will in IOWA, USA
Quote:
This really is very similar to the Baton interface (which already has lock-out implemented), except with long and short presses sort of reversed.

I actually tried baton on my test rig, and it was close to what I wanted, but i thought it would be easier to use plain STAR as my stepping point.
The main things I didn’t like:
- I don’t like to use a double click as a commonly used function (just preference)
- I wanted the cycle to always start at moon, not the last mode.

I do like how you’ve implemented the lockout, but I’d rather have the unlock function to be a double click (just because that’s less likely to happen in a pocket than a long press is)
Is it possible to have a long press from off to lockout, and a double click to unlock to moon?

My Favorite Modded Lights: X6R, S8 , X2R , M6, SP03

Major Projects:  Illuminated Tailcap, TripleDown/TripleStack Driver

ToyKeeper
ToyKeeper's picture
Offline
Last seen: 8 hours 10 min ago
Joined: 01/12/2013 - 14:40
Posts: 10811
Location: (469219) 2016 HO3

pilotdog68 wrote:

I actually tried baton on my test rig, and it was close to what I wanted, but i thought it would be easier to use plain STAR as my stepping point.
The main things I didn’t like:
- I don’t like to use a double click as a commonly used function (just preference)
- I wanted the cycle to always start at moon, not the last mode.

I do like how you’ve implemented the lockout, but I’d rather have the unlock function to be a double click (just because that’s less likely to happen in a pocket than a long press is)
Is it possible to have a long press from off to lockout, and a double click to unlock to moon?

The reason it works that way is simply because I was copying an existing interface. It doesn’t have to stay that way. Smile

I think a double click could be used to unlock; I just haven’t ever tried it.

The memory could also be removed, which would simplify the interface. Or you could, you know, start with STAR-momentary as a base instead… which already works that way. Smile

I probably won’t have time to mess with it for a while, but I wanted to make sure you were aware of it in case it might be useful.

pilotdog68
pilotdog68's picture
Offline
Last seen: 7 months 2 weeks ago
Joined: 05/30/2013 - 23:31
Posts: 6422
Location: Held against my will in IOWA, USA

I have the UI in post #913 working now, I’ll just have to play with the lockout function (probably start by copying from Baton) to get it to my liking.

My Favorite Modded Lights: X6R, S8 , X2R , M6, SP03

Major Projects:  Illuminated Tailcap, TripleDown/TripleStack Driver

vex_zg
Offline
Last seen: 3 years 5 months ago
Joined: 08/10/2014 - 11:08
Posts: 420
Location: Sweden

ToyKeeper wrote:
vex_zg wrote:
The blink out function works fine, but for some reason, invoking it in while(1) loop in main function causes big lag and sometimes unresponsiveness. I tried to put in inside WDT_off / WDT_on, but with similar unpredictable results.

What you’re trying to do is basically threading or other parallel programming. This is not going to be easy to do on such a minimal processor.

If it’s in the main loop, that entire loop will be blocked until the blinking readout is done. If you do it in an interrupt handler, you either have to disable interrupts until you’re done (and ignore events) or risk re-entering the handler while it’s already running.

You could do it with threads, but I doubt there’s a preemptive threading library for attiny (and if there is, it probably wouldn’t fit). So, your best option is probably to implement your own cooperative threading or to work both threads into a single logic stream in the main loop. Perhaps build a task queue which gets processed in the main loop but can be interrupted by other events, and the blink digit function would simply add tasks to the queue?

In any case, what I’m saying is it’s probably going to be a bit of a pain since the MCU is designed for only specific types of parallelism and I don’t thank that’s one of them.

thanks for the explanation. Perhaps I give it a shot with attiny85, I am currently on 998bytes with Attiny13a, with nothing left to cut out.

vex_zg
Offline
Last seen: 3 years 5 months ago
Joined: 08/10/2014 - 11:08
Posts: 420
Location: Sweden

For the record in this thread:

I made a small add-on to star_momentary which dynamically changes the pwm level of the lowest moon mode depending on voltage.

Why?

Because I wanted a lowest moon mode (which is Phase corrected PWM level 2 when using 2 channel / a single 7135), and it doesn’t emit any light below cca 3.1V.

So I implemented a routine to up it to level 3 if the voltage goes below that level, so your light can always be able to work in the lowest available moon mode.

So should anybody be interested, I can share it.

ToyKeeper
ToyKeeper's picture
Offline
Last seen: 8 hours 10 min ago
Joined: 01/12/2013 - 14:40
Posts: 10811
Location: (469219) 2016 HO3

vex_zg wrote:
I made a small add-on to star_momentary which dynamically changes the pwm level of the lowest moon mode depending on voltage.

I did something similar in my cypreus firmware, where “moon” means “fast PWM=0”. It changes the PWM speed according to voltage, so that the moon mode will be less voltage-sensitive. At 4.2V it’ll run at the usual 19 kHz, but at 3.5V it pulses at 2.4 MHz. In-between it adjusts smoothly.

Below 3.5V it mostly just gets too dim to see, but that’s okay because the high-amperage cells I’m using are basically empty at that level anyway so I would need to change the battery.

If you find that changing the PWM level is too big of a jump, you could use PFM to adjust it more smoothly. However, this is incompatible with dual PWM so it won’t work on a driver such as the “moonlight special” with two independent PWM channels.

vex_zg
Offline
Last seen: 3 years 5 months ago
Joined: 08/10/2014 - 11:08
Posts: 420
Location: Sweden

ToyKeeper wrote:
vex_zg wrote:
I made a small add-on to star_momentary which dynamically changes the pwm level of the lowest moon mode depending on voltage.

I did something similar in my cypreus firmware, where “moon” means “fast PWM=0”. It changes the PWM speed according to voltage, so that the moon mode will be less voltage-sensitive. At 4.2V it’ll run at the usual 19 kHz, but at 3.5V it pulses at 2.4 MHz. In-between it adjusts smoothly.

Below 3.5V it mostly just gets too dim to see, but that’s okay because the high-amperage cells I’m using are basically empty at that level anyway so I would need to change the battery.

If you find that changing the PWM level is too big of a jump, you could use PFM to adjust it more smoothly. However, this is incompatible with dual PWM so it won’t work on a driver such as the “moonlight special” with two independent PWM channels.

I don’t know (yet) how to adjust PWM frequency, any tips/code snippets?

Yes, it’s quite a big jump, when I increase it from PWM=2 to 3.

I am only using “secondary” PWM output at those low PWM levels, why would that be a incompatible with adjusting PWM frequency?

pilotdog68
pilotdog68's picture
Offline
Last seen: 7 months 2 weeks ago
Joined: 05/30/2013 - 23:31
Posts: 6422
Location: Held against my will in IOWA, USA

What would it take to add a fast strobe mode? Or is there already an off-time FW that includes a strobe?

EDIT: I see there are a few discussed earlier in the thread, but the links seem to be broken..? (Or maybe it’s my company’s firewall causing that)

My Favorite Modded Lights: X6R, S8 , X2R , M6, SP03

Major Projects:  Illuminated Tailcap, TripleDown/TripleStack Driver

wight
Offline
Last seen: 1 year 8 months ago
Joined: 11/27/2013 - 16:40
Posts: 4969
Location: Virginia, USA

Give post numbers please.

Still fine, still on a break. One day I’ll catch up with you folks! previous wight catchup Wink
list of my drivers & variants (A17DD, FET+1 stuff, WIP stuff, etc)

pilotdog68
pilotdog68's picture
Offline
Last seen: 7 months 2 weeks ago
Joined: 05/30/2013 - 23:31
Posts: 6422
Location: Held against my will in IOWA, USA

wight wrote:
Give post numbers please.

post #248 and on from there. That one sounds like on-time, I assume adapting it for off-time would just be copy/paste?

My Favorite Modded Lights: X6R, S8 , X2R , M6, SP03

Major Projects:  Illuminated Tailcap, TripleDown/TripleStack Driver

wight
Offline
Last seen: 1 year 8 months ago
Joined: 11/27/2013 - 16:40
Posts: 4969
Location: Virginia, USA

pilotdog68 wrote:
wight wrote:
Give post numbers please.

post #248 and on from there. That one sounds like on-time, I assume adapting it for off-time would just be copy/paste?
Yes, must be your company firewall. The code RMM posted was based on STAR_on_time v1.1 (pre dual-PWM). Yes, I expect that it should be simple to move the code over.

It’s a very simple mod. I think that LVP does not function when in strobe mode, but practically speaking I consider this more of a benefit than a risk. If you leave the light in strobe mode for an extended period you likely need the light to flicker more than you need to protect the battery…

Here is a link to the diff vs the original STAR_on_time v1.1 code (pre dual-PWM): https://www.diffchecker.com/6wbp3uu9

Still fine, still on a break. One day I’ll catch up with you folks! previous wight catchup Wink
list of my drivers & variants (A17DD, FET+1 stuff, WIP stuff, etc)

Pages