PID Control loops
I need some help with PID control loops, I don't understand all of the math on them but do understand the code. I imagine my error is with the gains...
My code uses pieces from Jasons IntPID-Scaled.spin code. My problem is that I am receiving a -1 or a 0 in the serial terminal. ( as seen in the attached picture)
Thanks in advance!
My code uses pieces from Jasons IntPID-Scaled.spin code. My problem is that I am receiving a -1 or a 0 in the serial terminal. ( as seen in the attached picture)
Thanks in advance!
CON _clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
VAR
long PGain
long IGain
long DGain
long SetPoint
long Measured
long DoInt
VAR ''---- Varriabls for PID Calc -----'
long Kp 'PID Gain
long Ki 'PID Gain
long Kd 'PID Gain
long Kd2 'PID Gain
long PMax 'Maximum P term error value
long Output 'PID Output
long PError, PClamped
long DError, D2Error
long IError 'Accumulated integral error
long LastPError 'Previous Error
long LastDError 'Previous Error
obj
MPU : "MPU"
FDS : "Fullduplexserial"
pub Main | za, zan, x, count
FDS.Start( 31, 30, 0, 115200 )
MPU.start
''---Zero Paramaters---'
LastPError := 0
IError := 0
waitcnt(clkfreq + cnt)
repeat
za := 0
repeat 10
za := za + MPU.getaccelz
waitcnt(clkfreq / 100 + cnt) 'Averages 10 Accelrometer values
zan := za / 10
zan := zan / 100 'Then reduces the value to a easier number to work with
'/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/'
SetPoint := 167
Measured := zan
'--------------------------------------------'
PGain := 6
IGain := 5
DGain := 4
'-=-=-=-=-=-=-=-=- PID paramaters =-=-=-=-=-=-=-=-=-=-=-=-=-='
Kp := PGain
Ki := IGain
Kd := DGain
Kd2 := 0
''--------------Begin PID Calcualtions-----------'
PError := SetPoint - Measured
DError := PError - LastPError
D2Error := DError - LastDError
LastDError := DError
LastPError := PError
PClamped := PError
if( PMax > 0 )
PClamped #>= -PMax
PClamped <#= PMax
Output := (Kp ** PClamped) + (Kd ** DError) + (Kd2 ** D2Error) + (Ki ** IError)
''-----------------END pid calculations----------------------'
count := count + 1
FDS.tx(0)
FDS.str(string("Loop Number: "))
FDS.DEC(count)
FDS.tx(13)
FDS.str(string("Current Point: "))
FDS.DEC(Measured)
FDS.tx(13)
FDS.str(string("Set Point: "))
FDS.DEC(SetPoint)
FDS.tx(13)
FDS.str(string("PID Output: "))
FDS.DEC(Output)
FDS.str(string(13,"Loop # "))
FDS.dec(count)
waitcnt(clkfreq / 2 + cnt)


Comments
It looks like you're using an accelerometer for feedback but what are you sending the output to? The output has to be able to affect the input (accelerometer) in order for the PID algorithm to be meaningful.
I adjusted PMax and it only gave me back a -2 -1 or a zero. I tried a range from 100 to 2000.
@DD
My project is an autonomous tricopter. But for now i'm just working with one motor and the control loop.
I am using an accelerometer (the mpu-9150) I just wanted to read the output for now on the pst but it will eventually be controlling an esc/motor.
and i figured that I would be able to tilt the accelerometer and see a change in the output then I would be able to set it up to work with the motor.
is that not possible?
also just wanted to clear up that the value of the z axis while level is 167 when averaged and divided by 100.
Okay, I don't know Spin but reading up on it a little it would seem the ** in the PID equation is not appropriate. It should be a single * for ordinary integer multiplying.
That is unless you use large values, greater than 16 bits worth, for both the readings and gains. Then it would be fruitful to use **
Also, the fact that you are not getting any +1 results I'd hazard a guess you've got some rounding biases to iron out as well.
I'm going to attempt to tune my gains, and then set it up with the motor. Thanks again!