Microcontroller based PID tuning

Status
Not open for further replies.

vinayakdabholkar

Advanced Member level 4
Joined
Nov 29, 2009
Messages
114
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,296
Location
goa
Activity points
2,195
Code:
#define BOOL unsigned char
#define TRUE 1
#define FALSE 0

float PID_Kp, PID_Ki, PID_Kd;
float PID_Integrated;
float PID_Prev_Input;
float PID_MinOutput, PID_MaxOutput;
BOOL PID_First_Time;

void Reset_PID()
{
  PID_Integrated = 0.0;
  PID_Prev_Input = 0.0;
  PID_First_Time = TRUE;
}

void Init_PID(float Kp, float Ki, float Kd, float MinOutput, float MaxOutput)
{
  PID_Kp         = Kp;
  PID_Ki         = Ki;
  PID_Kd         = Kd;
  PID_MinOutput  = MinOutput;
  PID_MaxOutput  = MaxOutput;
  PID_Integrated = 0.0;
  PID_Prev_Input = 0.0;
  PID_First_Time = TRUE;
}

float PID_Calculate(float Setpoint, float InputValue)
{
  float Err, ErrValue, DiffValue, Result;


  Err = SetPoint - InputValue;

  // --- calculate proportional value ---
  ErrValue  = Err * PID_Kp;

  // --- Calculate integrated value ---
  PID_Integrated = PID_Integrated + (Err * PID_Ki);
  // limit it to output minimum and maximum
  if (PID_Integrated < PID_MinOutput) 
    PID_Integrated = PID_MinOutput;
  if (PID_Integrated > PID_MaxOutput)
    PID_Integrated = PID_MaxOutput;

  // --- calculate derivative value ---
  if (PID_First_Time)
  {
    // to avoid a huge DiffValue the first time (PID_Prev_Input = 0)
    PID_First_Time = FALSE;
    PID_Prev_Input = InputValue;
  }
  DiffValue = (InputValue - PID_Prev_Input) * PID_Kd;
  PID_Prev_Input = InputValue;

  // --- calculate total ---
  Result = ErrValue + PID_Integrated - DiffValue; // mind the minus sign!!!
  // limit it to output minimum and maximum
  if (Result < PID_MinOutput) 
    Result = PID_MinOutput;
  if (Result > PID_MaxOutput)
    Result = PID_MaxOutput;
  return (Result);
}


This is a PID algorithm which i am using in my digital compensator to control a buck converter. What i do is convert the analog output to digital value using the PIC18F4520. This digital value is passed to the PID routine along with a setpoint value. I have used 0-5V reference for ADC and my setpoint voltage is 1.2V. so if 5V is 1023 then 1.2V is 246. Based on this my output varies from 225-275. So the PID routine returns a value in the range of 225-275. This value i then map as per my requirements to set the duty cycle of the PWM module.
So for 275 duty should be zero, for 225 it should be 100% and in between for other values based on the calculations.Now i wanted to ask is how do i set the values of kp, ki and kd ? I know there are tuning methods that show steps for settings these values.I want to see how the output tracks the setpoint , the changes that occur when values of Kp, ki and kd are changed, as happens in MATLAB. I my self am not sure how to go about it . Can someone guide me here
 

I have a major doubt,
As you see what i want to do i have explained in my previous post.I use a PID algorithm and use the output to write the duty register.So the terms Kp, Kd and Ki dont have any effect finally i think.I could have very well skipped this algorithm and directly used some sort of look up table saying if this is the error this must be the duty cycle. So the PID algorithm serves nothing in this sense.Can someone clarify me here
 

I could have very well skipped this algorithm and directly used some sort of look up table saying if this is the error this must be the duty cycle. So the PID algorithm serves nothing in this sense.
You could have, ending up in a pure P controller. A P controller controller can work indeed, but involves a residual error in steady state. Adding integral action cancels the steady state error, derivative action might help to improve transient behaviour. If dynamical behaviour isn't very critical, PI should be enough.

As you mentioned in your previous post, PID parameters can be calculated using tuning rules.
 

Sorry i think i was not able to explain my doubt clearly.For me dynamic behavior is very critical, and that's why i had started with a PID.
what i fail to understand is, when i convert the output to a analog value i pass that value to the PID routine along with the setpoint. I have set my pwm module to 500K frequency, so the duty goes from 0-39 max(39 means 100% duty cycle).So the PID calculates some value and i then map it to the range from 0-39 for setting the duty cycle.So how am i using Kp, Kd, and Ki ? How are this factors affecting my duty cycle then ?
 

Another doubt
Say the PID routine takes an input value of 225 and setpoint of 246 so the output will be 245 when Kp=1 Ki=0 and Kd=0
If i make Kp=1 Ki=1 and Kd=1 same 225 inputvalue gives an output of 275. How do i use this output ?. Based on the output i need to set a duty between 0-39
If there is no one to one correspondence how will the duty be decided ?
 

The code in post #0 suggests that you have an basic understanding how a PID controller works. But according to your latest posts, you have no clue.

The important point is that I action depends on the integral error (sum of previous deviations between setpoint and process value) and D action on the differential error.
https://en.wikipedia.org/wiki/PID_controller
 

Hello Vinayadabolkar,

could you send me the PID code with PWM.

Regds,
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…