This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

PI controller on C2000 Launchpad

Other Parts Discussed in Thread: CONTROLSUITE

Hi guys,
I am trying to implement a PI controller in the c2000 launchpad. The code that I am using is as follows:

typedef struct {
float Ref; // Reference
float Fdb; // Feedback
float Err; // Error
float Kp; // Proportional
float Ki_ts; // Integral x Sample time
float OutMax; // Saturation Up
float OutMin; // Saturation Down
float Out; // Output
float integral; // Output integral
float (*compute)();
} PIREG;
typedef PIREG *PIREG_handle;
void pireg_compute(PIREG_handle);

void pireg_compute(PIREG *v){

v->Err = v->Ref - v->Fdb;
v->integral = v->integral + v->Ki_ts*v->Err;
if ( v->integral > v->OutMax){
v->integral = v->OutMax;
} else if (v->integral < v->OutMin){
v->integral = v->OutMin;
}

v->Out = v->integral + v->Kp*v->Err;

if ( v->Out > v->OutMax){
v->Out = v->OutMax;
} else if ( v->Out < v->OutMin){
v->Out = v->OutMin;
}
}

The controller is not working, can anyone spot an error in my code?

Thanks in advance

Nicolas

  • Hi Nick,

    Why don't you use the ready made sample library for PI controllers? You can find the same here:
    C:\ti\controlSUITE\libs\app_libs\motor_control\math_blocks\v4.2

    Regards,
    Gautam
  • Hi Gautam,
    Thanks for the reply. Have you already implemented a PI controller from that library? I´ve tried without success.

    #include "C:\ti\controlSUITE\libs\math\IQmath\v160\include\IQmathLib.h"
    #include "C:\ti\controlSUITE\libs\app_libs\motor_control\math_blocks\v4.2\pi_reg4.h"

    PI_CONTROLLER pi_ILbuck = {0, 0, 0, 0.1, 0.001, 1, 0, 0, 0, 0, 0, 0};

    pi_ILbuck.Ref = 3;
    pi_ILbuck.Fbk = IL_u;

    PI_REG4(pi_ILbuck);
  • I personally prefer my own implementation. I've never used the TI's PI library.
    Btw what is the issue you face... did you go through the user guide doc?

    Regards,
    Gautam
  • Yes I did go through the doc, but it didnt give any information on how to write the code. My previous code is changing the values in the output as a PI should do but when it reaches the setpoint the value goes to zero and I dont know why.

    Regards,
    Nicolas
  • Nic, refer this link: e2e.ti.com/.../101799
    The kit example code can shed some light.

    Regards,
    Gautam
  • Nicholas, if the output goes to zero when error is zero it means you only have a proportional controller.. U=Kp*e ...

    I would recommend you confirm you have the integral term.. this is a tell tell sign..

    Also as is mentioned on the post pointed to by Gautam, PID Grando is another module you can use , it has some benefits from input scaling etc.. which can improve some transient performance.
  • Hello Manish,

    I am aware that my controller is functioning as a proportional controller only. The problem is I implemented an integral term in my code.

      

    typedef struct {

           float Ref;   // Reference

           float Fdb;   // Feedback

           float Err;   // Error

           float Kp;     // Proportional

           float Ki_ts;  // Integral x Sample time

           float OutMax; // Saturation Up

           float OutMin; // Saturation Down

           float Out;   // Output

           float integral; // Output integral

           float  (*compute)();

    } PIREG;

    typedef PIREG *PIREG_handle;

    void pireg_compute(PIREG_handle);

     

    PIREG pi_ILbuck = {0, 0, 0, 0.1, 0.001, 1, 0, 0, 0, pireg_compute};

      

    void pireg_compute(PIREG *v){

           v->Err =  v->Ref - v->Fdb;

           v->integral = v->Ki_ts*(v->integral + v->Err);

           if ( v->integral > v->OutMax){

                 v->integral = v->OutMax;

           } else if (v->integral < v->OutMin){

                 v->integral =  v->OutMin;

           }

     

           v->Out = v->integral + v->Kp*v->Err;

     

           if ( v->Out > v->OutMax){

                 v->Out = v->OutMax;

           } else if ( v->Out < v->OutMin){

                 v->Out =  v->OutMin;

           }

    }

     

           pi_ILbuck.Ref = 3;

                  pi_ILbuck.Fdb = IL_u;

                  pi_ILbuck.compute(&pi_ILbuck);

      

    I have tried to use that PID_grando library. Actually, that was my first approach to implement the PI, the problem was that I could not make the controller to work that’s why I decided to write my one.

    #include "f2802x_common/include/IQmathLib.h"

    #include "C:\ti\controlSUITE\libs\app_libs\motor_control\math_blocks\v4.2\pi_reg4.h"

    PI_CONTROLLER pi_ILbuck = {0, 0, 0, _IQ(0.1), _IQ(0.001), _IQ(1), _IQ(0), _IQ(0), _IQ(0), _IQ(0), _IQ(0), _IQ(1)};

    pi_ILbuck.Ref = _IQ(3);

    pi_ILbuck.Fbk = _IQ(IL_u);

     

    PI_REG4(pi_ILbuck);

     

    set_duty(_IQtoF(pi_ILbuck.Out));

     

    Can you spot a problem in this code?

    Thanks in advance.

     

  • Nicolas,
    One thought: have you selected a default IQ value capable of representing 0.001?
    If not, your Ki_ts variable will be initialized to zero and your integral path will always output zero. What is GLOBAL_Q in your project?
    Regards,
    Richard
  • Richard,

    I am not familiar with the _IQmath.h library. The Global_Q is in its default settings. How can I be sure of which Global_Q to select?

    Thanks  for the Input.

    Nicolas

  • Nicolas,

    I don't know if this is the problem, but you are using the IQ math library in the code in your post. The fifth element in the PI structure is your "Ki_ts" variable, initialized as _IQ(0.001).
    PI_CONTROLLER pi_ILbuck = {0, 0, 0, _IQ(0.1), _IQ(0.001), _IQ(1), _IQ(0), _IQ(0), _IQ(0), _IQ(0), _IQ(0), _IQ(1)};

    Please check what GLOBAL_Q is in the header file "IQmathLib.h". If it's still the default you should see 24, in which case your problem is not this. I'm asking in case it's somehow been changed to a much smaller value which would reduce numeric resolution and could lead to the issue you're seeing.

    The library documentation is here:
    www.ti.com/.../sprc990.pdf
    See section 3.8 for advice on selecting GLOBAL_Q.

    I don't see anything else to suspect in your code.

    Regards,

    Richard