PID Control loops
teganburns
Posts: 134
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!