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.

Motor uncontrolled acceleration during motor identification

Other Parts Discussed in Thread: MOTORWARE, SYSBIOS, DRV8301

Hello,

I have the following problem: We have a custom hardware based on the F28069 CPU. Our software
uses InstaSPIN Foc and InstaSPIN motion to control the BLDC motor. Everything is set up and
works as it should be.

But very rarely it happens that during the motor identification the motor accelerates up to a
point where it gets dangerous and we have to switch off the whole system. I have no idea what
is the cause for this behaviour, but I believe it is a software problem.

The software is based on motorware 12 / proj_lab12. We use an encoder as feedback for the motor
angle.

Also we are using SysBios in our application. That's why I had to refactor the code of proj_lab12,
because in SysBios I do not have any main loop. As far as I know there is no example available
showing how to use the motorware within SysBios, right?

My Software is build up as follows:

  1. I have a background task, that switches on/off the motor PWM depending on the state of the controller: 
    void motorTaskFxn(UArg a0, UArg a1)
    {
        for(;;)
        {
            if(CTRL_isError(ctrlHandle))
            {
                // set the enable controller flag to false
                CTRL_setFlag_enableCtrl(ctrlHandle,false);
    
                // disable the PWM
                HAL_disablePwm(halHandle);
            }
            else
            {
                // update the controller state
                bool flag_ctrlStateChanged = CTRL_updateState(ctrlHandle);
    
                if(flag_ctrlStateChanged)
                {
                    CTRL_State_e ctrlState = CTRL_getState(ctrlHandle);
    
                    if(ctrlState == CTRL_State_OffLine)
                    {
                        // enable the PWM
                        HAL_enablePwm(halHandle);
                    }
                    else if(ctrlState == CTRL_State_OnLine)
                    {
                        HAL_updateAdcBias(halHandle);
    
                        // enable the PWM
                        HAL_enablePwm(halHandle);
                    }
                    else if(ctrlState == CTRL_State_Idle)
                    {
                        // disable the PWM
                        HAL_disablePwm(halHandle);
                    }
    #ifdef FAST_ROM_V1p6
                    if ((CTRL_getFlag_enableUserMotorParams(ctrlHandle) == true) &&
                        (ctrlState > CTRL_State_Idle))
                    {
                        // call this function to fix 1p6
                        USER_softwareUpdate1p6(ctrlHandle);
                    }
    #endif
                }
            }
    
            updateGlobalVariables_motor(ctrlHandle, stHandle);
    
            // sleep for some time (10ms)
            Task_sleep(MOTOR_TASK_SLEEP_TIME);
        }
    }

  2. Then I have a task that starts the motor identification and steps through each state. The whole process is started with the following function:
    static void setupController()
    {
        // set the default controller parameters (Reset the control to re-identify the motor)
        CTRL_setParams(ctrlHandle,&gUserParams);
    
        // setup the SpinTAC Components
        ST_setupVelCtl(stHandle);
        ST_setupPosConv(stHandle);
    
        // Dis-able the Library internal PI.  Iq has no reference now
        CTRL_setFlag_enableSpeedCtrl(ctrlHandle, false);
    
        // enable/disable the use of motor parameters being loaded from user.h
        CTRL_setFlag_enableUserMotorParams(ctrlHandle, true);
    
        // enable/disable Rs recalibration during motor startup
        EST_setFlag_enableRsRecalc(((CTRL_Obj *)ctrlHandle)->estHandle, true);
    
        // enable/disable automatic calculation of bias values
        CTRL_setFlag_enableOffset(ctrlHandle, true);
    
        // enable or disable the control
        CTRL_setFlag_enableCtrl(ctrlHandle, true);
    }

  3. The statemachine is called every 1ms and the steps during motor identification are:
        switch (m_nCurrState)
        {
            case PREPARE_MOTOR_START:
            {
                if (EST_isMotorIdentified(obj->estHandle))
                {
                    // set the speed acceleration
                    CTRL_setMaxAccel_pu(ctrlHandle,_IQmpy(MAX_ACCEL_KRPMPS_SF, _IQ(1.0)));
    
                    USER_calcPIgains(ctrlHandle);
    
                    // initialize the watch window Bw value with the default value
                    velCtlBwScale = STVELCTL_getBandwidthScale(stObj->velCtlHandle);
    
                    // initialize the watch window with maximum and minimum Iq reference
                    velCtlOutputMax_A = _IQmpy(STVELCTL_getOutputMaximum(stObj->velCtlHandle), _IQ(USER_IQ_FULL_SCALE_CURRENT_A));
                    velCtlOutputMin_A = _IQmpy(STVELCTL_getOutputMinimum(stObj->velCtlHandle), _IQ(USER_IQ_FULL_SCALE_CURRENT_A));
    
                    // wait until estimator and controller is online
                    m_nCurrState = PREPARE_MOTOR_ONLINE;
                }
                break;
            }
    
            case PREPARE_MOTOR_ONLINE:
            {
                CTRL_State_e ctrlState = CTRL_getState(ctrlHandle);
                EST_State_e  estState  = EST_getState(obj->estHandle);
    
                // set the SpinTAC (ST) bandwidth scale
                STVELCTL_setBandwidthScale(stObj->velCtlHandle, velCtlBwScale);
    
                // set the maximum and minimum values for Iq reference
                STVELCTL_setOutputMaximums(stObj->velCtlHandle, _IQmpy(velCtlOutputMax_A, _IQ(1.0/USER_IQ_FULL_SCALE_CURRENT_A)), _IQmpy(velCtlOutputMin_A, _IQ(1.0/USER_IQ_FULL_SCALE_CURRENT_A)));
    
                // enable/disable the forced angle
                EST_setFlag_enableForceAngle(obj->estHandle, false);
    
                if (ctrlState == CTRL_State_OnLine && estState == EST_State_OnLine)
                {
                    // enable the SpinTAC Speed Controller
                    STVELCTL_setEnable(stObj->velCtlHandle, true);
    
                    // motor is ready to use
    m_nCurrState = PREPARE_FINISH; } break; }

This is really a serious problem for us, as I don't know what is the reason and how to provoke it. So does someone has an idea what can be the cause for this behaviour. Or maybe I did something wrong when using SysBios here?

Sebastian

  • Sebastian,

    When you are doing the motor identification, is the angle for the FOC provided by the encoder or the sensorless estimator?

    In the proj_lab12 projects we use the RsRecalibration in order to align the motor and the encoder.  If not enough current was used to move the motor into alignment, it can cause an issue where the encoder calibration is not aligned the electrical angle of the motor.  If this occurs the motor can spin out of control.  it is important to get a good calibration between the motor and the encoder.

  • Hi,

    this uncontrolled spinning is very dangerous in our environment. Is there any way to detect that the motor/encoder calibration was not successful? Then I can shutdown the motor (controller, estimator, pwm whatever).

    But in the end I need a working motor. I can increase the current that is used for the alignment. This is the parameter USER_MOTOR_RES_CURRENT in the user.h file, right? This is currently set to 1.0.

    Sebastian

  • Sebastian,

    You could detect the direction of motor movement.  Typically if this happens, the motor will be spinning in the clockwise direction which is considered negative by the encoder.

    Does this only happen during motor identification, does it happen when you startup the motor normally?

    Do you need to do the motor identification each time the motor starts up?

    If you increase the USER_MOTOR_RES_CURRENT in the user.h file it will do the alignment more strongly which should help with this issue.  This can be set as high as motor max current.

    The other approach is to use a different mechanism for aligning the motor and encoder.  The eQEP peripheral will latch the encoder count when the index line is seen.  If you know the motor's electrical angle when it is on the index, from that information and the latched encoder count you can build a very robust encoder calibration.  Another option is to use an encoder that can also provide absolute information over SPI.  This will allow you to get the initial encoder position at power up.

  • LineStream - Adam Reynolds said:

    If you increase the USER_MOTOR_RES_CURRENT in the user.h file it will do the alignment more strongly which should help with this issue.  This can be set as high as motor max current.

    I would like to chime in with this statement. We should document this in the motorware user's guide.

    Specially, for hard-to-spin motors, they need a high value for  USER_MOTOR_RES_CURRENT.

    I was able to spin all motors in house by increasing this value.All motors we have in house are with very very low Ls_d values !

    With one particular motor, the max current is 10A but the  USER_MOTOR_RES_CURRENT is set at 7A !

    I even got one driver board with a damaged DRV8301 chip because of lower value of USER_MOTOR_RES_CURRENT applied on this particular motor. (Very few commercial ESC could spin this motor even.)

    The Is in the RamUp state goes up to 7A every time for that motor!  With lower values of  USER_MOTOR_RES_CURRENT, the motor would shake violently ! The motor would become very hot and without a fuse the driver board could damage the  DRV8301 chip! 

    Before increasing the value I had 5A fuses and have burnt so many of them! Now I am using a 10A fuse,

    I really would like  to hear an explanation for this behavior.