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.

TMS320F28379D: tmdxiddk379d example code -

Part Number: TMS320F28379D
Other Parts Discussed in Thread: TMDXIDDK379D

Greetings,

I have a couple of questions regarding the implementation of the tmdxiddk379d FOC fast current loop code. In the fcl_f2837x_tmdxiddk.c source file, the FCL_initADC() function is called to specify the two channels that will be used for the fast current loop current sensing:

    //
    // This function initializes the ADC PPB result bases, as well as the ADC
    // module used to sample phase W. Ensure that the final argument passed
    // corresponds to the ADC base used to sample phase W on the HW board
    //
    FCL_initADC(ADCARESULT_BASE, ADC_PPB_NUMBER1,
                ADCBRESULT_BASE, ADC_PPB_NUMBER1,
                ADCA_BASE);

1) From the configure_ADC() function, the channels passed into the FCL_initADC() function are motor phase currents V (analog input A2) and W (analog input B2). The final argument passed into FCL_initADC() is the ADC base used to sample phase W. From the previous sentence this should be ADCB_BASE, however, in the example code ADCA_BASE is passed into the function. Does it matter which one you pass through? It looks like this is used to set up the proper interrupt flag.

2) After the FCL ADC initialization is set up, the register with the ADC PPB result is called in fcl_cpu_code.c in order to get the phase current value for the control process:

#define FCL_CLARKE_ADC_IN()                                                    \
    clarke1Alpha = (float32_t)((int16_t)HWREGH(curA_PPBRESULT) *               \
                            FCL_params.adcScale);                              \
    clarke1Beta  = ((clarke1Alpha +                                            \
                     (2.0 * ((float32_t)((int16_t)HWREGH(curB_PPBRESULT)) *    \
                      FCL_params.adcScale))) * ONEbySQRT3);

curA_PPBRESULT and curBPPBRESULT are pointers to registers which hold the motor phase current V and W values. From this section of code, you can see that the V phase current is set equal to the alpha component of the clarke transformation. Shouldn't phase U be set to the alpha component? The way that curA_PPBRESULT and curBPPBRESULT are named seem to imply that phase currents U and V should be getting sampled instead of V and W.

I bring this up because I am running some hardware in the loop simulations. My hardware in the loop system pmsm motor model defines the clarke transform as the U phase current in phase and equal to the alpha component. Because the TI code defines the clarke transform as the V phase current in phase with the alpha component, it creates unideal performance where some d axis current is generated when it shouldn't be (this is an SPM motor). This then obviously takes away from the torque I'm able to generate during the simulation. I attempted to pass the U (analog input A0) and V (analog input A2) phase current channels into FCL_initADC(), along with ADC_ABASE as the final input argument, but the control is not working properly, despite the fact that the registers are being read properly.

3) Can I measure phase currents U and V for the FCL code instead of phase current V and W?

Thank you for your assistance, it is greatly appreciated.

  • Does it matter which one you pass through?

    That depends on the hardware. You can use the ADC base address for either V or W, but you need to change the interrupt configuration codes accordingly.

    Shouldn't phase U be set to the alpha component?

    You can use either U/V or V/W that depends on the hardware, and you need to assign the PWM to U/V/W accordingly.

    3) Can I measure phase currents U and V for the FCL code instead of phase current V and W?

    Yes, but you need to change the FCL_initADC() and FCL_CLARKE_ADC_IN() codes. Or you may just change the order of the PWM to use the U/V as the V/W in the example code.

  • That depends on the hardware. You can use the ADC base address for either V or W, but you need to change the interrupt configuration codes accordingly.

    Thank you, this makes sense to me.

    You can use either U/V or V/W that depends on the hardware, and you need to assign the PWM to U/V/W accordingly.
    Yes, but you need to change the FCL_initADC() and FCL_CLARKE_ADC_IN() codes. Or you may just change the order of the PWM to use the U/V as the V/W in the example code.

    Can you expand on this point? I've changed the FCL_initADC() code to work with phase U and V, as you can see here:

        FCL_initADC(ADCARESULT_BASE, ADC_PPB_NUMBER1,
                    ADCARESULT_BASE, ADC_PPB_NUMBER2,
                    ADCA_BASE);

    I've also changed the interrupt configuration code. I've confirmed that the FCL control is now receiving the proper register value from the ADCs. However the control is not working. Why would I need to change FCL_CLARKE_ADC_IN() or the order of the PWMs? I am trying to set phase U to the alpha axis, which is what the FCL_CLARKE_ADC_IN() does.

  • You don't need to change the FCL_initADC() and FCL_CLARKE_ADC_IN(), and just need to change the PWM order to make the U/V/W to V/W/U, so the U/V on your board will be V/W used in project.

  • Hi Yanming, thank you for your comments. I have tried as you suggested, changing the PWM order to VWU, but this caused an instability in the control. I also tried plugging in phase U and V currents instead of V and W, and this also causes instability. The only way that the system will operated properly is the default VW phase currents being plugged into the FCL algorithm. Is there something else that I am missing?

  • Can you share with me why the clarke1Beta is calculated as:

     

    clarke1Beta  = ((clarke1Alpha +                                            \
                     (2.0 * ((float32_t)((int16_t)HWREGH(curB_PPBRESULT)) *    \
                      FCL_params.adcScale))) * ONEbySQRT3);

    From clake transform definition, the beta component is:

    ibeta = 1/sqrt(3) * ib - 1/sqrt(3) * ic

    And with the alpha component aligned with the b phase current, it would be:

    ibeta = 1/sqrt(3) * ic - 1/sqrt(3) * ia

    Can you share how this formula was constructed?

  • The Clarke formula can be found in some of the motor control textbooks as below if using the two inputs.

    Ialpha = ia;

    Ibeta = 1/sqrt(3) * (ia + 2 * ib);

    The FCL_params.adcScale is the scale factor to convert the ADC result data to the current with PU format. 

    Yes, you can use the following formula as you mentioned above if using three inputs.

    ialpha = 1/3 * (2*ia - ib - ic);

    ibeta = 1/sqrt(3) * (ib -  ic);

    So you can replace the ia/ib/ic in these equations since ia + ib + ic = 0;

  • Hello,

    I've performed some more tests to isolate my issue and I think it may have to do with the rotor angle calculation through the encoder.

    Here is my understanding of the encoder initialization stage during startup:

    First, the encoder alignment routine begins where d axis current IdRef_start  is injected to align motor to d axis. The motor is then ran at open loop at a slow speed set by lsw1speed until the encoder index fires. Then the calibration is complete and the motor begins operating in closed loop.

    1) Is this correct?

    A few questions:

    2) During open loop operation, the distance the rotor will have to spin in order for the index to fire will vary depending on the rotor initial position. Is this distance used as an encoder offset during closed loop operation? If so, what variable holds this value? It seems like it should be qep1.CalibratedAngle, but this value is never updated.

    For my HIL simulation, the motor model accepts an initial angle, speed, and encoder offset. I currently have them all set to zero. If the controller computes a different value during the startup routine, I will have different angles between controller and HIL.

      

    3) Given that my previous statements are true, can I load the HIL rotor initial conditions and encoder offset directly into my controller and skip the initialization routine since the values are known? And then when I implement on hardware I can use the initialization routine.

    Thanks.

  • Can you please also share with me where the rotor angle 0 degree position is defined from? My measurements are showing that it is aligned with the W phase, while the alpha axis is aligned with the V phase. Some clarity on where the axes for FOC (abc, clarke, park) are defined in the example code provided would be greatly appreciated.

    As you can see in the image, the electrical angle resets to zero each time W phase current is at it's maximum, indicating that these are aligned.

  • We don't need to care the rotor is aligned to which phase. Just need to inject the right d-axis and align the rotor to a position, and assume the position is the zero angle of the rotor.

  • Ok thank you, that does answer my question. My HIL simulation when computing the D and Q axis currents measures the angle with respect to the U phase current axis. It appears the difference in reference is causing the simulation to report some d axis current, when in reality it is an error due to the discrepancy in angle definition. Thank you.