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.

CCS/TMS320F28379D: PID program error

Part Number: TMS320F28379D
Other Parts Discussed in Thread: C2000WARE, CONTROLSUITE

Tool/software: Code Composer Studio

Hello everyone, I have some errors in my PID code that I took from controle Suite.
the errors are in the pid_grando.h file althought i already included all the libraries necessary for running the code : 

#include "IQmathLib.h"
#include "IQmath.lib"
#include "pid_grando.h"

the 3 errors are : (the errors are shown in red color) 

1) identifier "PID_Terminals" is undefined 

 this error is here (in file pid_grando.h): 

typedef struct { PID_TERMINALS term;
PID_PARAMETERS param;
PID_DATA data;
} PID_CONTROLLER;

2) identifier "PID" is undefined (this error is in the main file .c)

PID pid1

3) identifier "Unit16" is undefined

I hope someone can help and thanks 

  • The first error seems to be because you are declaring the variable "PID_Terminals", but nothing by that name exists in the header file "pid_grando.h". Keep in mind that in C names are case sensitive. If you are declaring terminals in your source file you should be using "PID_TERMINALS", not "PID_Terminals".

    The structure name for the PID controller is "PID_CONTROLLER", not "PID". To declare a controller you would use:
    PID_CONTROLLER pid1;

    The error message about "Uint16" is not related to "pid_grando.h" as that uses only _iq variables. Your program should define Uint16 somewhere, like this:
    typedef unsigned int Uint16;

    Probably you are missing a header file which does this, but you can try adding this typedef to your source, or just declare you variables as "unsigned int"

    BTW, if you are looking for a PID controller I recommend you download C2000Ware and review the Digital Control Library there. "PID Grando" is quite old now and there are newer and better controllers available for F2837x.

    I hope this helps.

    Regards,

    Richard
  • thanks for your answer, i solved the second and third error, but the first one not.
    I'm not using "PID_Terminals" but "PID_TERMINALS" .
    "PID_PARAMETERS" and "PID_DATA" are declared with the same manner but they have no error on them.
    here is the code for pid_grando.h (the error is marked in a comment) :
    ------------------------------------------------------------------------------------------------------------------------------------
    typedef struct { _iq Ref; // Input: reference set-point
    _iq Fbk; // Input: feedback
    _iq Out; // Output: controller output
    _iq c1; // Internal: derivative filter coefficient 1
    _iq c2; // Internal: derivative filter coefficient 2
    } PID_TERMINALS;

    typedef struct { _iq Kr; // Parameter: reference set-point weighting
    _iq Kp; // Parameter: proportional loop gain
    _iq Ki; // Parameter: integral gain
    _iq Kd; // Parameter: derivative gain
    _iq Km; // Parameter: derivative weighting
    _iq Umax; // Parameter: upper saturation limit
    _iq Umin; // Parameter: lower saturation limit
    } PID_PARAMETERS;

    typedef struct { _iq up; // Data: proportional term
    _iq ui; // Data: integral term
    _iq ud; // Data: derivative term
    _iq v1; // Data: pre-saturated controller output
    _iq i1; // Data: integrator storage: ui(k-1)
    _iq d1; // Data: differentiator storage: ud(k-1)
    _iq d2; // Data: differentiator storage: d2(k-1)
    _iq w1; // Data: saturation record: [u(k-1) - v(k-1)]
    } PID_DATA;


    typedef struct { PID_TERMINALS term; // <=== this is the error
    PID_PARAMETERS param;
    PID_DATA data;
    } PID;
    ----------------------------------------------------------------------------------------------------------------------------------------------------
  • I'm not seeing an issue with the code you pasted. In the header file in controlSUITE the last structure is named "PID_CONTROLLER", but if you are declaring a PID variable you will not see an error. The problem is somewhere else.

    Can you post the "pid_grando.h" file you are using please?

    Regards,

    Richard
  • Thanks; the file has PID_CONTROLLER, not PID as the structure name, so it is at least a little different from the code you posted.

    It does build fine on my machine. What is the error you are seeing when you build?

    Regards,

    Richard
  • yeah pid_grando.h build without error when he is not attached to my file main.c

    but when i attached with main.c it gets the error : identifier "PID_TERMINALS" is undefined 

    here is my main.c file :

    #include "F2837xD_device.h"
    #include "IQmathLib.h"
    #include "IQmath.lib"
    #include "pid_grando.h"
    
    Uint16 output1;
    /* Instance the PID module */
     PID pid1={ PID_TERM_DEFAULTS, PID_PARAM_DEFAULTS, PID_DATA_DEFAULTS };
    main()
    {
    pid1.param.Kp = _IQ(0.5);
     pid1.param.Ki = _IQ(0.005);
     pid1.param.Kd = _IQ(0);
     pid1.param.Kr = _IQ(1.0);
     pid1.param.Km =_IQ(1.0);
     pid1.param.Umax= _IQ(1.0);
     pid1.param.Umin= _IQ(-1.0);
    }
    void interrupt periodic_interrupt_isr()
    {
    pid1.term.Ref = 15; // Pass _iq inputs to pid1
    pid1.term.Fbk = 3; // Pass _iq inputs to pid1
    PID_MACRO(pid1); // Call compute macro for pid1
    output1 = pid1.term.Out; // Access the output of pid1
    }
    

  • It is building fine for me, except that the main file you sent defines a variable as PID, which is incompatible with the PID_CONTROLLER as I mentioned in my last post, so this file will not find the struct definition in "pid_grando.h". I think you need to look at this because I'm not convinced it's parsing the header file you sent earlier.

    Regards,

    Richard
  • In CCS, if you right-click on the "PID" in line 8 of the file you sent, and select "Open Declaration" the IDE will open the file where that is defined. Please check that file because I think the error is there. Thanks.

    Regards,

    Richard
  • nah still not working, I just want a simple pid program can you help me please ?
    like i have the algorithm here for a PID :
    -----------------------------------------------------------------
    previous_error = 0
    integral = 0
    loop:
    error = setpoint - measured_value
    integral = integral + error * dt
    derivative = (error - previous_error) / dt
    output = Kp * error + Ki * integral + Kd * derivative
    previous_error = error
    wait(dt)
    goto loop
    ------------------------------------------------------------------------
    but i don't know how to write it in CCS language.
  • I normally recommend the Digital Control Library.  You can find it in C2000Ware, and it contains a rich selection of PID and PI controllers for the C2000.  If you install C2000Ware in the default location, the library will be at:

    C:\ti\c2000\C2000Ware_1_00_06_00\libraries\control

    I modified and attached the file you sent before by copying one of the DCL controllers into it so that it doesn't include any non-device headers. The PID controller is the function at the bottom of the file; the rest should be obvious.  This builds cleanly and should work fine on your device.  If you need more information on it you can refer to the DCL user's guide - it's the PID_C2 controller.

    The controller code in your post will not work properly if the loop saturates.  There are other refinements too in the C2 controller which are worth having.  You can read about them in the user's guide.  There is also a PID tuning guide in the \docs folder which you may find helpful.

    Regards,

    Richard

    #include "F2837xD_device.h"
    
    typedef volatile struct {
        float Kp;       //!< Proportional gain
        float Ki;       //!< Integral gain
        float Kd;       //!< Derivative gain
        float Kr;       //!< Set point weight
        float c1;       //!< D path filter coefficient 1
        float c2;       //!< D path filter coefficient 2
        float d2;       //!< D path filter intermediate storage 1
        float d3;       //!< D path filter intermediate storage 2
        float i10;      //!< I path intermediate storage
        float i14;      //!< Intermediate saturation storage
        float Umax;     //!< Upper saturation limit
        float Umin;     //!< Lower saturation limit
    } PID;
    
    #define PID_DEFAULTS {  1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, \
                            0.0f, 1.0f, 1.0f, -1.0f }
    
    Uint16 output1;
    PID pid1 = PID_DEFAULTS;
    float ref;
    float fbk;
    
    float runPID(PID *p, float rk, float yk, float lk);
    
    main()
    {
        pid1.Kp = 0.5f;
        pid1.Ki = 0.005f;
        pid1.Kd = 0.0f;
        pid1.Umax= 1.0f;
        pid1.Umin= -1.0f;
    
    
    
    }
    
    void interrupt periodic_interrupt_isr()
    {
        ref = 15.0f;
        fbk = 3.0f;
        output1 = (Uint16) runPID(&pid1, ref, fbk, 1.0f);
    }
    
    float runPID(PID *p, float rk, float yk, float lk)
    {
        float v1, v4, v5, v8, v9, v10, v12;
    
        v5 = (p->Kr * rk) - yk;
        v8 = ((rk - yk) * p->Ki * p->Kp * p->i14) + p->i10;
        p->i10 = v8;
        v1 = yk * p->Kd * p->c1;
        v4 = v1 - p->d2 - p->d3;
        p->d2 = v1;
        p->d3 = v4 * p->c2;
        v9 = ((v5 - v4) * p->Kp) + v8;
        v10 = (v9 > p->Umax) ? p->Umax : v9;
        v10 = (v10 < p->Umin) ? p->Umin : v10;
        v12 = (v10 == v9) ? 1.0f : 0.0f;
        p->i14 = v12 * lk;
        return(v10);
    }