Attiny25/45/85 FW Development Thread

Great job guys! I don’t know if I’ll be able to build these new drivers once they’re ready… :person_facepalming:

Hi TA, not sure where it said max modegroups is 8. Is that in a comment somewhere? It's defaulting to group 12 (array slot 11, wish we just named the groups from 0).

The new MAX_MODES define sets the maximumum number of modes IN a group. You can raise it. Actually I just tried it. It doesn't cost anything to raise it. It only costs a few bytes more in RAM not, flash. Yes, the voltage should read ~0.2V too high if you don't have a diode. Just shift all the values up two rows in the calibration (the second table) and extrapolate the missing two.

Yeah, it was in the comments, I am guessing it was left over from biscotti.

Good idea on the voltage shift, that is easy enough.

At gchart. I think really you want regulation like that to work on any defined power level less than 100%. It should automatically work out where the lowest batery level will be that will force it to 100%. Ideally that's just a wrap around check in the math (when output goes past 255, output=255) so doesn't need to be explictly determined, but with unsigned ints and compiler optimizations that's slightly tricky. Complicating all this that in bistro you first have to figure out if you're even in a FET mode, and you have to adjust all three PWMs together (well that's the easiest way), , it's kind of a shift from how the ramps are done now in bistro where the 7135s just go up to 100% when the fet is in use. I think it would be better for this to jst define those modes as equal PWM levels for all three. It just makes it trickier to guarantee that ramp definitions stay in order. (is 70% 7135s +70% fet more or less than 100% 7135's? Answer: it depends) There may be other ways, but I think it's tricky anyway.

Really though you might want ramp the pure 7135-only modes too, but that probably gets trickier to work out since you don't know what max voltage to target and depends on the setup and number of 7135s. Maybe have to rethink how to define modes entirely and define them by their minimum 100% voltage instead of by their duty factor at maximum.

Deleted comment needs more thought. Basically though, the last thing I said there. Might make sense to define modes by effective Vf... ie 100% duty factor voltage, which is more directly related to light output than PWM is.

The 7135’s should remain unaffected as they will maintain output anyways. Only the FET needs to be adjusted (although it needs the ability to control other channels as well for the new driver I am working on).

It could simple add X% to the duty for each .1v that voltage drops as well if that is simpler / takes up a lot less space. Not as adjustable but it is better then nothing.

"Side effect: can now have a couple of very long ( <8) groups without much memory cost at all."

That comment was meant to say >8 is now possible. But it's about the modes per group not number of groups. Not worded well.

Yes, but you don't know how much output they'll maintain, because you don't know how many there are. That's a problem with they're combined with the FET. What you know is that if you PWM everthing by 70%, you'll have about 70% as much light. The hard part though is matching up a 70% FET+70%7135 to a 100% 7135 at full battery. Which one is higher? So it doesn't really solve the problem of not knowing how much output you have in 7135s. It moves it to a different place though. It becomes a problem of mode ordering instead of a problem of regulation.

I haven't worked out all my thoughts on non-FET modes. But I think regulation there can also be beneficial.

Yes a 100% ALLFET mode will regulate as long as it can. But a 50% PWM all FET mode won't. Assuming no battery sag, just depletion, it will regulate until the same battery level as the 100% one would, because they're both pulling the same current during on cycles, and then it will start to drop. But it's only at 50% of its potential brightness when it starts dropping. You can still raise the PWM level up from there to maintain regulation longer. The more 7135s you have, the bigger both these issues get, the combined modes, and regulation of the pure 7135 modes.

At some point with either enough 7135's or low enough voltage, the 7135s are just acting exactly like a FET. They're 100% open. It's a bigger issue the more 7135s you use.

I am not worried about the 7135’s brightness and current. All that matters is that the FET maintain the added output as long as possible. Once it can not maintain that level of output the total output will start dropping regardless.

Better to have the 7135’s running at 100% duty and just mess with the FET by itself.

Plus in the new driver you can not control all the channels at the same time, they must be controlled separately.

Also this will mostly be used in triple builds and/or 219C’s that need the PWM turned down in order to keep the current in check. In those cases the FET plays a large role and you want the 7135’s to take as much of the load as possible to keep efficiency high.

Basically all we really need to worry about are the non-regulated FET modes, all the regulated modes are, well, regulated.

Also the worry about not knowing how many 7135’s there is not something I am worried about, you can get away with a surprising amount of variance. Plus you can always adjust the code before compiling and/or I will release multiple hex files like the TA drivers for different options.

I agree. Simply regulating the fet while allowing it to return to 100% duty when the voltage is at a level that can be better handled will allow the use of the fet drivers with newer low vf emitters without sacrificing output on high towards the middle and end of battery charge.

There are other considerations that could possibly creat more efficient drivers in the future but for now controlling the over powered fet channel would be greatly helpful.

Here's my attempt at regulation. I don't have time to test it on a light but I have tested the code on a PC and it appears to produce a decent ramp. It's 80 bytes on AVR as a function, probably a few less once inlined. Hopefully the comments are enough explanation but feel free to ask questions. Just don't expect too many answers before tomorrow.

The values I put in there for V_ZERO_AMP and V_FULL_PWM are placeholders, you'll need to figure out your own for a given driver and LED.

/* 
    This requires a linear voltage reading. So if the voltage divider is after 
    a diode, the diode drop must be added to the voltage readout (and voltage 
    constants below). 
V_ZERO_AMP is the voltage where the LED would produce 0A if the regulation 
curve was extended all the way to 0A. In practice, there will still be 
light there because the curve becomes very nonlinear at low currents. To 
get this value, project the part of the Vf/A curve where you want 
regulation to work all the way to 0A, in a straight line. Using one of 
djozz&#39;s awesome graphs makes this easy :)

V_FULL_PWM is the voltage below which there is no more regulation (ie. PWM 
is left untouched). 

The final PWM value is 
    in_PWM * (V_FULL_PWM - V_ZERO_AMP) / (Vcc - V_ZERO_AMP) 
when Vcc &gt; V_FULL_PWM, otherwise it is unchanged (no regulation). 

*/
#define V_ZERO_AMP 135
#define V_FULL_PWM 200

#include <stdint.h>

/*
This does a * b / c, with the intermediate result being 16-bit to avoid
overflow. The result is still 8-bit so it could overflow if b > c.
*/
static
uint8_t u8_mul_u8_div_u8( uint8_t a, uint8_t b, uint8_t c )
{
uint16_t tmp = 0;
uint16_t wa = a;
uint8_t i = 8;
while( 1 == 1 )
{
if( (b & 1u) != 0 )
tmp += wa;
if( --i == 0 )
break;
b >>= 1;
wa <<= 1;
}
uint16_t wd = (((uint16_t)c) << 8) >> 1;
uint8_t result = 0;
i = 8;
while( 1 == 1 )
{
if( tmp >= wd )
{
tmp -= wd;
result |= 1;
}
if( --i == 0 )
break;
wd >>= 1;
result <<= 1;
}
return result;
}

/* Takes vcc reading and pwm value and returns "regulated" pwm. */
static
uint8_t regulate_fet( uint8_t vcc, uint8_t pwm )
{
if( vcc > V_FULL_PWM )
{
pwm = u8_mul_u8_div_u8(
pwm, (V_FULL_PWM - V_ZERO_AMP), (uint8_t)(vcc - V_ZERO_AMP) );
}
return pwm;
}

I don't get the resistance.

In a 100% FET mode you can't regulate it period. We're talking about having regulated middle modes. We already have that for the all 7135 mode but it just depends how many 7135s you have on how long that can stay in regulation, and when it goes out, so do all the modes under it above one 7135. You MUST at least take into account pwming all channels even in fet modes or you just won't get this right at all, but if you don't take into acount in one way or another the 7135 output, you'll also end up with modegroups that are a confusing out-of-order mess that depends on battery level. The thing that kept them in order was leaving the 7135s on full while the FET is on, but you just can't do that now, well not without even more work to sort it out. And then you might as well just do things right:

This is what makes sense:

#define ALL7135_MAXVF // the Vf expected at the current level provided by all 7135s

#define ONE7135_MAXVF // the Vf expected at the current level provided by one 7135s

target_vf=vf_targets[mode_idx];

while (1){

actual_voltage=get_voltage();

if(target_vf>actual_voltage) {// Set a target we can actually reach. Correct for voltage sag next time around.

target_vf=actual_voltage; // better yet would be to lock out a mode once the target_vf of the next lower mode is>= voltage

}

if (target_vf>ALL7135_MAXVF){ // More than 7135's can handle, use everything.

PWM=light_output(target_vf)/light_output(actual_voltage);

PWM_ALL_CHANNELS(PWM);

} else if (target_vf > ONE7135_MXVF){// Using all 7135s

// compare desired light to what we'll actually get at the lesser of this voltage or the max 7135 voltage

// Note if target_vf is set equal to ALL7135_MAXVF we'll still have a no PWM mode.

PWM=light_output(target_vf)/light_output(actual_voltage);

PWM_ALL7135s(PWM);

} else { // Using one 7135

.. ok using voltage down here in the weeds probably doesn't make much sense.

.. just translate these to fixed single PWM levels.

}

// loop to keep up with voltage sag and drain.

}

light_output is the normalized lumens expected at a particular Vf. We rarely see this curve actually, but we have vf vs current curves and current vs light curves so you can combine them and work it out. I've never seen it.

The ratios are the thing to be approximated and can probably be done by

255-(actual_voltage-target_vf)*LED_CAL

Instead of by division.

It seems that multiplication by a constant isn't very expensive. The optimizer works out a a fixed algorithm for it.

I think it's multiplication or division of two variables that is expensive.

The hard part here is just knowing what the Vf corresponding the current of your ALL7135s is.

That depends on how many 7135s, and both that and LED_CAL will depend on the LED in use.

If configured right this will keep all the modes in order and all regulated as long as possible.

edit: removed a redundant comparison in second conditional.

Most drivers have a max of 8 regulators. Which is 2.8amps. In bistro there are four levels higher than this number. They add a bit of fet duty cycle for each. We are wanting to keep these leds under 5-6amps for a single and 10-12amps for a triple. Never will the fet be on when regulated under 2.8amps. So all regulation needs to take place above this number which is only the influence of the fet. If we were to say that we only want a max amps of 2.8, then the fet should be 0 and the regulators left alone. These new leds might stay regulated at 2.8amps all the way down to 3.3-3.5 battery voltage. So there is no situation where the regulators need to be regulated.

So say I want a nichia 219c to run at 5amps. The regulators will bring it to 2.8 then I would wat the fet to pick up the slack. The fet will be needed less when the battery is full and more when it’s empty. All modes under 2.8 will remain unchanged. All modes above 2.8 will be powered by 2.8+FET*%

When the battery is really low all regulators and the fet will be at 100% to create as little resistance as possible and give the led whatever the battery can give. At this point there will be no difference between the few highest modes but this is to be expected.

Right?

It's not the important point, but yes there are situations where it's useful to regulate the 7135's even without the FETS. A 50% all 7135 mode will drop out of regulation once the battery is low enough, and that happens to be the same level where 100% all 7135 mode drops out, not later, and it doesn't need to, because it's still only 50% of what you've got. The PWM'ed 7135 modes are NOT maximally regulated. You can keep it in regulation much longer. So it's just not true that there is no useful situation for that.

The bigger issue though, is what do you mean by "leave the 7135s alone" You mean leave them off or leave them as they are now now?

Ok.. addressed your comment on that more directly two posts down. Basically leave them on flat and worry about their contribution to the power curve or you PWM them together with the FET and worry about mode ordering. Either way you have to take their output into account in the math.

Fixed confusion in second sentence above.

This is the thing. What is 2.8+FET%? This is a duty cycle. When the fet is on the 7135 doesn't matter. The light is 100% on. When the fet is off, you're at 7135 power. So this means 50%DF*100%LIGHT + 50%DF*2.8amps worth of light.

Ok, but yeah, we can probably deal with that too in principle. I think the calculation is, well nobody has written it out yet. I'll play with it. You're still going to have to account for the 7135 output though. It's not like you can just ignore it. There is no approach where you get to just ignore it.

Flint I think you are overthinking it a bit.

In the latest 3 channel drivers there are very few mode groups that even PWM the 7135’s at all, they are pretty much always at 100% except for moon and low, which would not be effected until th battery is so low it does not matter.

The end all point is that the 7135’s will regulate the current until the voltage drops to a point where keeping regulation longer is not really an issue worth worrying about unless it takes up very little extra space and can be disabled.

There is nothing wrong with having the ability to software regulate the 7135’s and for the new driver as I said it needs to be able to regulate multiple channels anyways.

Which since the test yesterday went ok I guess I can say a little about the new design, it is an op-amp based design, basically think open source LD-3. In this case it will not need any software regulation for the op-amp channel (it will for the others) as the opamp will take care of that internally.

So basically what I am getting at is that the FET (and other channels with the same setup) are what we need to worry about, at the very least the channels need to be activated/addressed individually.

We are not looking for perfection here, we simply won’t get it. We are looking for a small code space option to improve the FET drivers and get the most out of the latest gen low Vf LED’s.

A very simple multiplier per .1v of voltage change is enough for what we need IMHO. Anything better that doesn’t take a lot of space is a great bonus.

I am not sure how it works exactly but it looks good.

So when you say Zero_amp, that would basically be a dead battery? It will increase the FET as voltage drops until it reaches 255pwm, regardless of the starting duty?

Can multiple channels be selected/use this?

How much space does this take up? It would also need to be selectable for which channels it effects, in the new driver it can not effect 1 of the channels or it will totally screw with how the light works. It also must be able to adjust the remaining channels “individually”, aka, if one of them is set to 0, it will need to stay at zero.