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.

Smooth motor movements at very low speed

Other Parts Discussed in Thread: DRV8301, MOTORWARE

Hello all,

I'm very new to BLDC motors and trying to smoothly rotate a motor even at low speed. Also it is very important to stop at a certain position. Therefore I'm using InstaSPIN-FOC on the DRV8301 evaluation kit.

My motor has an encoder attached with 8000 steps per revolution. I can read the absolute position in software but this is not connected to the motor controller/estimator in software anyhow.

I have no problem rotating the motor at high speed (200 Upm and more...)

But I need to position the motor and therefore I have to drive at very low speed and at the desired position the motor has to stop.

My main problems are:

- At very low speed the motor rotates not smoothly. The speed is not constant.

- When the motor has stopped (speed is zero), it is still oscillating and moving in one or the other direction. The motor does not have any torque to hold the position.

I have tried the motorware example and played with some settings (RsRecalc, automatic Offset  calculation, estimator forced angle), but it is not working as expected.

I have also read many topics in the forum and for my understanding the estimator is not able to calculate the angle at very low speed and this is the reason for my problems? Butwhat can I do to solve it?

My software looks similar to proj_lab03x even I have added the encoder to read the absolute position.

So what have am I doing wrong? Do you have any suggestions for me?

Sebastian

  • sebastian michel said:
    - At very low speed the motor rotates not smoothly. The speed is not constant.

    What proj_lab# are you using?

    For very low speed you need to use a mechanical rotor sensor like an encoder.

    The projects that use the encoder are proj_lab12 (velocity) and proj_lab13 (position) under InstaSPIN-MOTION

    From everything you have posted I would guess you are trying to do this without your encoder (or at least the SW isn't using your encoder).

    Please follow the Lab User's Guide to work sensorlessly through -FOC 5b and then -MOTION 5f, then move to MOTION 12 and 13 of position is required.

  • Hi,

    everything woks well with example proj_lab13, but I do not want to use InstaSPIN-Motion.

    My starting point is example proj_lab03 with just InstaSPIN-FOC and without encoder support. I added all the stuff needed by the encoder including the enc module to this example. The next step is to manually set the angle in the estimator before I call CTRL_run(...) in the interrupt handler.

    // use encoder position to set estimator angle
    _iq angle_pu = ENC_getElecAngle(encHandle);
    EST_setAngle_pu(((CTRL_Obj *)ctrlHandle)->estHandle, angle_pu);

    // run the controller
    CTRL_run(ctrlHandle,halHandle,&gAdcData,&gPwmData);

    This works quite well, the motor is running smoothly even at low speed. But there is another problem: The motor has no/little torque in comparison to example proj_lab13. This leads to motor oscillating when speed is set zero.

    Is there something I can do to increase the torque?

    Sebastian

  • sebastian michel said:

    everything woks well with example proj_lab13, but I do not want to use InstaSPIN-Motion.

    Why?

    sebastian michel said:

    Is there something I can do to increase the torque?

    Lack of Torque would come from the angle not being correct, are you doing any sort of zero-ing out the electrical to mechanical alignment?

    Lack of Torque could come from the position and velocity controllers not being sufficiently tuned. What are you using, standard cascading PI?

    You have some debugging to do.

  • Hello and thanks for your answer,

    I'm using the encoder module in the same way aas it is done in the example proj_lab12

    void mainISR()
    {
        GPIO_Handle gpioHandle = ((HAL_Obj *)halHandle)->gpioHandle;
        CTRL_Obj *obj = (CTRL_Obj *)ctrlHandle;
    
        // compute the electrical angle
        ENC_calcElecAngle(encHandle);
    
        // TODO: remove test code
        static uint_least32_t gLEDcnt = 0;
    #define LED_BLINK_FREQ_Hz                      5
    #define USER_NUM_PWM_TICKS_PER_ISR_TICK        (3)
    #define USER_PWM_FREQ_kHz                      (45.0)
    #define USER_ISR_FREQ_Hz                       ((float_t)USER_PWM_FREQ_kHz * 1000.0 / (float_t)USER_NUM_PWM_TICKS_PER_ISR_TICK)
        if (gLEDcnt++ > (uint_least32_t)(USER_ISR_FREQ_Hz / LED_BLINK_FREQ_Hz))
        {
            GPIO_toggle(gpioHandle, GPIO_Number_31);
            gLEDcnt = 0;
        }
    
        // convert the ADC data
        HAL_readAdcData(halHandle,&gAdcData);
    
        // use encoder position to set estimator angle
        _iq angle_pu = ENC_getElecAngle(encHandle);
        EST_setAngle_pu(((CTRL_Obj *)ctrlHandle)->estHandle, angle_pu);
    
        // run the controller
        CTRL_run(ctrlHandle,halHandle,&gAdcData,&gPwmData);
    
    
        // write the PWM compare values
        HAL_writePwmData(halHandle,&gPwmData);
    
    
        // setup the controller
        CTRL_setup(ctrlHandle);
    
        // if we are forcing alignment, using the Rs Recalculation, align the eQEP angle with the rotor angle
        if((EST_getState(obj->estHandle) == EST_State_Rs) && (USER_MOTOR_TYPE==MOTOR_Type_Pm))
        {
            ENC_setZeroOffset(encHandle, (uint32_t)(ENC_getPositionMax(encHandle) - ENC_getRawEncoderCounts(encHandle)));
        }
    }

    At the end if the ISR I also set the zero offset.

    Sebastian

  • I'd look at your position and velocity controllers then.