STAR Firmware by JonnyC - Source Code and Explanation

Yes, that's an issue with fast-PWM and the MCU being awake (while the button is held down) but not outputting a PWM signal.

If you're not using it to control a 7135-based driver, you should really adjust those levels from the defaults in the original source file. Different driver hardware will work with different minimum levels, 7135s need a minimum of around 5-6, other stuff can go much lower. Some hardware may be too bright in the lowest mode with even a PWM of 1.

That brings up an interesting question… is the PWM signal a square wave with an equal on/off cycle or is it a triggered pulse where the off-time can be significantly longer?

These are taken from MCU pin 6.

PWM=2

PWM=6

PWM=18

PWM=54

PWM=130

PWM=255

It does not have an equal on/off cycle.

Duh! :slight_smile: Right… “PULSE =WIDTH= MODULATION”
On-time =during= the cycle.

Thanks for the excellent images!

Thanks.

Its contolling a fet.

So if I’m understanding correctly (which isn’t likely as I don’t understand the program at all) setting the lowest mode (as in #define MODES line) to 1 is an approach to solve this? I did this, but the issue is still occurring.

Is the other solution to set tccroba=0x21?

It is not a problem, doesn't cause anything other than the behavior you described. Phase-correct is noisy and not a good solution for something that isn't wrong.

OK. It doesn’t seem ideal, but doesn’t really bother me. I thought I would get rid of it if I could,but doesn’t sound like its possible. Thanks.

Well, it is possible, by changing to phase-correct instead of fast-PWM, but the issue isn't anything to worry about. It doesn't do anything at all except keep the LEDs dimly on if you hold the button down after backing up from the 1st mode to off. The MCU goes to sleep as soon as you release the button, that's why the LEDs fully turn off then. Some earlier firmwares used a different sleep strategy, and if they used fast-PWM the LEDs would never fully turn off... but this FW is not like that, as you yourself pointed out - the LEDs do turn fully off.

If you would rather change it to phase-correct and end up with a light that squeals like a stuck pig in the upper-middle modes, all to get rid of something that only happens when you keep holding the switch button after you've told the light to turn off, well....

I decided to try what you have called the phase correct ( 0*21 thing) to see what would happen. The low level light when the button is pressed is no longer there, and yes I do get a slight buzz, but only audible if I’m in a really quiet room and ear right near the torch. That’s not a problem for me, unless it is some way damaging the driver.

Is it genuinely loud for you went you use the phase correct? Maybe im lucky mine is very quiet. Or you just don’t like the very slight buzz?

The only time I get bad whine with the phase correct is when I use it with an inductor. Otherwise there are only a few modes that I can hear and they aren't very loud. With the inductor and flyback diode the noise is pretty bad IMO.

I removed the star-soldering logic to make room for more modes and features… here is an example of how that turned out:
http://bazaar.launchpad.net/~toykeeper/flashlight-firmware/trunk/view/head:/ToyKeeper/s7/s7.c

I run this on my EDC, and it provides five nice constant-output modes plus a bunch of interesting blinkies… with no need to cycle through the blinkies when not desired.

Thanks, that explains a lot. I was having issues with a custom firmware where the LEDs wouldn’t run off all the way, and now I know why. :slight_smile:

(was trying to implement a ZL-like UI, but so far it looks like it won’t fit into just 1024 bytes)

ok thanks toykeeper! i only have one strobe mode. i prefer off-time memory and that takes up space in the code. its hard to go back to on-time memory. i did figure out how to remove the stars to save a little room. i was getting errors before, but i didnt know that #ifdef modes had to be under an inline void or where i put them is after int main (void).

Any line which starts with ‘#’ is a precompiler directive. All that stuff gets evaluated before even sending the code to the regular compiler. So, if you have anything like ‘#ifdef foo … #endif’ and ‘foo’ isn’t defined, the entire section of code will get deleted before it tries to compile anything. It doesn’t care if you put them near an inline void or after main or anywhere; all that stuff is a completely different language.

Basically, the #if and #ifdef stuff is there to give us an easier way to put several different versions of the same code into the same file, or to change things just before compiling. It’s not part of the actual program logic though. It simply trims out lines or search-and-replaces keywords before attempting to compile.

isnt #ifdef referring to #define?

well when i deleted this in star_off_time it had errors and wouldnt compile,

inline void check_stars() {
// Load up the modes based on stars
// Always load up the modes array in order of lowest to highest mode
// 0 being low for soldered, 1 for pulled-up for not soldered
// Moon
#ifdef MODE_MOON
if ((PINB & (1 << STAR2_PIN)) == 0) {
modes[mode_cnt++] = MODE_MOON;
}
#endif

but when i put it here it compiled fine,

int main(void)
{
// All ports default to input, but turn pull-up resistors on for the stars (not the ADC input! Made that mistake already)
PORTB = (1 << STAR2_PIN) | (1 << STAR3_PIN);

//mode order
#ifdef MODE_MOON
modes[mode_cnt++] = MODE_MOON;
#endif
#ifdef MODE_LOW
modes[mode_cnt++] = MODE_LOW;
#endif
#ifdef MODE_MED
modes[mode_cnt++] = MODE_MED;
#endif
#ifdef MODE_HIGH
modes[mode_cnt++] = MODE_HIGH;
#endif
#ifdef MODE_TURBO
modes[mode_cnt++] = MODE_TURBO;
#endif
#ifdef MODE_STROBE
modes[mode_cnt++] = MODE_STROBE;
#endif

i think this "inline void check_stars()" puts "#ifdef MODES_" after "check_stars()" under int main(void).