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.

How did EST_run() function calculate oneOverDcbus?

Other Parts Discussed in Thread: MOTORWARE

Dear Motorware team,

I have a question with DC Bus Compensation in Motorware. In particular I want to understand how to calculate the value "oneOverDcBus" (1/Vdc_bus) which is implemented in EST_run() function.

I found in the lab11, the code section is written:

//! \brief     The main ISR that implements the motor control.
interrupt void mainISR(void)
{
    // Declaration of local variables
    _iq oneOverDcBus;

    // acknowledge the ADC interrupt
    HAL_acqAdcInt(halHandle,ADC_IntNumber_1);

    // run the estimator
    // The speed reference is needed so that the proper sign of the forced
    // angle is calculated. When the estimator does not do motor ID as in this
    // lab, only the sign of the speed reference is used
    EST_run(estHandle,&Iab_pu,&Vab_pu,gAdcData.dcBus,gMotorVars.SpeedRef_pu);

   // These 3 statements compensate for variations in the DC bus by adjusting the
   // PWM duty cycle. The goal is to achieve the same volt-second product
   // regardless of the DC bus value.  To do this, we must divide the desired voltage
   // values by the DC bus value.  Or...it is easier to multiply by 1/(DC bus value).
   oneOverDcBus = EST_getOneOverDcBus_pu(estHandle);
   Vab_pu.value[0] = _IQmpy(Vab_pu.value[0], oneOverDcBus);
   Vab_pu.value[1] = _IQmpy(Vab_pu.value[1], oneOverDcBus);

   // Now run the space vector generator (SVGEN) module.
   // There is no need to do an inverse CLARKE transform, as this is
   // handled in the SVGEN_run function.
   SVGEN_run(svgenHandle,&Vab_pu,&(gPwmData.Tabc));

}

According to my understanding, the oneOverDcBus = 1/VdcBus_pu, right? And this value can be calculated as following:

oneOverDcBus = _IQdiv(_IQ(1.0), _IQ12toIQ(gAdcData.dcBus));

where, gAdcData.dcBus is calculated in the HAL_readAdcData(), namely:

#define USER_VBUS_VOLTAGE_SF  		((float_t)((USER_VBUS_ADC_FULL_SCALE_VOLTAGE_V)/(USER_IQ_FULL_SCALE_VOLTAGE_V)))
#define ADC_DATA_V_DCBus		ADC_ResultNumber_4		//Store digital value of #V_DCbus which is read from ADC

static inline void HAL_readAdcData(HAL_Handle handle,HAL_AdcData_t *pAdcData)
{
  HAL_Obj *obj = (HAL_Obj *)handle;

  // read the dcBus voltage value
  // notes  Because the hardware gain of VdcBus channel is different from the one of Va,b,c
  value = (_iq)ADC_readResult(obj->adcHandle,ADC_DATA_V_DCBus);     // divide by 2^numAdcBits = 2^12
  value = _IQ12mpy(value,_IQ12(USER_VBUS_VOLTAGE_SF));
  pAdcData->dcBus = _IQ12toIQ(value);

  return;
} // end of HAL_readAdcData() function

But when I compared the result in my method with the result which is got by EST_getOneOverDcBus_pu(), then I find the they are different. This makes me think that I am understanding wrong about oneOverDcBus = 1/VdcBus_pu.

So please help me, how did EST_run() function calculate the oneOverDcBus?

I hope I will get the answer as soon as possible!

Thanks in advance,

Mr. Tran

  • In other word, I mean that: if I don't use the Estimator (call Est_run() and EST_getOneOverDcBus_pu()), how must I write a equivalent function EST_getOneOverDcBus_pu() to have oneOverDcBus value to use in the code section of DC Bus Compensation:

    Vab_pu.value[0] = _IQmpy(Vab_pu.value[0], oneOverDcBus);
    Vab_pu.value[1] = _IQmpy(Vab_pu.value[1], oneOverDcBus);
  • yes, it is just 1 divided by the Vbus value in per unit
    it doesn't look like yours has the per unit scaling
  • Dear Chris,

    Thank you for you explanation! So I must understand 

    VdcBus_pu =HAL_readDcbusVoltage_pu(halHandle);
    oneOverDcBus = _IQdiv(_IQ(1.0), VdcBus_pu);

    and,

    //! \brief      Reads the DcBus voltage
    //! \param[in]  handle    The hardware abstraction layer (HAL) handle
    //! \return  	The DcBus voltage is normalized in range from _IQ(-1.0) to _IQ(1.0)
    static inline _iq HAL_readDcbusVoltage_pu(HAL_Handle handle)
    {
    	HAL_Obj *obj = (HAL_Obj *)handle;
    
    	_iq value;
    
    	//convert potentionmenter from IQ12 to IQ24 (GLOBAL_Q)
    	value = _IQ12toIQ((_iq)ADC_readResult(obj->adcHandle, ADC_DATA_V_DCBus));
    
    	return (value);
    } //end of HAL_readDcbusVoltage_pu() function

    Right?

    In addition, I have one more question that relating to DC Bus Compensation, according to your knowledge:

    1) what is the principle of DC Bus Compensation in motor control? Or can you share me a document that explains about DC bus compensation.

    2) Whether there is any requirements about range of DC bus ripple for DC Bus Compensation algorithm or not?

    3) How improvement does DC Bus Compensation bring to when active the DC bus Compensation in Motor control?

    Thank you for your discussion!

  • that should be correct, yes

    1. Our DC bus compensation implementation tries to compensate for a small +/- change in the nominal DC bus by scaling the effective duty cycle being used. Meaning, if the Vbus drops by 10%, the commanded duty cycle will be increased by 10% to give the correct average voltage. Once you reach maximum modulation of course you aren't able to compensate one your duty cycle + compensation > duty cycle limit.

    2. There is the limitation when the compensated duty cycle is > the modulation limit. I think we have tested for about 20-25% voltage swings.

    3. It will give you better torque and speed regulation
  • Dear Chris,

    Thank for your clear answer. That is exact answer that I need.

    With kind regards,