Attiny25/45/85 FW Development Thread

1922 posts / 0 new
Last post
Flintrock
Offline
Last seen: 3 years 3 months ago
Joined: 09/10/2016 - 20:29
Posts: 1544

fixed it wrote:
Flintrock wrote:

If the code was general enough it could take a couple of paramters and produce different curves.  Then the same 50 bytes can maybe reused for voltage calibration curves too, saving a little back.

What voltage calibration is that? I think I missed something somewhere as I'm not aware of any curve besides the one needed to "regulate" FET output.

 

Theres a calibration "curve" for   voltage(ADC_readout).  Normally that should be linear.  But when skipping the voltage divider and "measuring" voltage on the input pin, you're actually measuring the internal refernce and the input pin is the reference.  So you measure 1.1V/Vcc, wtih 255 full scale of course.  And Vcc has a correction for the diode voltage... and the 255- is just to turn it  upside down, which isn't actually needed, except the code comparissons use a > or < already as they step through the calibration table, and it keeps that code working the same for Vcc and classic mode.  The tables are defined in calibration.h in the files I linked and are implemented in voltage.h.

 

It could even be handy to have both the Vcc and normal table active at once, so having a general parameterized curve function that takes two or three input parameters and an input value and gives an output could get reuse.

Texas_Ace
Texas_Ace's picture
Offline
Last seen: 7 hours 7 min ago
Joined: 03/24/2016 - 07:44
Posts: 9036
Location: Everything is brighter in Texas

Ok, looking through the code, luckily the code you were using was more updated them I had thought, only minor changes to the code itself, mostly the calibration file that was different.

I see it said that the max mode groups is 8? Is that just a left over from biscotti? Or can it handle the full 24+ mode groups? I have come to find a few more that would be nice to add but the old firmware would only handle 23, 24 always messed up.

I noticed there are 2 tables for the ADC voltage?

Here are the few changes merged into your code: TTF-Bistro

And for reference here is the latest code I was working with, ignore the V1, V1 has had a few versions released due to being too laze to update the link in the threads lol: TA-Bistro

Texas_Ace
Texas_Ace's picture
Offline
Last seen: 7 hours 7 min ago
Joined: 03/24/2016 - 07:44
Posts: 9036
Location: Everything is brighter in Texas

If I have time I will try flashing it later. Going to try to build a protoytype driver first to see if it is a go or no go.

Texas_Ace
Texas_Ace's picture
Offline
Last seen: 7 hours 7 min ago
Joined: 03/24/2016 - 07:44
Posts: 9036
Location: Everything is brighter in Texas

I just flashed the new bistro and tried it out, it seems to work fine but obviously the timings are off due to the calibration file.

The voltage with the voltage divider in place seems to be reading .2V high for some reason? Otherwise no obvious issues but didn’t mess with it extensively.

Texas_Ace
Texas_Ace's picture
Offline
Last seen: 7 hours 7 min ago
Joined: 03/24/2016 - 07:44
Posts: 9036
Location: Everything is brighter in Texas

Hmm, I was thinking, I am guessing that the .2v high readings are because the calculation assumes that the diode voltage drop is in place, when it is not with the voltage divider.

gchart
gchart's picture
Offline
Last seen: 22 min 21 sec ago
Joined: 03/19/2016 - 11:57
Posts: 2957
Location: Central IL

Not sure if this will prove helpful, but here's a simplistic function to scale a duty cycle value according the battery level as provided by the BATTERY_VpT tables.

inline uint8_t pwm_reg(uint8_t pwm_val, uint8_t batt_lvl) {
#define BATT_LOW 36 // the last battery level for 100% duty cycle, 3.6V is 36
#define BATT_HIGH 42 // the high end of battery values, 4.2V is 42
#define DUTY_CYCLE_ON_HIGH 70 // the duty cycle at the highest battery level, 70% is 70

uint8_t batt_val = 10*(batt_lvl>>5)+(batt_lvl&0b00011111);

if (batt_val <= BATT_LOW) { return pwm_val; }
else {
// scaler is a pwm multiplier 100% = 100, 90% = 90, etc
uint8_t scaler = 100 - (100 - DUTY_CYCLE_ON_HIGH) * (batt_val - BATT_LOW) / (BATT_HIGH - BATT_LOW);
return pwm_val * scaler / 100;
}
}

 

Then within set_output(), replace PWM_LVL = pwm1 with:

 uint8_t batt_lvl = battcheck();
PWM_LVL = pwm_reg(pwm1,batt_lvl);

 

It will linearly scale the PWM value according to the battery level, starting at a given voltage level.  It does not take different modes into consideration.  It can be used for multiple channels if needed.  It's a little heavy (bytes) but can be fit if needed by trimming stuff like BIKING_STROBE.  I've got it baked into vanilla Bistro source (pulled from the repository this morning) here on pastebin. And lastly, I have not flashed/tested this. sealed

Texas_Ace
Texas_Ace's picture
Offline
Last seen: 7 hours 7 min ago
Joined: 03/24/2016 - 07:44
Posts: 9036
Location: Everything is brighter in Texas

Very nice!

How much room did it take up?

gchart
gchart's picture
Offline
Last seen: 22 min 21 sec ago
Joined: 03/19/2016 - 11:57
Posts: 2957
Location: Central IL

It’s around 240 bytes. It seems like multiplication and division take up quite a bit of space. Need to do something about that size Tired

Texas_Ace
Texas_Ace's picture
Offline
Last seen: 7 hours 7 min ago
Joined: 03/24/2016 - 07:44
Posts: 9036
Location: Everything is brighter in Texas

Wow, that is large.

Which reminds me, is it possible to add a simple define that can be commented out to disable this feature. It is possible this is something that would only be able to work on a Tiny85 unless it can be shrunk a lot.

gchart
gchart's picture
Offline
Last seen: 22 min 21 sec ago
Joined: 03/19/2016 - 11:57
Posts: 2957
Location: Central IL
Texas_Ace wrote:
is it possible to add a simple define that can be commented out to disable this feature

Yeah, in the sample at pastebin I’ve got it surrounded in a #define PWM_REGULTAION

Texas_Ace
Texas_Ace's picture
Offline
Last seen: 7 hours 7 min ago
Joined: 03/24/2016 - 07:44
Posts: 9036
Location: Everything is brighter in Texas

Ah, I missed that the first time glancing at the code, plus I know just enough about code to get in trouble which is why I try not to mess with it unless I have to.

chouster
Offline
Last seen: 1 month 1 week ago
Joined: 02/20/2014 - 15:05
Posts: 746
Location: germany

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

Flintrock
Offline
Last seen: 3 years 3 months ago
Joined: 09/10/2016 - 20:29
Posts: 1544

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. 

Texas_Ace
Texas_Ace's picture
Offline
Last seen: 7 hours 7 min ago
Joined: 03/24/2016 - 07:44
Posts: 9036
Location: Everything is brighter in Texas

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.

Flintrock
Offline
Last seen: 3 years 3 months ago
Joined: 09/10/2016 - 20:29
Posts: 1544

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.

Flintrock
Offline
Last seen: 3 years 3 months ago
Joined: 09/10/2016 - 20:29
Posts: 1544

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.

Texas_Ace
Texas_Ace's picture
Offline
Last seen: 7 hours 7 min ago
Joined: 03/24/2016 - 07:44
Posts: 9036
Location: Everything is brighter in Texas

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.

Flintrock
Offline
Last seen: 3 years 3 months ago
Joined: 09/10/2016 - 20:29
Posts: 1544

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

Flintrock
Offline
Last seen: 3 years 3 months ago
Joined: 09/10/2016 - 20:29
Posts: 1544

Texas_Ace wrote:
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.

 

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. 

 

 

 

Flintrock
Offline
Last seen: 3 years 3 months ago
Joined: 09/10/2016 - 20:29
Posts: 1544

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. 

Texas_Ace
Texas_Ace's picture
Offline
Last seen: 7 hours 7 min ago
Joined: 03/24/2016 - 07:44
Posts: 9036
Location: Everything is brighter in Texas

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.

LightRider
LightRider's picture
Offline
Last seen: 3 years 2 days ago
Joined: 08/05/2015 - 09:52
Posts: 2007
Location: U.P. MI, USA

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.

fixed it
Offline
Last seen: 1 year 3 months ago
Joined: 12/08/2015 - 14:27
Posts: 396
Location: Canada

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'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 > 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;
}
Flintrock
Offline
Last seen: 3 years 3 months ago
Joined: 09/10/2016 - 20:29
Posts: 1544

 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.

LightRider
LightRider's picture
Offline
Last seen: 3 years 2 days ago
Joined: 08/05/2015 - 09:52
Posts: 2007
Location: U.P. MI, USA

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?

Flintrock
Offline
Last seen: 3 years 3 months ago
Joined: 09/10/2016 - 20:29
Posts: 1544

 

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.

 

Flintrock
Offline
Last seen: 3 years 3 months ago
Joined: 09/10/2016 - 20:29
Posts: 1544

Fixed confusion in second sentence above.

Flintrock
Offline
Last seen: 3 years 3 months ago
Joined: 09/10/2016 - 20:29
Posts: 1544

LightRider wrote:
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?

 

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.

Texas_Ace
Texas_Ace's picture
Offline
Last seen: 7 hours 7 min ago
Joined: 03/24/2016 - 07:44
Posts: 9036
Location: Everything is brighter in Texas

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.

Texas_Ace
Texas_Ace's picture
Offline
Last seen: 7 hours 7 min ago
Joined: 03/24/2016 - 07:44
Posts: 9036
Location: Everything is brighter in Texas
fixed it wrote:

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.

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?

Pages