Flashlight Firmware Repository

FWIW, I finally merged Crescendo into trunk.

It doesn’t have thermal regulation yet, and I want to change how it gets to the config mode, but otherwise it seems to work.

That’s get me big picture… Thanks, TK.
In short, if I want to have only 1 group, like your example above, what I need to edit?

#define RAMP_SIZE 7 —> #define RAMP_SIZE 9
#define NUM_MODEGROUPS 12 —> #define NUM_MODEGROUPS 1
and:
PROGMEM const uint8_t modegroups[] = {
1,2,3,4,5,6,7,8,9,
},

Is that correct? And if so, that’s okay?

Meanwhile, without any modification, when I try to run debug on biscotti, using Atmel Studio 7, I got an error said: “Program Memory Usage: 1136 bytes 110,9% full”
Is this related to my computer memory or something else? TIA.

It’s almost there. It still assumes a maximum of 8 modes per group, so you’ll still need to modify the count_modes() function and maybe some other things to allow for 9.

This really should be in a FAQ, if I could figure out where to put a FAQ and how to get people to read it.

I’ve never touched Atmel Studio. If you want to build it with a different toolchain than it was written with, you’ll have to configure your toolchain. The bin/build.sh script has details on the options it expects, including (but not limited to) “-Os” to optimize for size.

Okay, I understand. So, the max RAMP_SIZE would be 8, without modification of the count_modes() function, right?
I got these when try 8 level:

./level_calc.py
How many power channels? (1) 1
How many total levels do you want? (4) 8
Describe the channels in order of lowest to highest power.
= Channel 1 =
Type of channel - 7135 or FET: (7135)
Lowest visible PWM level: (6) 4
How bright is the lowest level, in lumens? (0.25)
How bright is the highest level, in lumens? (1000)
1: visually 0.63 (0.25 lm): 4.00/255
2: visually 1.97 (7.63 lm): 5.85/255
3: visually 3.31 (36.17 lm): 13.02/255
4: visually 4.65 (100.27 lm): 29.11/255
5: visually 5.98 (214.31 lm): 57.74/255
6: visually 7.32 (392.68 lm): 102.52/255
7: visually 8.66 (649.78 lm): 167.07/255
8: visually 10.00 (1000.00 lm): 255.00/255
PWM1 values: 4,6,13,29,58,103,167,255
Press Enter to exit:

I’ll try and play around with that number to get known the firmware better. Thanks.
My initial goal is to get the same or similar value using S2+ with 8 IC in the driver, compare with S2+ with only 6 IC.
In S2+ 6 IC, when I put in the 40% level, the heat is bearable for long run. So, I like to modified to get same result but using 8 IC.
I though the number represent the power draw during on, but I wrong, it’s showing the lumens.

Another question, what the name of original Convoy S series use? With just only 2 groups. Thanks so much.

I’m sorry if my question above is very well know and repeating again and again. I’ll try to learn little bit.
I have Linux which can be use to test my environment suit for compile the firmware.
After little bit learn your explanation above, I try using your build.sh file, seems I just need the file name only, NOT include the extension.
I just tried to run the biscotti without any modification, and get this result:

build.sh biscotti
avr-gcc -Wall -g -Os -mmcu=attiny13 -c -std=gnu99 -DATTINY=13 -I… -I…/… -I…/…/… -o biscotti.o -c biscotti.c
avr-gcc -Wall -g -Os -mmcu=attiny13 -o biscotti.elf biscotti.o
avr-objcopy —set-section-flags=.eeprom=alloc,load —change-section-lma .eeprom=0 —no-change-warnings -O ihex biscotti.elf biscotti.hex
Program: 996 bytes (97.3% Full)
Data: 16 bytes (25.0% Full)

So, that’s mean I success compile the firmware without any problems? I got 3 additional file, with hex, o, and elf extension within the same folder.

One more thing, is ATtiny 13 and 13A same? In the term of compiling firmware. Thanks once again, TK.

The ramp can be up to about 240 values long, but the mode groups have a limit of 8. This is because biscotti is based on bistro, which used a smooth ramp and evenly-spaced levels in each mode group. The original design had 64 ramp values, and biscotti is a smaller version of that.

Ah, that makes sense. That’s why biscotti has mode groups which only go up to 50% power. But in your case you would want 75% instead.

I don’t have the source code for that, or a compiled version. The closest we have is called NLITE from DrJones, which is binary-only. It’s intended to be almost identical to the old 3/5-mode firmware.

… and I should probably not answer questions when I’m sleep-deprived and a bit grumpy. Sorry about that. :slight_smile:

Yes, that looks like a successful build. You should be able to get the same result from Atmel Studio too, if you prefer, but it may take some time to get the project and options set up.

The attiny13 and attiny13a are identical as far as the code is concerned. I think the 13a is just a newer, cheaper, more efficient version.

Thanks for the helps, TK. No worries, I understand.
I’ll try and error before get confused and asking again.
If I am stuck at some point, then I still have this thread to ask more.
For now, I’ll use Atmel to simulate/debug only while compiling using my Linux, for all the benefits.

I’ve been working a bit on thermal regulation in Crescendo. So far I have an early proof of concept working, with 10-bit measurements for better precision, and have been trying to come up with a good algorithm which will work on a wide range of hardware.

Since I don’t have a wide range of hardware to actually test on, and because the testing takes a long time, I’ve been working with simulations for now. They look like this:

Those units are arbitrary, so 100 does not mean 100 F or 100 C. And the “seconds” are arbitrary time steps, not necessarily real seconds.

Anyway, this example reaches a stable state with relatively little oscillation and a relatively low over-shoot at the beginning. But if I change the host parameters, meaning the thermal mass and the lag time before the driver can sense changes in temperature, things can get better or worse:




So, it might work on a X6 but not a tube light. Or it might work on a single emitter but not a triple. Or it might work with thermal foam between the pill and the driver, but not with open air. And I’m trying to make it work on as many different hardware variations as possible, with no actual changes in the code, without being overly slow or over-shooting too much at the beginning. And without oscillating forever.

*sigh*

This might take a while.

As usual TK love your work. The time and effort you put in benefits most users here. Thanks.

How about doing it the simple way and adding a thermistor to the LED board? :slight_smile:

That’s a deeper and more complicated change which requires driver tweaks, an extra pin, and host modifications which might not be possible. I’m limited to only what a common driver can do by itself in an otherwise stock host.

However, one can often put some thermal transfer foam between the MCU and the pill. It’s a relatively easy way to speed up heat measurement in some hosts.

If the steps are smooth enough you won’t even be able to see the change by eye in most lights. The difference between 1000 and 1500 lumens is really not all that noticeable without having them side by side.

So if it ramps nice and smooth over the course of several seconds I bet you can get away with a lot of hunting without anything noticing. Although obviously less hunting is better the most important thing is not having abrupt changes in output if you want it to be a visually seamless regulation.

One possible option is you could have a calibration option like you use now but have it time how long it takes to heat up as well as the max temp. Then input that heat up time into the code to bias everything to that lights heat shedding ability.

Thus a bigger host would have a slower throttling response then a smaller host.

A bigger host already has a slower throttling response than a smaller host. The rate of correction is proportional to the rate of temperature change, so the extra thermal mass makes it course-correct slower. For example, in the last two graphs above, the one with more mass takes twice as long.

Also of note is that it starts stepping down before the measured temperature exceeds the threshold, because it reacts based on predictions instead of the latest measurement. This can help compensate for lag and reduce high initial peaks, but it also requires a wider steady-state window in order to avoid oscillations.

The last graph is a straightforward example. By the time Tdrv has exceeded the green zone, the PWM level has already stepped down three times, from 64/64 to roughly 56/64. It hits a low of 48, and then when it sees where things are heading it starts stepping back up well before Tdrv has even gone back into the green zone.

With the older bistro algorithm, it wouldn’t step down until Tdrv was already above the green zone, and then it wouldn’t step back up until Tdrv had fallen out the bottom of the green zone. So, the new algorithm (in this case) ends up with a much smaller peak and it never falls out of the bottom at all.

If I remove the prediction code, this is the result:

To reduce that issue, bistro reacted much slower, using a much stronger lowpass filter, so its actual behavior was more like this:

So far it looks like this is a significant upgrade compared to what bistro does, even if it’s not perfect.

True, you were saying that you were having issues accounting for smaller or larger hosts so timing the time it took to heat up seemed like a simple way to account for that. I am not sure how your algorithm works though so I could be totally off.

I’m not sure how it works either. :wink:

At least, I haven’t tried it in a real host yet. I should bypass a spring or two first so I don’t kill the host while testing. And I’ll most likely have to adjust the simulation to match reality, after I have some real results.

TK, it would be easier to suggest improvements if you showed us your algorithm (or describe it).
How about a higher-order analysis? Remember oscillation peaks as predictors of the mid value to squash the curve faster?

Hi,
could someone with more expertise help me out, I need hex file for biscotti firmware but I need for mode 5 to be 1% - 50% - 100% so in code this should be 2, 6, 7, 0, 0, 0, 0, 0, instead of current 2, 4, 7, 0, 0, 0, 0, 0,

I’ve been hitting the wall last 4 hours and I can’t do it anymore, when I finally succeeded compiling C file in AVR studio 5 without errors and warning I get hex file that is ~3,3kb and it doesnt fit to Attiny13A.
I made only 2 changes to original code: uncomented this “#define ATTINY 13” because it doesnt work without that and changed mode group 5 as described above.
It just doesn’t want to work with me :weary:

Thanks for the hex file…

Here’s a build with group 5 changed:
http://toykeeper.net/torches/hunter/

Thank you ToyKeeper for your speedy reply, I downloaded/burned hex. file and the output is just right but for some reason mode memori on/off function doesnt work!
I did not mention, I am usting standard Nanjg105 driver.

Hmm, several hours later I reflashet same hex again and it work now !!! :expressionless:

I added thermal regulation to Crescendo. It works pretty much the same as the Emisar D4.

The “crescendo-25.hex” file is calibrated for one of RMM’s recent FET+1 drivers, the 17mm one with a hole through the center for BAT. I tested it on a Convoy S2 triple.
http://bazaar.launchpad.net/~toykeeper/flashlight-firmware/trunk/files/head:/ToyKeeper/crescendo/

It can still be built for tiny13 too, but without memory or thermal regulation or config mode. Tiny13 does at least have room for a bunch of special modes. However, a tiny25 driver is recommended due to the extra room and the thermal sensor.

In the thermal config mode, it runs at a low brightness for 2 seconds then goes up to maximum. If you tap during the low period, it’ll set the limit to the default value (~50 C). Tap during turbo and it’ll set the limit to whatever the current temperature is.

FWIW, the thermal regulation looks approximately like this when it’s active. (except LVP should kick in sooner than it did in this test; I had my test light’s voltage calibrated too low at the time)

If it’s above the temperature limit, it’ll step down to a safe level. Then as output sags due to the battery draining, it’ll step back up occasionally to try to maintain a constant temperature. As the battery gets low, it steps up more and more often to fight the voltage sag. Eventually it hits the maximum level again, and the direct-drive sag curve continues normally until LVP activates.

The graph shows brightness over time:

The brightness will also react to changes in environmental temperature. For example, touch an ice cube to the head of the light and pretty soon it should start getting brighter.