Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Servo Motor PID Parameters Problem

Status
Not open for further replies.

FMradio

Member level 3
Member level 3
Joined
Nov 24, 2009
Messages
58
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Location
Heaven
Activity points
1,672
Hey guys!
I am working on a servo motor drive so far its working great but now I am facing a problem related to PID parameter values
Servo loop time = 5ms
Encoder PPR = 1000
Motor RPM (max) = 4200
Kp = 5, Ki = 1, Kd = 3 (signed int16)
Motor (signed int16)

Here is my Servo Controlling Algorithm
Servo loop:
Error = reference position – encoder position
If(Error > 1023) Error = 1023
Else if(Error <-1023) Error = 1023
Motor = PID (Error);
If(Motor > 1023) Motor = 1023
Else if(Motor <-1023) Motor = 1023
Goto Servo loop;

Now my Problem is that I can’t increase the range of my PID parameters values, I have seen in a Ready Made Servo drive it takes in the PID values up to 16bits more flexible better for precise tuning & It can take a small servo loop time up to 125u seconds , here in my case lets assume
Error = 1023; (maxium)
in PID
P = Error x Kp; // 1023 x 5 = 5115
I = summation f(Error) x Ki; // it will grow with time “Servo loop time”
D = difference of Errors x Kd
Motor = P + I + D // it will saturated

Here if I reduce my servo loop time then the integrator will sum up the error more quickly right and I can’t go below Ki=1 (minimum), & if I make Ki > 1 Motor starts oscillating. “Stuck”
& if I increase Kp then P=32 will exceed 32000 again it will saturated (signed int16)
Similarly with Kd,
I am not using any floating variables in order to minimize the computation cost,

now whats the solution??
 

I am not sure what do you want to do with this. Error is all the time equal to 1023 (the same position or what)?

Regards

its a Saturation bound on Error so that the error remains in between -1023 to 1023
 

Yes, but shouldn't it be

If(Error > 1023) Error = 1023
Else if(Error <-1023) Error = -1023

????
 

I think, you should use float variables to avoid saturation, so Kp, Ki and Kd could be less then 1 and more precisselly at the same time.

Regards
 

Yes, but shouldn't it be

If(Error > 1023) Error = 1023
Else if(Error <-1023) Error = -1023

????

its not the actual code just a text

If(Error > 1023) then set Error = 1023
Else if(Error <-1023) then set Error = -1023

but its not my Problem sir

---------- Post added at 12:17 ---------- Previous post was at 12:14 ----------

I think, you should use float variables to avoid saturation, so Kp, Ki and Kd could be less then 1 and more precisselly at the same time.

Regards

yes u r right but if i use Floating values the computation cost will increase & some times it disable the interrupts as floating variable is 32 bits
 

Can you describe what type of microcontroller is used in your aplication?

Regards
 

Make your error value a long (32-bit) variable.
Then scale the result to suit the control response.
 

Can you describe what type of microcontroller is used in your aplication?

Regards

am using PIC18F

---------- Post added at 14:27 ---------- Previous post was at 14:21 ----------

Make your error value a long (32-bit) variable.
Then scale the result to suit the control response.

sir can u plzz show me how to scale the error ??

for eg
Error type is 32-bit integer
Error = 47
if i divide my error by 2
i get Error = 24 instead of 23.5

now again its a problem ?? 0.5 lost
 

It will not be lost. It will be summed in the Ki value.

Code:
/*--- Pi structure ---*/

typedef struct 
  {
  int16_t Gain[2];    /* Pi gain values - Kp and Ki */
  int16_t History[2]; /* Delay-line samples */
  int16_t Output;     /* Pi Controller Output  */
  int16_t Target;     /* Target speed */
  int16_t Measured;   /* Measured speed */
  }PI;
 
PI Pi_sync; 


/*--- Error limits ---*/

#define MAX_ERROR   +250
#define MIN_ERROR   -250
#define OUTPUTSCALE 50

/*--- Pi Gains ---*/

#define Kp  3
#define Ki  1
        
/*--- Initialise Pi ---*/

void PiInit(PI *Pi)
  {
  Pi->Gain[0] = Kp;  /* Proportional gain Kp */                 
  Pi->Gain[1] = Ki;  /* Integral gain Ki */           

  Pi->History[0] = 0;
  Pi->History[1] = 0;        
  Pi->Output = 0;
  }
  
/*--- Calculate Pi ---*/

int16_t PiCalc(PI *Pi)  
  {
  int32_t error, scaled_error;
  
  Pi->History[0] = Pi->Measured - Pi->Target;  
    
  error = (int32_t)(Pi->History[0] * Pi->Gain[0]);    
  error += (int32_t)(Pi->History[1] * Pi->Gain[1]);
  
  Pi->History[1] += Pi->History[0];
        
  if(Pi->History[1] > MAX_ERROR){
    Pi->History[1] = MAX_ERROR;
    }
  else if(Pi->History[1] < MIN_ERROR){
    Pi->History[1] = MIN_ERROR;
    }
    
  scaled_error = error / OUTPUTSCALE;       
  Pi->Output = (int16_t)scaled_error; 

  return Pi->Output;
  }     
    
/*--- End of file ---*/
 
Last edited:
Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top