Shop OBEX P1 Docs P2 Docs Learn Events
PID Control loops — Parallax Forums

PID Control loops

teganburnsteganburns Posts: 134
edited 2014-06-21 01:04 in Propeller 1
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!
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)
1024 x 690 - 42K

Comments

  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-06-20 02:37
    It would be easier for people to help if you attached the archive of your project.

    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.
  • evanhevanh Posts: 15,923
    edited 2014-06-20 05:26
    PMax isn't set, defaults to zero.
  • teganburnsteganburns Posts: 134
    edited 2014-06-20 15:20
    @evanh

    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.
  • evanhevanh Posts: 15,923
    edited 2014-06-20 21:12
    Doh! My suggestion didn't help because PMax didn't matter being zero. I dunno why I ignored the if( PMax > 0 ) ...

    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.
  • teganburnsteganburns Posts: 134
    edited 2014-06-21 01:04
    I think that did the trick @evanh !! I'm receiving a range of values that seem to be proportional to the accelerometer.

    I'm going to attempt to tune my gains, and then set it up with the motor. Thanks again! :D
Sign In or Register to comment.