STAR Firmware by JonnyC - Source Code and Explanation

Are you using the standard Star off time as can be found in the link in your signature? That code really isn’t optimized. There are a lot of things you can do to minimize space. For example:

Instead of having all of those defines for modes, just make a simple array without all of this “#ifdef” and “mode_cnt” stuff. I mean, when you compile the hex file you know how many modes you’re going to have anyway:

static uint8_t modes = {3,14,39,255};

For turbo mode definition you can then just use #ifdef TURBO_TIMEOUT.
For moon mode definition:

#ifdef MODE_MOON
static uint8_t modes = {3,14,39,255};
#else
static uint8_t modes = {14,39,255};
#endif

Then you can get rid of the unneeded space wasting integer “mode_cnt” and it’s handling, and instead use “sizeof(modes)” to get the amount of modes later in the code.

I’ve written my firmware this way so I know it works, so I just tested making these small changes in the linked Star off time (took about 5 minutes) and went from 1000 bytes to 920 bytes… With no change in functionality at all.

Star and the off time version have plenty of things that can be optimized in similar fashion without changing functionality. Star is great because it’s written for easy use, but there are changes that can be done like the one I made above that can save even more space without necessarily making it harder to use.

How might I allow for slower or faster button presses when changing modes with STAR_offtime_no-memory? I would like to allow slower presses to change modes instead of reverting to low. Does the CAP_THRESHOLD value affect this?

I gave my mag-lite to my parents to see how the mode switching worked for them and they fumbled with the control of the light more than I was expecting.

Yep, the CAP_THRESHOLD is what affects it. In easy terms the off time press check is just checking the voltage level of the capacitor, a lot like the voltage monitoring routine. When the light is turned on the off time pin is configured as input and compares the measured level with the threshold value. Once all of that is done the off time pin is set to output and turned on (high) which charges the capacitor and keeps it charged until the light is switched off.

Yeah, getting some to understand momentary pressing rather than full clicks is not always easy.

Yeah, not all that user friendly :( It will be rare that someone would use dual PWM outputs, but I don't want to have a whole bunch of separate programs with different features.

I have a light that has the old turbo step down, and I find it really annoying too, especially because "turbo" is not that much brighter than "high", yet I have to step through high to get to turbo. The ramp down works awesome too, most users won't even notice a change in output yet they get max brightness right from the start without any overheating.

Modes (well, just moon) can be altered by the stars that are soldered though, so they aren't just determined at compile time, even though most people that are customizing the code really have no use for the star soldering features.

I said it before, but seriously, if someone wants to take this codebase and make it an "official" BLF firmware and continue adding features, please feel free. Many of you have come up with great features already, and are better programmers than I. Now that STAR has options there to fit almost anyone's basic needs for a light (my UI needs were met a long time ago), I have lost interest in adding features, creating documentation, etc., as everyone has little variances in how they would like the UI to work (and you are implementing those UI's just fine on your own, which was really the point of releasing this firmware as it's a good starting point for modification). As you guys have pointed out, the more features that were added, the more confusing it is to newer entrants to firmware flashing. This can only get worse.

I will go through each program when I get some time to add some more comments about what #define options do what to make it easier for a newer user to understand everything.

I'm working with RMM on a port for the ATtiny25 (already ported, just need to implement temp sensing in STAR_off_time like we have in STAR_momentary), where we have much more room to improve the logic to adjust the output based on temperature. Once that is completed I will probably bow out, as it was a fun hobby from the start, but is now more of a chore. Working for a new software startup is keeping me busy (which I honestly should be devoting every waking minute to), and I have a whole bunch of projects that I haven't had the mental energy to commit any time to, including learning to machine parts on my 9x20 lathe, rebuilding a motorcycle has been down to the frame for more than two years, and remodeling my house. I guess finding a girlfriend/wife should be in there somewhere as well ;)

Yeah, I get what your saying. Gotta thank you for your work, it got me going with writing my own firmware. I spent a lot of time optimizing because I needed the space.

Except, of course, breaking the core design concept of STAR. It’s designed to be configurable at run-time (via soldered stars) instead of compile-time. This costs a lot of space, but makes drivers end-user configurable.

However, I’ve found two things which definitely can be reduced in STAR off-time. It doesn’t actually need to set up or use the WDT interrupt. That part of the code can be removed and replaced with a small bit of logic in the main loop. It also can be made smaller by replacing the stock _delay_ms() with a custom one. These are the first two things I figured I’d try before attempting to add medium-press and battery check to it.

It will be interesting to see if 105c supplies dry up, or if they will be kept in production.

Several people, including myself, have been sent the 105d’s, which don’t have the stars.

Because I can flash drivers now, the stars don’t matter as much to me, but for the average person buying a 105C with standard or custom firmware on it they are kind of nice to have. Of course, programmable drivers, programmed via the input switch would eliminate the need for stars and allow for even more changes on the fly.

Yeah, your right about that. I’m just the kind of guy that programs in a moon mode if I want it, and leave it out if I don’t. I don’t use stars for any kind of mode configurations, only use them for off time caps, inputs and outputs.

Also true, but you’d have to re-program the turbo timeout because it’s currently counting WDT ticks.

Yep, I suggested that quite a lot of pages ago in this thread. I’ve found that the stock _delay_ms() is not so bad, but gets bad if you pass values above 255 into it, forcing it to deal with doubles. My delay routine has a lower resolution so all my delaying needs are under 255 and therefor only needs integers. That keeps memory usage down a bit.

It doesn’t really matter right now, but a “double” in C is a float with twice the default resolution. Integers above 255 are still integers, they’re just 16 bits instead of 8. Technically, it would be called a dword, or double-word, since the word size on the attiny13a is 8 bits.

For portability, people usually avoid using “words” because the size varies per architecture, choosing explicit bit sizes instead. But words are handy for speed optimization, since they typically are the fastest for most operations.

Interesting… from that last post all you comment with is an in depth explanation of my incorrect terminology. Oh well, I guess it’s good that everyone is different, the world would be a boring place otherwise :beer:

Did they stumble with the offtime timeout, or the fact that it’s a forward clicky with an offtime firmware?

Both! It was mildly depressing.

I’ve seen both problems when demonstrating flashlights to various people so that’s no surprise. The one-button interface thing is a whole new world. There are some great aspects to FWD clickies, being a good introduction to multi-mode lights is not on the list IMO.

As far as the rest (the whole timing issue with half presses), I’m really curious how much better / worse a momentary firmware would be.

EDIT: to clarify, I meant to say… don’t let it get you down. As I mentioned above, it’s a whole new world for many people: it shouldn’t reflect one way or another on your parents and it doesn’t really say anything about the viability of a flashlight business for you either. Just let this experience advise you on how important it will be to gently introduce neophytes. Picking up a one-button-interface device like a FWD or reverse clicky flashlight and learning to use it is akin to getting on a bicycle for the first time. It’s a desirable product but you do have to learn how to use it! I haven’t spent a lot of time on it, but I really haven’t seen a simple way to quickly get someone who’s totally unfamiliar with the concept up to speed.

That’s what I’m here for. :stuck_out_tongue_winking_eye:

Especially with Zebralights. Nice UI, but genuinely too complicated for a lot of people. I can’t hand a Zebralight to a muggle and expect them not to fail… they’ll generally click the button, turn it on in turbo, hurt their eyes (or someone else’s), click it again in an attempt to shut it off (taking it down to medium), then rapidly click until it starts blinking… and then hand it back to me with a negative comment like “that thing is booby-trapped!”.

Alternately, they might wait just long enough after the initial blast before they start fast-clicking, which makes it toggle between turbo and high.

So, probably a good idea to at least try to make UIs somewhat muggle-friendly… i.e. don’t do anything particularly surprising on single-press-from-off.

I stay with the convention that a WORD is always unsigned 16 bits, DWORD unsigned 32 bits, BYTE unsigned 8 bits. Most C/C++ compilers don't natively support WORD and DWORD, so I usually assign them in a common header. I've worked several times with binary data import/export or comm/dual port interfaces between processors, and it can be a nightmare if you don't have a rigorous set of standard formats. Mixing big Endian (Motorola, etc.) and little Endian (Intel, etc.) is even worse with byte ordering all messed up. In theory the WORD does depend on the processor. The int I make no assumptions on it's size, but guaranteed it's always signed. Some processors it gets debatable what it's WORD size really is. Some do BYTE addressing but have 16 bit registers, or have a mix of 16 bit and 32 bit registers, etc. Usually it's based on memory access or the accumulator size, but that can get complicated too, with different modes.

I've been working on micros as far back as the Intel 8080, Motorola 6800 back when CP/M was the latest. I bought the original IBM PC for $3,500 back in '81 or so, just to play/learn - did a few mod/upgrades on it of course Wink. Actually I still support products using the 68331, which is a variant of the 68000, and also still support 8051 variants.

Yea, thanks for the encouragement wight. I think with a proper 30 second instructional video demonstration it will be easy for the average person. I’ll incorporate it into my product video.

I think they'll stick around for a while, but you may not be able to get them from FT anymore (who seems to get them from Convoy).

Kind of OT: Any thoughts on running an XM-L2 via Qlite from 3x nimh? I haven’t done extensive testing yet but I’m wondering if it’s just not going to be enough voltage. I may end up going strictly 2x 26650 (1s2p) for my mag upgrade kit.