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.

QEP index count

We need to keep track of our system's position using the index count. We'd like it to increment in the positive direction and decrement in the negative direction. We're using Lab12B as the basis. What's the best way to do this? Would setting up an ISR on the index interrupt cause problems elsewhere?

  • We're running an F2806xM ISO controlCARD on the HV board.

    Is there a Position Rollover Count variable (signed index pulse count) in a data structure that we can use?
  • Jim,

    Since you are working with lab 12b you should be able to use SpinTAC Positon Convert in order to keep track of your system's position.  It will output the number of mechanical revolutions since powering on and will also report the number of rollovers it has seen.  When combining these two readouts you should be able to construct your system's position.

    You could also add an index ISR, provided that it was a brief ISR I don't see it causing major system issues.

  • I looks like

    revolutions = (st_obj.vel.conv.PosROCounts * 20) + st_obj.vel.conv.Pos_mrev/_IQ(1.0);

  • Jim,

    That is correct, except that the first rollover only indicates 10 revolutions since the position counter starts at 0 and not -10.
  • LineStream - Adam Reynolds said:
    Jim,

    That is correct, except that the first rollover only indicates 10 revolutions since the position counter starts at 0 and not -10.

    Dear Adam,

    I also have a similar needs to use QEP counts for negative values. But because the function HAL_getQepPosnCounts() which returns an uint32_t value, so how can I get a negative value for counts when motor run in reverse direction?

    Moreover, I want to know the unit which is returned by STPOSCONV_getPostionRollOver() and STPOSCONV_getPosition_mrev(). 

    What is position roll-over value?

    How to convert from "mrev" to Qep counts? 

    Thank you in advance,

  • Tran Binh Duong said:
    But because the function HAL_getQepPosnCounts() which returns an uint32_t value, so how can I get a negative value for counts when motor run in reverse direction?

    The QEP hardware is only configured to count up.  You can check the direction flag and convert the value from positive to negative.

    Tran Binh Duong said:
    Moreover, I want to know the unit which is returned by STPOSCONV_getPostionRollOver()

    This is the number of position rollovers seen by SpinTAC since the device was started.  The SpinTAC position scheme operates between 10 & -10 mechanical revolutions that it is tracking based on the electrical angle from the encoder.

    Tran Binh Duong said:
    and STPOSCONV_getPosition_mrev(). 

    This is in the units of mechanical revolutions within the 10 to -10 window.

    Tran Binh Duong said:
    What is position roll-over value?

    This indicates how many times the position signal has rolledover from 10 to -10 (positive rollover) and -10 to 10 (negative rollover).  It is a counter of the total number of rollovers.

    Tran Binh Duong said:
    How to convert from "mrev" to Qep counts? 

    Mrev is mechanical revolutions.  So 1 mrev = max qep count.

    I've attached a document that should help illustrate the windowed position system used by SpinTAC.

    8540.SpinTAC_Position_Move_Rollover.pdf

  • Dear Adam,

    According to the above discussion, in order to convert from rollover counts to Qep counts I will use the following equations:

    float_t revolutions = (st_obj.vel.conv.PosROCounts * 20) + st_obj.vel.conv.Pos_mrev/_IQ(1.0);

    int32_t counts = revolutions * (4*USER_MOTO_ENCODER_LINES - 1)

    Right?

  • That appears correct.  The only thing missing is that the first rollover count is only 10 revolutions since the system starts at 0 and not -10.

  • LineStream - Adam Reynolds said:

    That appears correct.  The only thing missing is that the first rollover count is only 10 revolutions since the system starts at 0 and not -10.

    Dear Adam,

    As your explanation in a topic, SpinTAC's position system uses relative positioning, so in order to get the absolute position, I will have to use the rollover counter to convert from the relative position to the absolute position. But how must I use to do this? What is the equation to use for this conversion? 

    In other words, I want to know: 1 rollover count = ??? Qep encoder counts?

    I tried the above conversion, but it seems that this equation returned wrong results. Whether I should replace by the following calculation:

    //! \brief		Get the current position in counts
    //! \param[in]	handle	The SpinTAC handle
    //! \return		counts	The number of absolute position counts
    //!
    inline int32_t SERVO_getPositionCounts(ST_Handle handle)
    {
    	ST_Obj *stObj = (ST_Obj *)handle;
    	//_iq posMrev = STPOSCONV_getPosition_mrev(stObj->posConvHandle);
    
    	//float_t posMrev = (20.0*stObj->pos.conv.PosROCounts) + stObj->pos.conv.Pos_mrev/_IQ(1.0); //-->Wrong
    
    	float_t posMrev = (20.0*stObj->pos.conv.PosROCounts) + _IQtoF(stObj->pos.conv.Pos_mrev);
    
    	return (int32_t)((posMrev)*(4*USER_MOTOR_ENCODER_LINES - 1);
    } //end of the SERVO_getPositionCounts() function

    Please verify for me as soon as possible. 

    Thanks

  • I think you have an error in your code.  There is an extra parentheses in the return statement.

    Additionally, you aren't accounting for the first rollover period only represents 10 mechanical revolutions.

    So you should use something near the following:

     

    if(abs(stObj->pos.conv.PosROCounts) >= 1)
    {
      if(stObj->pos.conv.PosROCounts > 0)
      {
        posMrev = 20.0 * (stObj->pos.conv.PosROCounts-1) + 10.0;
      }
      else
      {
        posMrev = -20.0 * (stObj->pos.conv.PosROCounts+1) - 10.0;
      }
    }
    
    posMrev += stObj->pos.conv.Pos_mrev

  • Dear Adam,

    Thank you for your help!

    I have tried your solution and verify that: it would be true if we modified your code a little bit, as following:

    if(abs(stObj->pos.conv.PosROCounts) >= 1)
    {
      if(stObj->pos.conv.PosROCounts > 0)
      {
        posMrev = 20.0 * (stObj->pos.conv.PosROCounts-1) + 10.0;
      }
      else
      {
        posMrev = -20.0 * (stObj->pos.conv.PosROCounts+1) - 10.0;
      }
    }
    
    posMrev += _IQtoF(stObj->pos.conv.Pos_mrev);

    int32_t posCounts = (int32_t)(4*USER_MOTOR_ENCODER_LINES*posMrev)+1;

    Relating to using SpinTAC-POSMOVE, I have one more two questions:

    1. In the Position Mode, while the motor is stepping for a Position Profile, whether we can change the MaxVel value which was set in the beginning of the movement or not? and How can we do that?

    2. How can we stop the motor immediately while it is rotating in Position Mode and have not finished its position profile?

    We want to do two above things, because our application needs these features. So please guide me to use SpinTAC-POSMOVE and SpinTAC-POSCTRL to do them.

    Thank you very much!

    
    
  • Tran Binh Duong said:
    1. In the Position Mode, while the motor is stepping for a Position Profile, whether we can change the MaxVel value which was set in the beginning of the movement or not? and How can we do that?

    SpinTAC Position Move is designed as a point-to-point profile generator, it does not support changing the profile limits during a profile.  In order to change the profile limits you would need to stop the profile and begin a new one.

    Tran Binh Duong said:
    2. How can we stop the motor immediately while it is rotating in Position Mode and have not finished its position profile?

    If you disable the profile generator this will place it into HALT mode where it will decelerate the motor to 0 speed using the HaltAccelLimit and HaltJerkLimit.