Attiny25/45/85 FW Development Thread

I actually think with VccLVP and OTSM you can probably remove enough stuff to fit an 85 (I'd say 45 since they seem far more likely to be easily available with BODS which should help keep the cap size down, but the fit is the same other than that).

Just saw your quote TA. Seems we had the same thought on combining the calibrations.

Actually I was already playing with this with this version.. but with inverted reads the voltage calibration actually gets pretty non-linear. For PWM regulation that's ok, but you want accurate voltage. Even a quadratic correction isn't as good as I hoped, and I figured for now without combining things it wouldn't have saved space anyway.

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.

Edit: I take it from your later post that you meant the code needed to handle the “read 1.1V with Vcc ref” mode. Makes sense as both need a division.

Come to think of it, yeah, if you're going to do this with Vcc, whoever's programming ti better understand the Vcc curve.

It's best represented as 255-255*(1.1/(Vin-Vdiode)). So really you want to unfold for regulation is power(probably not current actually by V8*I) vs that. For all I know that ends up straighter.

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.

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

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.

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.

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.

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.

Very nice!

How much room did it take up?

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 :weary:

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.

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

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.

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.