Update Oct 3: PD68 TripleDown/TripleStack - Tri-Channel Driver

Just a quick note… I updated the level calculator to work with any number of power channels. It assumes some things though, like that there is only one FET channel (at most) and it’s the most powerful channel and it works better by itself than with other channels turned on. It’ll bail and refuse to run if you tell it a FET channel has less output than all the others combined.

http://bazaar.launchpad.net/~toykeeper/flashlight-firmware/tiny25/view/head:/bin/level_calc.py

Here’s an example use, calculating 7 evenly-spaced modes on a tripledown with 1x7135, 6x7135, and 1xFET driving a triple XP-L at a max of 3000 lumens:

> ./level_calc.py                                                
How many power channels? (1) 3
How many total levels do you want? (4) 7
Describe the channels in order of lowest to highest power.
===== Channel 1 =====
Type of channel: ["7135"] or "FET": (7135) 7135
Lowest visible PWM level: (6) 3 
How bright is the lowest level, in lumens? (0.25) 0.25
How bright is the highest level, in lumens? (1000) 140
===== Channel 2 =====
Type of channel: ["7135"] or "FET": (7135) 7135
Lowest visible PWM level: (6) 3
How bright is the lowest level, in lumens? (0.25) 1.5
How bright is the highest level, in lumens? (1000) 840
===== Channel 3 =====
Type of channel: ["7135"] or "FET": (7135) FET
Lowest visible PWM level: (6) 1
How bright is the lowest level, in lumens? (0.25) 10
How bright is the highest level, in lumens? (1000) 3000
1: visually 0.63 (0.25 lm): 3.00/255, 0.00/255, 0.00/255
2: visually 2.93 (25.12 lm): 47.85/255, 0.00/255, 0.00/255
3: visually 5.23 (142.85 lm): 255.00/255, 3.41/255, 0.00/255
4: visually 7.53 (426.32 lm): 255.00/255, 88.60/255, 0.00/255
5: visually 9.82 (948.41 lm): 255.00/255, 245.51/255, 0.00/255
6: visually 12.12 (1782.01 lm): 255.00/255, 255.00/255, 101.08/255
7: visually 14.42 (3000.00 lm): 0.00/255, 0.00/255, 255.00/255
PWM1 values: 3,48,255,255,255,255,0
PWM2 values: 0,0,3,89,246,255,0
PWM3 values: 0,0,0,0,0,101,255

You can also specify all the options on the command line, like this:

> ./level_calc.py 3 7 7135 3 0.25 140 7135 3 1.5 840 FET 1 10 3000

Since it’s close already, I’d probably manually adjust the values a bit afterward to make sure one mode is exactly 140 lm and one mode is exactly 980 lm — so that modes 3 and 5 would have no PWM.

Does this mean you have a firmware with 3 pwm outputs?

No, not yet. I should have a tripledown version of bistro pretty soon though. I just wanted to start with the ramp calculator before I look at how to turn on the other PWM circuit.

So, it took a while to figure out exactly how to configure the third PWM channel. There’s this weird dependency between PB4 (FET channel) and PB1 (6x7135 channel) that I don’t fully understand. And then I thought I still had it wrong because my test light doesn’t have much output difference between 7x7135 and the FET. The host I used gets the following outputs:

  • 1x7135: 160 lm
  • 6x7135: 760 lm
  • 7x7135: 880 lm
  • FET: 1190 lm

It didn’t help that I gave it a ramp calibrated for a 3000-lm light, so it spent a lot of the ramp on the FET modes and thus looked like nothing was changing.

Anyway, it’s working now:
http://bazaar.launchpad.net/~toykeeper/flashlight-firmware/tiny25/files/head:/ToyKeeper/bistro/
(requires an updated tk-attiny.h too, to get the TRIPLEDOWN_LAYOUT definition)
(also requires tiny25/45/85 since tiny13 lacks space and can’t do PWM on more than two channels)

This has a ramping test mode enabled instead of bike flash and police strobe, to help with testing driver functionality. I also haven’t attempted to calibrate voltage or OTC timings for this exact driver; those will also need tweaking on a per-driver basis.

This is with a triple xlp host? What battery did you use?

No, not a triple-emitter host. It had only a single emitter.

However, it has three power channels and it implements a smooth brightness ramp using all three channels. This is much like a FET+1, except with three channels instead of two (so the medium-high modes are more efficient).

To use it in a higher-powered light, you’ll need to generate new ramp values (as in the example a few posts ago).

So to get a 3rd PWM channel, are you using the Timer/Counter1 PWM feature? Looks like that's new in the 25/45/85, not in the 13A. What pin does it go out of? Does it have to be any special pin?

Dang, didn't know this was possible. On the 85/Narsil, I'm using pin #3 (PB4) for the indicator LED, and would love to control it via PWM.

Ok. I was asking because it sounded like you were anticipating 3000lm. Your feet channel is not too far off then. Depending on the led and battery…

Im excited to get to this firmware. I’ve got one other project to finish first though. Thanks for your work on this!

Excellent ToyKeeper!
If only I had a 3 channel driver on hand, I’d be flashing it now.

Yes, the tiny25/45/85 has two PWM counters. Each can control one or two PWM channels. The main counter controls pins 5 (PB0) and 6 (PB1), secondary counter controls pins 3 (PB4) and 2 (PB3). They use somewhat different APIs though, so they’re not totally interchange-able.

I’m explicitly not using the 4th PWM channel, because it has the OTC and I want that pin always high to keep the cap charged.

To enable channel 3, basically do this:

#define FET_PWM_PIN PB4     // pin 3
#define FET_PWM_LVL OCR1B   // output compare register for PB4

DDRB |= (1 << FET_PWM_PIN);          // set third channel (DDB4) as output
TCCR1 = _BV (CS10);                  // no prescaler
GTCCR = _BV (COM1B1) | _BV (PWM1B);  // clear OC1B on compare
OCR1C = 255;                         // Set ceiling value to maximum

FET_PWM_LVL = 123;  // set whatever PWM duty cycle you like

I got it wrong a whole bunch of times before it worked… was setting a bunch of unnecessary flags and reading from the wrong reference tables and looking at the wrong registers and … etc.

You might actually want to set a pre-scaler though, since I think it’s running at 31.25 kHz by default. You can slow that down if desired. I haven’t confirmed its speed yet though.

Oh, um, and remember that PWM stops while the processor is asleep. It can’t PWM the indicator LED in standby mode.

Nice work! I'm taking a snapshot of that.

Yea, but might be a way of keep'n the PWM clock running? We talked about methods of doing indicator LED blinks in a power saving mode. You can keep the WDT running, I believe, and if you set the frequency lower, could wake up on occasion then a blink for example to show low voltage, then back to sleep. Don't think it would take much power, not as much as keep'n the full processor running all the time. Haven't had time to pursue this though. The best use of it would be for reducing output in standby mode, but if it takes too much power, than not good. I believe you make good use of this though in the Rocher F6 driver, maybe not in standby, not sure.

Last I checked, at least on tiny13 (for fancy lighted tailcaps), I recall there being no way to keep PWM running while asleep. It uses the main processor as its clock source, normally, so when that clock is off it means PWM is off too. You might be able to do it with an external clock source, but we don’t have one.

About standby mode, I don’t recall exactly what I did in Ferrero Rocher to dim the indicators in standby mode, but I think it involved abusing a bug in the attiny. IIRC, it’s not supposed to do that. It normally sets the pin high or low (on or off), but I found a third state which produced a much dimmer glow. I’d have to check the sources and reference manual to remember what exactly it’s doing.

Could someone explain to me now I can adjust the firmware to include a mode with 0 output. I have a lucidrv driver from dr jones and I can program one of the mode groups to include zero output. Idk if it is a bug or if it was intentional, but I’ve found it works great for some of the hunting lights I’ve been making. This way the hunter can turn the light off and on with a quick noiseless tap.

Anyway, is this an easy thing to do?

In bistro-tripledown, you should be able to get most of the way there by adding a 0,0,0 entry to the ramp tables then adding that mode index to a mode group somewhere. However, that likely won’t turn the light completely off. The third power channel seems stuck in “fast” PWM mode, which lights up a little bit even at 0.

Alternately, you could define a special no-output mode, assign it a number, put that number into a mode group somewhere, and add a special case to handle it (like how strobe works). It would just need to set all three PWM pins to stop sending a signal. Maybe even put the MCU to sleep to reduce power use more. This will likely require looking a few things up in the attiny reference manual though…

Eeeeek… Sounds a little too deep for me at the moment. However, the partially off may work well enough. It sounds like its just a matter changing some code that already exists. I may give that a try.

Ok. Can I change the first ramp entry from 3,0,0 to 0,0,0? and if I want to put that into a mode group, I would enter a 1 where I want it to appear. So I could change the first mode group to 1,40,0,0,0,0,0,0 and that would give me one faint glow mode and one high mode. Am I correct?

Yes, that should work. If you still want moon mode though, you should probably edit the thing which adds moon to set it to level 2 instead of 1.

Or you could just use “moon” as the “off” mode, which would only require setting the first level to 0,0,0.

If I left the moon settings as is, could I then use the moon config toggle to rather toggle the false off mode? I’m trying to think what to call a fake off mode:) have others talked about this concept for hunters or others needing an off without a click?

Yes, you could simply set moon to “off” and use it otherwise the same.

Ordered some v2 boards today .
In the bistro-tripledown.c , do i need to change something to flash it on a attiny25 ?

thanks pd for the boards and tk for the fw .