STAR Firmware by JonnyC - Source Code and Explanation

I’ll be interested to see what you come up with

I wrote a momentary FW based upon STAR momentary with the following mode selection UI.

From OFF:

  • Short press turns ON to last mode.
  • Long press turns ON to moonlight.
  • Double press turns ON to turbo.

From ON:

  • Short press turns OFF.
  • Long press cycles to next mode.
  • Double press cycles to previous mode.

I am trying to replicate the OLight S20 Baton but without flash modes. Any feedback would be welcome.

EDIT: link to code here

Please post your code somewhere and put a link here.

Code can be found here:

Thanks for posting. I will take a look at this soon!

In the meantime I see that your UI description is very similar to what akv was asking for over in this thread: akv - looking for a good value flashlight so I am going to post a link over there. This sounds very good for akv.

You might be interested in Baton.c / Baton.hex in my code repo, under ToyKeeper/Ferrero_Rocher/ . The link is below, in my signature.

It implements the Olight Baton interface (including soft lockout), but without the flash modes.

Thanks for the link. I took a look and Baton.c and see a lot of similarities with my code.

I compiled the code and ran it on my test breadboard and found one quirk. The first press from off results in a dim light which then switches to either the last mode or moon depending on the duration of the press. I think this is because you used FAST PWM always. Changing PWM_MODE to PHASE eliminated this quirk.

Indeed. That’s why the comment at the top of the file says “FAST has side effects when PWM=0, can’t shut off light without putting the MCU to sleep”. :slight_smile:

Unfortunately, PHASE has some downsides too — it’s often audible (high-pitched whine), and it flashes slow enough that it kind of bothers my eyes. So I usually go with FAST instead, if I use only one.

That can be solved with running attiny at 9.6 MHz (-Ulfuse:w:0x76:m)

I had a feeling there was a good reason not to do this… and then wight explained it in another thread. He says:

Also, I think the attiny uses more power at faster clock speeds.

I think I’ll stick with 4.8 MHz for now.

Another potential option to eliminate both the “ghost moon” and audible whine would be to run in phase-correct mode with a PWM ceiling of 128 instead of 255. Or maybe even a ceiling of like 192. Might be high-pitched enough to not be heard. This increases the pulse frequency without increasing the clock speed. The downsides are slightly reduced output resolution and incompatibility with dual PWM.

But if you use PHASE with level of 0, you get true off. You can use FAST for all other levels. For level 255, use PHASE to get true on. This is what is done in STAR_momentary.

I cleaned up the UI and adopted the blink-on-power option from your Baton.c code.

Here is the modified UI:

From OFF:

  • Short press turns ON to last mode.
  • Long press turns ON to moon.
  • Double press turn ON to turbo.

From ON:

  • Short press turns OFF.
  • Long press cycles to next mode. Keep pressing to continue cycling.
  • Double press cycles to previous mode. Keep pressing to continue cycling.

Notes:

  • There is no previous mode from moon. This is to prevent jarring transition from moon to turbo.

I don’t normally use only one. :slight_smile:

The reason STAR-momentary defaults to PHASE at both ends is because I kept bugging JonnyC to do it that way (for exactly the same reason). Most of my other changes have remained separate, but he accepted that one.

As for the Baton UI, I kind of stopped working on it because I found I just didn’t like the interface as much as some others. I’ve mostly been using Ramping_UI_table.c on my e-switch lights instead, or Ferrero_Rocher.c (depends on the light). The ramping UI is similar to Baton, but it does smooth ramping instead of stair-stepping, and it auto-reverses so a long press will go either up or down based on context. I didn’t have enough room to fit a battery check mode or soft lockout though (I’m using realtime batt indicators instead, and no lock).

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.

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 0x75 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 0x7a. I guess that can affect the low voltage operation of the Attiny in a negative manner.

Thoughts or suggestions?

From Post #620

So where in this section do I add that?

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

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.

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

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.