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.

TMS320F280039C: eSMO issue

Part Number: TMS320F280039C

Tool/software:

Hi team,

When using the ESMO algorithm to observe the rotor angle, I found that the rotor angle is not linear, but rather has several stepped protrusions between -180 and+180, which leads to inaccurate angle observation. May I know which parameters may be affecting this?

Thanks & Best regards,

Jiahui

  • Hi Jiahui,

    What speed is the motor running at? The eSMO utilizes the estimated back EMF for angle reconstruction and may be inaccurate for low speed operation. 

    Thanks,

    Jiaxin

  • Hi Jiaxin,

       It was past expressed this forum eSMO (sliding mode observer) when selected and build enabled replaces the fast estimator slow speed observer <1Hz (open loop) only. Seemingly both Fast and eSMO enable symbols must be build present and (Fast with eSMO) selected via LAB script debug monitor for FOC start up, using slow speed observer built into Fast Estimator library calls.

      To select sliding mode observer motor startup (open loop), select eSMO source via LAB script drop down dialog to override the original slow speed observer library calls. Then Fast Estimator calculates angle (closed loop) for FOC sensorless run code. The hardest part of motor startup is determining the rotor direction (open loop) to get it spinning well prior to entering closed loop with current control priority.

    The Universal motor control open loop startup will not work correctly if ESMO symbol (enabled) is not first added General Symbol tab. Seemingly code motor1_drive.c linear progression loads both startup modes parameters very same function call for both slow speed (open loop) observers.

    Below, code the trajectory being set by MOTOR1_ESMO for both slow speed observers.

                #if defined(MOTOR1_FAST)
                //***********************************************************
                // enable or disable force angle
                EST_setFlag_enableForceAngle(obj->estHandle,
                                             obj->flagEnableForceAngle);
    
                EST_setFlag_enableRsRecalc(obj->estHandle,
                                           obj->flagEnableRsRecalc);
                #endif  // MOTOR1_FAST
    
                #if defined(MOTOR1_ESMO)
                //************************************************************
                if(obj->motorState >= MOTOR_CL_RUNNING)
                {
                    TRAJ_setTargetValue(obj->trajHandle_spd, obj->speedRef_Hz);
                }
                else
                {
                    TRAJ_setTargetValue(obj->trajHandle_spd,
                                        (obj->speedForce_Hz * obj->direction));
                }

    #if defined(MOTOR1_FAST) && defined(MOTOR1_ESMO)    //WAS && (OK<->OK)
        // sensorless-FOC
        MATH_Vec2 phasor;
    
        ANGLE_GEN_run(obj->angleGenHandle, obj->speed_int_Hz);
        obj->angleGen_rad = ANGLE_GEN_getAngle(obj->angleGenHandle);
    
    
    // run the eSMO
        ESMO_setSpeedRef(obj->esmoHandle, obj->speed_int_Hz);
        ESMO_run(obj->esmoHandle, obj->adcData.VdcBus_V,
                        &(obj->pwmData.Vabc_pu), &(obj->estInputData.Iab_A));
    
        obj->angleComp_rad = obj->speedPLL_Hz * obj->angleDelayed_sf;
        obj->anglePLL_rad = MATH_incrAngle(ESMO_getAnglePLL(obj->esmoHandle), obj->angleComp_rad);
    
        SPDFR_run(obj->spdfrHandle, obj->anglePLL_rad);
        obj->speedPLL_Hz = SPDFR_getSpeedHz(obj->spdfrHandle);
    
        obj->speedFilter_Hz = obj->speedFilter_Hz *0.875f + obj->speed_Hz * 0.125f;
        obj->speedAbs_Hz = fabsf(obj->speedFilter_Hz);
    
        // Running state
        if(obj->estimatorMode == ESTIMATOR_MODE_FAST)
        {
            obj->speed_Hz = obj->speedEST_Hz;
    
            if(obj->motorState >= MOTOR_CTRL_RUN)
            {
                obj->angleFOC_rad = obj->angleEST_rad;
    
                ESMO_updateKslide(obj->esmoHandle);
            }
            else if(obj->motorState == MOTOR_CL_RUNNING)
            {
                obj->angleFOC_rad = obj->angleEST_rad;
                ESMO_setAnglePu(obj->esmoHandle, obj->angleFOC_rad);
            }
            else if(obj->motorState == MOTOR_OL_START)
            {
                obj->angleFOC_rad = obj->angleEST_rad;
                obj->motorState = MOTOR_CL_RUNNING;
    
                ESMO_setAnglePu(obj->esmoHandle, obj->angleFOC_rad);
            }
            else if(obj->motorState == MOTOR_ALIGNMENT)
            {
                obj->angleFOC_rad = 0.0f;
                obj->enableSpeedCtrl = false;
    
                obj->stateRunTimeCnt++;
    
                obj->IsRef_A = 0.0f;
                obj->Idq_out_A.value[0] = obj->alignCurrent_A;
                obj->Idq_out_A.value[1] = 0.0f;
    
                TRAJ_setIntValue(obj->trajHandle_spd, 0.0f);
                EST_setAngle_rad(obj->estHandle, obj->angleFOC_rad);
                ESMO_setAnglePu(obj->esmoHandle, obj->angleFOC_rad);
    
                if((obj->stateRunTimeCnt > obj->alignTimeDelay) ||
                         (obj->flagEnableAlignment == false))
                {
                    obj->stateRunTimeCnt = 0;
                    obj->motorState = MOTOR_OL_START;
    
                    obj->Idq_out_A.value[0] = obj->fluxCurrent_A;
                    PI_setUi(obj->piHandle_spd, 0.0);
                }
            }
            else if(obj->motorState == MOTOR_SEEK_POS)
            {