STAR Firmware by JonnyC - Source Code and Explanation

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).

When testing the drivers out in the open it can be not that bad (since most of the noise isn't coming from the driver itself), but once in a light the springs, switch, and even the battery vibrating against the inside of the tube can get annoyingly loud. It's certainly not anything I'm willing to live with in response to something that only happens when I intentionally hold the switch after it should have been released.

Just curious, but why is the LEDs-on-when-button-held thing bothering you? The light works exactly as intended. If the LEDs didn't shut off after you released the switch, then sure, that something that's not acceptable, the light isn't working properly. But this? It's a non-issue. It doesn't cause anything else at all to happen ever, it doesn't cause higher parasitic drain, since the MCU sleeps as it should as soon as you release the switch.

I’m not entirely sure what you mean, but if I saw the errors I could probably explain what caused them.

If you removed the entire chunk of code you pasted, I can see why it wouldn’t compile. The snippet included the beginning but not the end of a function, leaving the code in a malformed state.

On a different note, JonnyC never responded about the code repo. I suppose perhaps I should relocate to github so at least I’m using the same infrastructure and can more easily merge changes. Git may not be as clean about how it keeps history, but it’s important for everyone to be using the same tools.

i think what caused the errors is #ifdef MODES_ has to be under int main(void) for the code to run in the correct order.

if i would have put #ifdef MODES_ under int main(void) after this code for off-time memory it will not compile,

// Start up ADC for capacitor pin
DIDR0 |= (1 << CAP_DIDR); // disable digital input on ADC pin to reduce power consumption
ADMUX = (1 << REFS0) | (1 << ADLAR) | CAP_CHANNEL; // 1.1v reference, left-adjust, ADC3/PB3
ADCSRA = (1 << ADEN ) | (1 << ADSC ) | ADC_PRSCL; // enable, start, prescale

// Wait for completion
while (ADCSRA & (1 << ADSC));
// Start again as datasheet says first result is unreliable
ADCSRA |= (1 << ADSC);
// Wait for completion
while (ADCSRA & (1 << ADSC));
if (ADCH > CAP_THRESHOLD) {
// Indicates they did a short press, go to the next mode
next_mode(); // Will handle wrap arounds
store_mode_idx(mode_idx);
} else {
// Didn't have a short press, keep the same mode
#ifndef MEMORY
// Reset to the first mode
mode_idx = ((mode_dir == 1) ? 0 : (mode_cnt - 1));
store_mode_idx(mode_idx);
#endif
}

or at least thats when i quit getting errors.