Flashlight Firmware Repository

Kind of. Your calculation is right on.
But it is very non-linear when you are at the edge of switching on the 7138s.
Your batch of 7138s may have slightly different gate characteristics, the MCU output as well.
And we are so close to the edge that the cell voltage makes a difference.
Something that worked for me was to bump the level by one at 3.6 V and again at 3.4 V.
The trick is to only go up with the bumping, otherwise you get a flickering candle.

With all of these firmwares being available has anybody thought about creating a library of functions? Would there be enough benefit in creating one?

That is not really the LED.
Try it at a low enough PWM frequency (below lets say 1 kHz) and any LED that lights up at 255/255 will also light up at 1/255.

The 7135s I looked at only start to turn on after about 2 us. They are only fully on after about 6 us.
So we want PWM pulses at least 6 us long to get semi-consistent operation.

If you want to accommodate 1/255 PWM that implies a PWM period of 255 * 6 us = 1.53 ms, or 654 Hz.

Easy test.

In the code above, select on the /8 prescaler for the PWM timer.
Then try 1/255.
You might not like the flicker, but it illustrates the point.

TCCR0A=0b00100001; //phase-correct PWM
TCCR0B=0b00000010; //pre-scale 8, so PWM at 1.1 kHz
or
TCCR0B=0b00000011; //pre-scale 64, so PWM at 140 Hz (should give terrible flicker)

Hmm, I just went to try this, and I am not having success. You just connected the LED+ to DMM+ and neg to gnd? My DMM has a Hz/% button, I assume that’s frequency,

LEDs aren’t very efficient sensors, so you might need to turn up the light you’re measuring to a pretty bright level, and hold it very close to the “sensor”. Also, it depends quite a bit on the DMM you use. The DMM I tried was a really expensive one, so I’m not surprised it worked so easily.

An actual photosensor should be able to measure much dimmer lights, but I don’t have one of those… so I ran an emitter in reverse. The efficiency is terrible, but it worked well enough for my purposes.

It’s funny you mention that. A couple days ago, I started exporting common code into header files so I can share it between different projects. It’s only the most basic stuff though, the things which have been identical in pretty much every project.

Making actual libraries is a much harder task, since on an attiny every byte counts. Libraries make it a bit hard to include only the specific bits of code you want, and hard to tailor that code to each project. But at least some things can be shared to avoid repetition…

The easiest thing to share is #defines. They take no room unless actually used. So, most of my headers are just #defines for calibration values, hardware abstractions, etc.

Maybe a compendium of useful functions, rather than a true library, is the way to go. You wouldn’t include it in your project but rather cut and paste the functions you want from some central, curated, repository.

Try a small solar cell in a mostly dark room. Will produce a larger signal and their response time is suppose to be fast.

I’m wondering if maybe my DMM doesn’t have the right frequency range. Its a Klein MM200

Unfortunately I don’t have a photosensor or solar cell.

It looks like the setting on the DMM can be either frequency or duty cycle? Maybe you need to push one of the buttons to change it to measure frequency rather than duty cycle?

It says that the display should show:

% > duty cycle
Hz > Frequency

Jim

FWIW, ohaya, I recommend measuring different values rather than trying to calculate what it will do. Try a PWM level, flash it to a driver, and try it with a full and an empty cell. If it’s too low, add one. If it’s too high, subtract one. Then try again.

At ~8 kHz, I have the BLF-A6 moon mode running at 2/255 on a single 7135 chip and it produces about 0.5 lumens. It decreases with voltage, but it’s not too bad… IIRC it drops from about 0.5 lm to 0.3 lm during the lifetime of a cell. On my attiny25 test host, I’m using 3/255 for moon on a single 7135, at 15.8 kHz, and it ranges from 0.55 lm to 0.34 lm (at 4.1V or 3.1V).

Sometimes even lower values work. My BLF-SRK with 32x7135 chips gets a moon mode at 16 kHz (fast PWM) with 0/255. Most FET-based drivers will also light up at 0/255 in fast PWM mode, but this level is highly voltage-sensitive.

FET-only drivers suck at moon mode; my last attempt with one of those went from ~3 lm (at 4.2V) down to 0.001 lm (at 3.6V) — even after I tried to correct for voltage by decreasing the off-time. So, at 4.2V it ran at 0/255 (16 kHz)… and then at 4.0V it did 0/128 (32 kHz), then at 3.6V it was down to 0/2 (~2 MHz PWM). It helped, but not enough. And I couldn’t bump it up to 1/255 because then it would go all the way up to ~10 lumens. At least it was neat watching the driver auto-adjust its output; it gave kind of a “soft turn-on” kind of effect.

Sometimes a higher value is needed. On a 8x7135 nanjg with an old XM-L T6, I couldn’t get the emitter to light up until 8/255 in fast PWM mode (~16 kHz). Swapping in an XM-L2 cut the lowest usable value by quite a bit.

Dropping the PWM speed does help with stability though… which is why I use phase-correct (~8 kHz) instead of fast (~16 kHz) for moon mode on most lights. But I haven’t found it necessary to drop the speed below that.

Mostly it depends on your driver, emitter, and cell voltage.

That’s kind of what the current code repository is. :slight_smile:

Ish.

At least, it does provide a bunch of different code to reference, and most of it is freely copy-able.

Ok, I’ve been trying to get this to work for a few days now. Everything compiles and flashes fine, but nothing happens when I actually try it.

So.

Instead of trying to get memory working (apparently difficult), how can I just have it so that STAR momentary starts in the first mode as soon as power is applied (hopefully simple) ?

I think all you need to do there is change the default value:
volatile uint8_t mode_idx = 1;

Unfortunately, that didn’t work. I even completely removed “0” from the mode order, still no dice.

This is a tough nut to crack, apparently.

Maybe I need to disable sleep mode somehow?

Edit: So I commented out the two instances of “sleep_until_switch_press()” Now I get light as soon as I apply power, but it doesn’t respond to switch presses anymore.

I took a look at it, and it seems there are two changes needed, not just one.

First, set this…

volatile uint8_t mode_idx = 1;

Then later, replace the first sleep with a WDT_on:

// Enable sleep mode set to Power Down that will be triggered by the sleep_mode() command.
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
//sleep_until_switch_press();  // <- this line is causing problems
WDT_on();  // <- but this line needs to be here

That worked for me, at least.

Hi,

I was wondering how do you all test your firmware? Do you do it in an actual light?

Is there a light that it’s easy to remove and replace the driver+emitter, ideally w/o tools or something? I’m thinking like maybe light with a pill with a retaining ring so it’s easy to pop the driver out and flash it then put it back into the pill and then put the pill back into the light?

Hmm… Maybe the older HD2010 is like that?

The reason I ask is that it seems like it’s hard to get the driver to behave the same way that it does inside a light vs. say on a bench?

Jim

I have a very cheap test rig:

When I build a driver, I first flash the MCU with battcheck. Then I solder/reflow all of the components onto the PCB and solder the leads to my power supply and LED. Next, run battcheck to get my adc values, and plug them into my chosen firmware. Then I flash the firmware, check it for functionality, and install the driver in my light.

If I’m lucky, I’m done. But usually I have to go back and reflash once (or twice) to adjust the turbo timer or dial in the mode spacing.

Hi,

That’s a cool heatsink… I’ll throw one in my cart next time I buy something from FT :)…

What about the switch/clicky? How do you have that setup?

I have a tailcap that I modified by soldering a wire to to the negative ring, and I hook up my bench supply to that, but it seems hard to simulate the click timing when everything is not fully in a built light. I don’t know, maybe it’s the ergonomics. or something…