Additional code:-
If you have too many 'other things' going on in the program (and needing more variables suggests that), then the effectiveness of the control will be reduced as the cycle rate will be reduced and regulation will suffer.
Had always perceived this as basically a stand-alone subsystem with input coming from alternative places if desired.
A bigger/faster chip might alleviate some of the issues (and give more variables as well) but the additional code would still need to be relatively trivial so the cycle time was still of the same order as it is now. Test with a short pause somewhere and regulation goes off.
Reducing variables:-
Basic principles;
The purpose of this bit of code was to even out variations in the pot.
A running average would also do that but introduce a lag.
If three readings are averaged, stored, then one more reading added, averaged and the extra reading accounted for, a running average is maintained.
I assume this is what the new code is doing.
If however you maintain the last three readings and average those, you get the average of the last three readings.
e.g.
If the set point has been 0 for a long time, then changes instantly to max, it will take (theoretically) an infinite amount of cycles for the average reading to become the max.
However, if the last three readings are stored individually (throwing away the previous reading), and those three readings are averaged then it would take only three cycles for this average to reach max with the same step change from 0 to max.
So the question becomes;
a. do we need to do this at all with the present code, and,
b. if so, how to store the last three readings without using up variables?
The answer to a. is yes. Without this average of three, the output still hunts. This could be reduced by increasing the amount of damping but this would reduce the minimum change that could be set and the regulation.
The only other option for storage (with an 08M) is to use the registers. Unfortunately calculations cannot be done directly on data in the registers which must be poked from variables and peeked back into variables with calculations using the variables.
The best I could come up with at short notice is a saving of 3 Word Variables - two by using the registers, and one by re-using SetVar in place of Target (I think Target became a separate variable due to some other code variation which no longer applies).
This code would also allow the last three FIFO to be extended to any number (within reason). It was previously limited by the number of variables available.
Have also changed the code to work with the sense on Adj circuit which I have tested again and it is good with the same IRL520N/0.15uF values used for sense on Vout.
Have also tested it again with the VN2222l/0.i5uF and find the previous ringing at certain voltages ahs disappeard. Did re-route some of the jumpers around the LM317T but nothing that would obviously account for the change.
Code:
#PICAXE 08M
setfreq m8
SYMBOL Set = 4 'ADC4 ~ the voltage setting Pot input
SYMBOL FeedBk = 1 'ADC1 ~ the feedback loop input
SYMBOL Gate = 2 'In/Out2 ~ output 'pump' to the R/C network on the MOSFET Gate
High Gate 'Drive Vout to minimum for safety on start-up!
SYMBOL SetVar = w0
SYMBOL SetVar_1 = 80 'Register address for FIFO buffer
SYMBOL SetVar_2 = 82 'Register address for FIFO buffer
SYMBOL SetVar_3 = 84 'Register address for FIFO buffer
SYMBOL FeedBkVar= w1
SYMBOL Temp_Var = w2 ' working temporary variable for peeks/pokes to FIFO
SYMBOL Damper = w3
'
main:
readadc10 Set,SetVar
peek setvar_2, word Temp_Var : poke SetVar_3, word Temp_Var
peek setvar_1, word Temp_Var : poke SetVar_2, word Temp_Var
Setvar = SetVar * 20 : poke SetVar_1, word SetVar
peek setvar_2, word Temp_Var : SetVar = SetVar + Temp_Var
peek setvar_3, word Temp_Var : SetVar = SetVar + Temp_Var
SetVar = SetVar / 60
'adjust:
readadc10 FeedBk,FeedBkVar 'get voltage data from output
if SetVar = FeedBkVar then
input Gate 'hold Gate charge
goto main 'return as output matches target
EndIf
'increase:
if SetVar > FeedBkVar then 'Out put is too low so raise output
Damper = SetVar - FeedBkVar
If Damper < 2 then main 'If change is just 1 unit, skip ~ damps out 'hunting' around set point
low Gate 'lower Gate V = Lower MOSFET R = Higher Current through Adj circuit = higher Vout
goto main
EndIf
'decrease:
'if Target < FeedBkVar then ~ falls through to decrease if not increase! If...Endif not required
Damper = FeedBkVar - SetVar
If Damper < 2 then main 'If change is just 1 unit, skip ~ damps out 'hunting' around set point
high Gate 'Higher Gate V = Higher MOSFET R = Lower Current through Adj circuit = Lower Vout
goto main
end
Had considered a keypad but if code is added to store the successive keystokes to arrive at the value of Voltage, then convert it to a 0-1023 range, then cycle time and regulation will be compromised.
It is very simple to read button presses for up/down, and have additional button/resistor combos for different size jumps. The problem I discovered before when testing this is that a single manual button push is way too long as the program cycles so fast that the shortest human button press duration last many program cycles. So additional external hardware would need to be used (a one shot or similar) as you can't use software techniques because you want to kmow about every button press. The one-shot has issues as well as you also want to be able to hold the button down, not have to press it repeatedly to move a long way.
I'm sure someone has an answer for this but nothing was suggested when this was covered astarting post #164 and specifically #173