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.

BLDC runs backwards when using a QEP encoder, but only from certain motor start positions.

Other Parts Discussed in Thread: DRV8301

Hi

We are experiencing a problem using the TI evaluation board DRV8301-HC-EVM Rev D powering a Sonceboz motor (model 5642 - 5 pole pairs, low inductance). Our problem occurs when using lab 12b for velocity control with quadrature.

If we use a 1000 line encoder feeding into the QEP, we get one of two behaviours depending on the starting angle of the motor: either it is fine, or it runs backwards at full speed. When running backwards the problem appears to be something to do with the output – the velocity speedQEP_krpm is correctly measured as large and negative, the error signal is large and the controller is requesting (and getting) maximum current. The motor has 12 detents and starting from half of these gives the problem, the other half gives perfectly normal control. It is completely repeatable. If we use the FAST estimator instead of QEP (lab 5d), it works correctly in all start positions (although the RPM is not very smooth).

When working normally, EST_getAngle_pu() and ENC_getElecAngle() track reasonably well. When not working, the former angle rises as before but the encoder derived angle falls very slowly for about one (electrical) revolution; then both angles change so quickly that we cannot sample them.

Thanks for any help.

  • Hi Rich,

    " So 0 // 6 (there should be a comma after the 0) is state 0 for array index 6 " 

    yes I put comma after each number, but for example in array index 6 I have state 010 which is the state 2, isn't it?

    Regards,

  • Remember that we are mapping from 3*Hall bits => state okay. Array index is the 3*Hall bits, and the value at that position is the state. The state is the OFFSET from 0 degrees angle.

    When you have UHallA, B and C make 6, which is 110b then that maps to High, High, Low which is the zero'th state.
  • Hi Rich,

    Thank you for your clarifications.

    now (refering to your first suggestion), I have problem just with :

    array 4 (100b)  --->  you put state (angle) 1 , I found 3

    array 1 (001b) ---> you put state (angle) 3 , I found 6

    regards,

  • Hi Sanet

    Okay rememebr that I have coded this for:
    UhallA is bit 2 (MSB)
    UhallB is bit 1
    UhallC is bit 0 (LSB)

    Array index 4 is definitely state 1 (the 2nd counting from zero). HIGH, LOW, LOW occurs only at position 1. If you were coding your A, B, C in reverse to me then you could get state 3. But in my notation for you we use A (MSB), B, C (LSB).

    With item 1 I cannot see how you get 6, but it really is 3. Remember the first state is zero, so this is the forth along.

    Rich
  • Hi Chris,

    you are right ^^, I am confusing between LSB and MSB. So inspiring by your function I found this :

    _iq ANG_getElecAngle (uint16_t* hallBits, uint32_t* mapErrors, uint32_t* inDegrees)
    {
    
        _iq rtnElecAngle_pu;
    
       // get register data Port B
        uint32_t gpioBdata = ((GPIO_Obj*) hal.gpioHandle)->GPBDAT;
    
        //!! attribute the three Hall Bits
        gpioBdata >>= 8;
        gpioBdata &= 0x000007; // only 3 LSBs are valid
        uint16_t S_abc = ((gpioBdata & 1) << 2) | (gpioBdata & 2) | ((gpioBdata & 4) >> 2);
    
        *hallBits = (S_abc << 2) ;
    
        if (HallAngles[*hallBits] == 65535)
        {
          // do not update motorElecAngle
          *mapErrors += 1;
        }
        else
        {
          *inDegrees = (HallAngles[*hallBits] * SEGMENT_SIZE) + MID_POINT_FROM_EDGE_OFFSET;
        }
    
        rtnElecAngle_pu = (((((uint32_t) 1) << 24)) / 360) * (*inDegrees);
    
        return rtnElecAngle_pu;
    }
    

    wht do you think !

    Regards,

     

  • Name is Rich ;-)

    Yes it looks good. I cannot check your GPIO shifting on line 12 of course. So your segment size and MID_POINT size are the same as mind?

    Rich
  • So sorry Rich for confusing your name :), because I am in parallel with Chris for another question ^^!

    as segment size, I put 30 because on one electrical revolution I have 180°, and the number of segment is 6 then the segment size is

    30. and the MID_point is the half of segment size which is 15 !

    I am a taker if you have more clarifications.

    Best regards,

  • And you Rich, how did you choose these parameters ?
  • Hi there rich,
    How about your last conditional test? (especially "gElecOffsetMotorToReal_pu")
  • Hi Sanet

    There is every possibility that the alignment of electrical angle between your motor's datasheet and InstaSPIN is incorrect. For both, zero degrees is an arbitrary point in the electrical angle circle.

    gElecOffsetMotorToReal_pu is used to apply an offset to the observed motor's angle and align it with what InstaSPIN wants. I have no idea what you need here, but it'll be a value between 0..1 IQ24.
  • Hi Rich,

    At first, how did you choose " MID_POINT_FROM_EDGE_OFFSET ", (for me the MID_point is the half of segment size which is 15)?

    -" gElecOffsetMotorToReal_pu "  is defined how in your system? is it a system value or it's up to us to describe it?

    -why did you substract it from gMotorElecAngle_pu?, it was consistent to link gMotorElecAngle_pu directely to

    the enc.enc_zero_offset, no! (note that I disabled Rs recalibration then the forcing alignment !)

    Think you for your collaboration

  • Hi Sanet

    Well your segment size, from memory is 60 degrees. You have six discrete angles that you can observe with your three bits (2 ^ 3 - 2). That's 360 / 6 which is 60 degrees. The midpoint from edge offset then needs to be half of that so that your reported angle is in the middle of the angle segment, minimizing the error. So yours is 30, I think. And your segment size is 60.

    gElecOffsetMotorToReal_pu is a variable that I created. It is just an angle offset in pu (0..1) to align your motor's reported electrical angle with what InstaSPIN wants.

    Rich
  • Hi Rich,

    "That's 360 / 6 which is 60 degrees"--> But I have two pair poles, so refering to my diagram above, I have six state in half mechanical revolution : I deducted 180/6 = 30 and the mid point is 15, are you agree with me? (if you have document or reference about the '  MID_POINT_FROM_EDGE_OFFSET ' would you me send it).

    "to align your motor's reported electrical angle with what InstaSPIN wants." --> How can I know what InstaSpin wants? and what will happen if I link  gMotorElecAngle_pu  directely to the  enc.enc_zero_offset ?

    Best regards,

     

  • Hi Rich,

    I think that "gElecOffsetMotorToReal_pu" is the value returned by:

    if((EST_getState(obj->estHandle) == EST_State_Rs) && (USER_MOTOR_TYPE == MOTOR_Type_Pm))
      {
    	  ENC_setZeroOffset(encHandle, (uint32_t)(HAL_getQepPosnMaximum(halHandle) - HAL_getQepPosnCounts(halHandle)));
      }
    
      return;
    } // end of mainISR () function

    In my case I disable it , that's why I set "gElecOffsetQep_pu = gMotorElecAngle_pu" without  gElecOffsetMotorToReal_pu.

    What do you think?

    Regards,

  • Hi Rich,

    I am getting the correct angles from hall sensors, but sometimes at starting I have some vibrations!
    Do you have a smooth runnig?
    Would you describe your results if possible?

    Best regrads,