Bits
Will try to do better. This could make understanding things better or worse
Start with your PWM Outputs.
You set the PWM to 00 hex, the output is staying low all the time. After a while Max-I & Max-V will discharge those filter caps to 0V.
You set the PWM to FF hex, the output is staying high all the time. After a while Max-I & Max-V will charge those filter caps to a Voltage.
The PWM is the % between min voltage of the filter and max voltage of the filter.
Here it is 0V and some +volt value and is used to control a voltage, but it could be the % of the power to heat your soldering iron. Here the ADC is reading Voltage and current but it could be Temp and fan speed. Like the PWM the ADC value is a % between -vref and +vref.
FF in hex is 1111 1111
00 in hex is 0000 0000
half is 1000 0000
half of the below half is 01000000
What you have is binary power of two happening.
Now if you could change your thinking and say that a all ones value is as close to 100 % as you can get this just means that your output goes from 0V to 25.5V instead of 25.6V. doing this makes the binary actually match the real world.
Half is 1000 0000 and all the computing just got easer.
Each lesser bit is half the value of the one before. This is a binary fraction.
the avr has some 10 bit ADC's
max positive is 11 1111 1111
max negative is 00 0000 0000
With the closest to 100% thinking half is 10 0000 0000 and matches in binary
Now 10-bits will not fit in a byte so you have no choice but to use 16-bits for the speed with the ADC.
For math you will probably need to use more then 8 bits to compute PWM values.
You could make your life and the program easer if you just used 16-bits for the PWM value also and just shift it two bits to the right as you go to feed it to the PWM hardware. Costs you one instruction to do the shift and prevents a lot of conversions to and from 8-bits.
Now depending on what math is needed done, it may be even better to shift more to the left on both.
10-bits with no left shift will leave 6 bits to the left. If you use a signed integer then left most bit is the sign bit. So a 16 bit signed integer range is -32768 to +32767 but your ADC values go from 0 to 4095 and actually is the % from -vref to +vref.
With 1 of those bits you can get almost to 200% and with 5 bits thats almost 3200%
So again with just a change your thinking of that binary ADC value is makes things easer. Do you need to compute up to almost 3200%? Would it be nice to loose some of that huge % and gain some more on the fractional side.
here is a table
Left shift almost max% Added_range_on_frac_side
0 3200%
1 1600% 1/2
2 800% 1/4
3 400% 1/8
4 200% 1/16
5 100% 1/32
The trick in computer control loops is to not use floats and try to leave the to/from human out of the loop by computing in %. It really is just a thinking thing most of the time.
One thing left out of most compilers is the idea of binary fractions. What exists works until the compiler increases the bit size of a value. The compiler will always add the additional bits to the left. At times you need some or all of the added bits on the right side, You will need to * or / by a binary power for this to happen.
And when going to/from human readable you need to handle the scale factor.
A left shift of one bit is like X 2 while a right shift of one bit is a / 2. The avr has instructions for bit shifts like this and are very fast. Good compilers know this and will use shifts when it can for integers. If you X3 then have to add the original to the one left shifted copy. So it's best to try to use powers of 2.
bits Better?
Quick notes on last post.
Did you miss the iSet voltage divider that will work in the last?
High ohm dividers will probably need a buffer sense amp.
Many destroyed :M3080's by trying to drive a voltage in to iSet, there is a thread.
iSet is a current output that is also used as a voltage ref.
The big problem I see for iSet is to keep it from causing a pulse on the output on power up. I just noticed that your pre-reg on pin 5 has an ON/OFF that would be a big help in preventing this pulse.
For T4, two resistors in series supplying base pull up with the resisters connected to iSet and base of T4. The resistors turn T4 on to max which causes T4's collector to pull iSet low. A second T4 then pulls down on the junction of the two resistors to turn off base current turning off the first T4 in the process. The net result is less current used from iSet and the output will increase as will the voltage across the iSet divider. At max LM3080 output. the divider current and base bias current must be less than iSet current needed for that max output.
In simple terms at 25.6V output, The iSet resistor = 1280k. The iSet voltage divider resistance in parallel with the bias resistors must be greater then 1280K
Protection is always useful but this is intended as a basic home device, if i needed something better i would get myself proper bench supply. So even though protection would be nice, it's not a high priority for me, i really just need something better then a bunch of 317's thrown together.
If you want to use the LM3080, I would like you to get it working with out blowing a bunch of LM3080's in the process. The LM3080 is much better than 317's but takes a different thinking on iSet pin.
C