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.

ControlSUITE SPLL_3ph_SRF_x with PSIM Simulation C Blocks

Other Parts Discussed in Thread: CONTROLSUITE, C2000WARE-DIGITALPOWER-SDK, TIDA-01606

Hello!

I have a question that might be answered here (sorry, PSIM has been recently acquired from ALTAIR and they lack forums for questions like this). 

I'm trying to generate SimCoder C blocks for the *.h files included in ControlSUITE Solar/v1.2. Up to now, I have had certain success with the the creation of some blocks.

However, the SPLL_3ph_SRF block has an input that is declared as a vector v_q[]:

the case is that, PSIM in its C block has just the "wire" input connection and I really don't know how to pass that signal as a vector to this C block. I even created the ABD-DQ0 block thinking that it could remedy this issue:

However, I still getting errors due to this vector which requires a value between [-1,1]:

Now, there are two ABD-DQ0_x files, the positive and the negative, but at SolarLib.pdf is just contemplated the ABD-DQ0_Pos/Neg and of course, the output is not a vector.

Some ideas on how to solve this issue?

Should be necessary to have one ABD-DQ0_Pos to a Pos/SPLL_3ph_SRF and then a ABD-DQ0_Neg for a neg/SPLL_3ph_SRF? 

Thank you.

  • Hi,

    The expert is out of the office because of Holiday. Please expect a reply by Tuesday.

    Thanks.

  • Hi Jacobo,

    Can you use the updated libraries provided in the latest version of the C2000Ware-DigitalPower-SDK. Let me know if you're still running into those issues.

    Regards,

    Ozino

  • Hello Ozino,

    Due to the holidays, I was not able to try your recommendation, I'll come back soon with the results of your suggestions.

    Thank you.

  • Hello Ozino,

    I'm back with this issue.

    I used the latest libraries on C2000Ware-DigitalPower-SDK and I realize that the files do not contain a MACRO to use directly on PSIM.

    For example, utilizing the old files' MACRO for ABD_DQ0 and I succeeded to create a SimCoder C Block on ALTAIR PSIM, (below code):

    ***********************************************************

    #ifndef ABC_DQ0_POS_F_H
    #define ABC_DQ0_POS_F_H

    //*********** Positive Structure Definition ********//
    typedef struct { float a; // Input: phase-a variable
    float b; // Input: phase-b variable
    float c; // Input: phase-c variable
    float sin; // Input: Sin of the grid angle
    float cos; // Input: Cos of the grid angle
    float alpha; // Internal: stationary alpha-axis variable
    float beta; // Internal: stationary beta-axis variable
    float d; // Output: stationary d-axis variable
    float q; // Output: stationary q-axis variable
    float z; // Output: zero sequence variable
    } ABC_DQ0_POS_F;

    //*********** Function Declarations *******//
    void ABC_DQ0_POS_F_init(ABC_DQ0_POS_F*v);
    void ABC_DQ0_POS_F_FUNC(ABC_DQ0_POS_F*v);

    //*********** Macro Definition ************//
    #define ABC_DQ0_POS_F_MACRO(v) \
    v.alpha=(0.6666666667)*(v.a - 0.5*(v.b + v.c)); \
    v.beta=(0.57735026913)*(v.b - v.c); \
    v.z =0.57735026913*(v.a + v.b + v.c); \
    v.d=v.alpha*v.cos + v.beta*v.sin; \
    v.q=-v.alpha*v.sin + v.beta*v.cos;


    #endif /* ABC_DQ0_POS_F_H_ */

    **************************************************************************

    Here is the internal variables of the block.

    Now, I tried to crete the same for the suggested new files for SPLL_SFR (below code):

    **************************************************************************

    #ifndef __SPLL_3PH_SRF_H__
    #define __SPLL_3PH_SRF_H__

    //##########################
    //
    // Macro Definitions
    //
    //##########################
    #ifndef C2000_IEEE754_TYPES
    #define C2000_IEEE754_TYPES
    #ifdef __TI_EABI__
    typedef float float32_t;
    typedef double float64_t;
    #else // TI COFF
    typedef float float32_t;
    typedef long double float64_t;
    #endif // __TI_EABI__
    #endif // C2000_IEEE754_TYPES

    //! \brief Defines the coefficients for a loop filter
    //!
    //! \details Loop filter coefficients
    //!
    typedef struct{
    float32_t b1;
    float32_t b0;
    } SPLL_3PH_SRF_LPF_COEFF;

    //! \brief Defines the SPLL_3PH_SRF structure
    //!
    //! \details This software module implements a software phase lock loop
    //! based on synchronous reference frame for
    //! grid connection to three phase grid
    //!
    typedef struct{
    float32_t v_q[2]; //!< Rotating reference frame Q-axis value
    float32_t Vqs; //! \Added var
    float32_t ylf[2]; //!< Data buffer for loop filter output
    float32_t fo; //!< Output frequency of PLL
    float32_t fn; //!< Nominal frequency
    float32_t theta[2]; //!< Grid phase angle
    float32_t delta_t; //!< Inverse of the ISR rate at which module is called
    SPLL_3PH_SRF_LPF_COEFF lpf_coeff; //!< Loop filter coefficients
    } SPLL_3PH_SRF;

    //!
    static inline void SPLL_3PH_SRF_init(SPLL_3PH_SRF *spll_obj)
    {
    spll_obj->v_q[0] = (float32_t)(0.0);
    spll_obj->v_q[1] = (float32_t)(0.0);

    spll_obj->ylf[0] = (float32_t)(0.0);
    spll_obj->ylf[1] = (float32_t)(0.0);

    spll_obj->fo = (float32_t)(0.0);
    spll_obj->fn = (float32_t)(50.0); //! \Added value

    spll_obj->theta[0] = (float32_t)(0.0);
    spll_obj->theta[1] = (float32_t)(0.0);

    spll_obj->delta_t = (float32_t)(20e-6); //! \Added value for 50kHz at SolarLib data

    spll_obj->Vqs = (float32_t)(0.0); //! \Added initial value Q
    }

    #define b1 -166.322444
    #define b0 166.877556

    //*********** Macro Definition ***********//
    #define SPLL_3PH_SRF_F_MACRO(spll_obj)\
    spll_obj.v_q[0]=spll_obj.Vqs;\
    spll_obj.ylf[0]=spll_obj.ylf[1]+(b0*spll_obj.v_q[0])+(b1*spll_obj.v_q[1]);\
    spll_obj.ylf[1]=spll_obj.ylf[0];\
    spll_obj.v_q[1]=spll_obj.v_q[0];\
    spll_obj.ylf[0]=(spll_obj.ylf[0]>(float32_t)(200.0))?(float32_t)(200.0):spll_obj.ylf[0];\
    spll_obj.fo=spll_obj.fn+spll_obj.ylf[0];\
    spll_obj.theta[0]=spll_obj.theta[1]+((spll_obj.fo*spll_obj.delta_t)*(float32_t)(2.0*3.1415926));\
    if(spll_obj.theta[0]>(float32_t)(2.0*3.1415926))\
    {\
    spll_obj.theta[0]=spll_obj.theta[0]-(float32_t)(2.0*3.1415926);\
    }\ spll_obj.theta[1]=spll_obj.theta[0];\
    #endif

    // end of _SPLL_3PH_SRF_H_ definition

    **************************************************************************

    But I have several errors mentioning mostly that the variable I create "Vqs" is not defined (according to PSIM).

    As you may notice, there is not too much to declare in PSIM.

    Sorry, I'm not so skilled in programming, perhaps some definition is missed. Could you give me some hints to solve this issue?

     

    Thank you for your time.

  • Hi Jacobo,

    Apologies for the delayed response. I'm not familiar with PSIM, but I want to confirm, are you updating the v_q[0] term prior to calling the macro? The older macro-based version of the library requires that. Are you able to leverage the C function routines in your PSIM module? See the API documentation on how to call and initialize this module: https://dev.ti.com/tirex/explore/node?node=A__AK-ZgXfLkBjr9Pafs40lNw__digital_power_c2000ware_sdk_software_package__5C6SEVO__LATEST&placeholder=true 

    You can also reference the TIDA-01606 to see how this library is called in an application.

    Regards,

    Ozino

  • Hello Ozino, finally I made this thing works!!

    There was plenty of search on the internet and I found some typos here and there...

    Let me start with the SolarLib.pdf  (C28x Solar Library v1.2): 

    Besides that the mentioned code is missing some data, also the text has these typos:

    According to the excel calculator:

    The mentioned values don't match.

    It is mentioned that the settling time should be 30msec, which is wrong; it should be 40msec to obtain the correct values for b0 = 166.877556 and b1 = -166.322444.

    Changing the settling time on the calculator to 40msec also gives the correct value for the natural frequency (119.0144), and kp (166.7619), mentioned in the text; but ki on text is still wrong for 40msec (and even 30msec). ki (30msec) = 25181.22, ki(40msec) = 14164.44

    Now the SPLL_3PH_SRF_F.h on PSIM,

    I modify the new coding to accommodate the Simplified C block on PSIM (sorry, I couldn't use the SimCoder C block), here is the listing:

    //#############################################################################
    //
    // Macro Definitions
    //
    //#############################################################################
    #ifndef C2000_IEEE754_TYPES
    #define C2000_IEEE754_TYPES
    #ifdef __TI_EABI__
    typedef float float32_t;
    typedef double float64_t;
    #else //< TI COFF
    typedef float float32_t;
    typedef long double float64_t;
    #endif //< __TI_EABI__
    #endif //< C2000_IEEE754_TYPES

    //*****************************************************************************
    //
    //! \brief Defines the coefficients for a loop filter
    //!
    //! \details Loop filter coefficients
    //!
    // float32_t b1;
    // float32_t b0;

    //*****************************************************************************
    //
    //! \brief Defines the SPLL_3PH_SRF structure
    //!
    //! \details This software module implements a software phase lock loop
    //! based on synchronous reference frame for
    //! grid connection to the three-phase grid
    //!
    float32_t v_q[2]; //!< Rotating reference frame Q-axis value
    float32_t ylf[2]; //!< Data buffer for loop filter output
    float32_t fo; //!< Output frequency of PLL
    float32_t fn; //!< Nominal frequency
    static float theta[2]; //!< Grid phase angle
    float32_t delta_t; //!< Inverse of the ISR rate at which module is called

    //*****************************************************************************
    //
    //! \brief Initialize SPLL_3PH_SRF module
    //!
    //! \param grid_freq The grid frequency
    //! \param delta_t 1/Frequency of calling the PLL routine
    //! \param *spll_obj The SPLL_3PH_SRF structure
    //! \return None
    //!
    v_q[0] = (float32_t)(0.0);
    v_q[1] = (float32_t)(0.0);

    ylf[0] = (float32_t)(0.0);
    ylf[1] = (float32_t)(0.0);

    fo = (float32_t)(0.0);
    fn = (float32_t)(grid_freq);

    theta[0] = (float32_t)(0.0);
    // theta[1] = (float32_t)(0.0);

    delta_t = (float32_t)(delta);

    //*****************************************************************************
    //
    //! \brief Run SPLL_3PH_SRF module
    //!
    //! \param v_q Q component of the grid voltage
    //! \param *spll_obj The SPLL_3PH_SRF structure
    //!

    //
    // Update the v_q[0] with the grid value
    //
    v_q[0] = x1; //!< Input declaration for PSIM

    //
    // Loop Filter
    //
    ylf[0] = ylf[1]
    + (b0 * v_q[0])
    + (b1 * v_q[1]);
    ylf[1] = ylf[0];
    v_q[1] = v_q[0];

    ylf[0] =(ylf[0] > (float32_t)(200.0)) ? (float32_t)(200.0) : ylf[0];
    //
    // VCO
    //
    fo = fn + ylf[0];

    theta[0] = theta[1] +
    ((fo * delta_t) *
    (float32_t)(2.0*pi));
    if (theta[0] > (float32_t)(2.0*pi))
    {
    theta[0] = theta[0] - (float32_t)(2.0*pi);
    }

    theta[1] = theta[0];
    y1 = theta[0]; //!< Output declaration for PSIM

    //############################################################################

    The declared variables are pi, delta for 50kHz (20e-6), grid-freq 50; b1, and b0 (previously mentioned values).

    - On the listing can be observed that theta[2] has to be declared as static float (with float simply doesn't work), why?

    - Also theta[1] should not be initialized, otherwise, PSIM will return the wrong signal graph.

    After running on PSIM, the block still has trouble locking the signal:

    I notice on PSIM tutorial - Implementation and Design of PLL and Enhanced PLL blocks the following graph for the conventional 3-phase PLL:

    there is a divider between the absolute value of q and d, so I added it to my simulation schematic:

    This is the result, now it works like charm!!:

    It locks the signal for different frequencies and even for phase change. I wonder if, in the full coding, main.c is this division (or some sort of operation), that will perform as this simulation.

    Anyway, I'll use this SRF for the SOGI as well and then implement it in my design.

    Your feedback is always welcomed.

  • Hi Jacobo,

    Thank you for the detailed feedback. Glad to hear you were able to leverage the SPLL library in your application. I've noted your feedback regarding the mismatch between documentation and the excel spreadsheet. I've gone ahead and filed a request to get it fixed in our next C2000WARE-DIGITALPOWER-SDK release.

    As for the divider, let me cross check our reference designs and see if it is being leveraged. I'll also check with one of our experts to get their opinions.

    Regards,

    Ozino

  • Alright, then I'll wait a few days but otherwise, I guess now all here is working and the case can be closed.

    Thank you for your support Vulcan tone2