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.

TMS320F28377D: EQEP setting for index pulse of Encoder

Part Number: TMS320F28377D
Other Parts Discussed in Thread: CONTROLSUITE

Sir/Madam,

I am referencing your example project for qep speed position estimation. In that project following settings have been done to initialize qep module.

 EQep1Regs.QUPRD = 2000000;            // Unit Timer for 100Hz at 200 MHz
                                          // SYSCLKOUT
 EQep1Regs.QDECCTL.bit.QSRC = 00;      // QEP quadrature count mode
 EQep1Regs.QEPCTL.bit.FREE_SOFT = 2;
 EQep1Regs.QEPCTL.bit.PCRM = 00;       // PCRM=00 mode - QPOSCNT reset on
                                          // index event
 EQep1Regs.QEPCTL.bit.UTE = 1;         // Unit Timeout Enable
 EQep1Regs.QEPCTL.bit.QCLM = 1;        // Latch on unit time out
 EQep1Regs.QPOSMAX = 0xffffffff;
 EQep1Regs.QEPCTL.bit.QPEN = 1;        // QEP enable
 EQep1Regs.QCAPCTL.bit.UPPS = 5;       // 1/32 for unit position
 EQep1Regs.QCAPCTL.bit.CCPS = 6;       // 1/64 for CAP clock
 EQep1Regs.QCAPCTL.bit.CEN = 1;        // QEP Capture Enable

Now I have a doubt. Since QCLM bit is set to 1, therefore at every unit timeout, a value will from POSCNT will be latched into POSLAT register which is used for calculating speed. Now PCRM bit is also set to 0, that means POSCNT will be reset to 0 on every index pulse. So my doubt is, since there will be multiple periods within a unit time out, isnt it a possibility that wrong speed will be calculated, as there is no synchronization between time out and index pulses.

Example code I am referencing to is located at "C:\ti\controlSUITE\device_support\F2837xD\v210\F2837xD_examples_Cpu1\eqep_pos_speed\cpu01".

Also I have another doubt, in my application code for close loop vector control I have generated theta by integrating speed. And in TI example code for the PMSM sensored vector control, POSCNT is used for generating theta. Now if theta is generated using POSCNT, it will be reset to 0 at every index pulse, which is mechanical theta. And to convert that to electrical theta it is divided by lines of encoder and multiplied with pole pairs. Now my doubt is doing this calculation will only change the peak of theta but how will it change the frequency of theta to electrical frequency.

Regards

Rishabh

  • Hi,

    Amtech said:

    Now I have a doubt. Since QCLM bit is set to 1, therefore at every unit timeout, a value will from POSCNT will be latched into POSLAT register which is used for calculating speed. Now PCRM bit is also set to 0, that means POSCNT will be reset to 0 on every index pulse. So my doubt is, since there will be multiple periods within a unit time out, isnt it a possibility that wrong speed will be calculated, as there is no synchronization between time out and index pulses.



    That's correct, if there are multiple iterations, you'll have to keep track of the iterations. One option is to take an interrupt on every index and keep track of the number of index occurrences in software. 


    Amtech said:
    Also I have another doubt, in my application code for close loop vector control I have generated theta by integrating speed. And in TI example code for the PMSM sensored vector control, POSCNT is used for generating theta. Now if theta is generated using POSCNT, it will be reset to 0 at every index pulse, which is mechanical theta. And to convert that to electrical theta it is divided by lines of encoder and multiplied with pole pairs. Now my doubt is doing this calculation will only change the peak of theta but how will it change the frequency of theta to electrical frequency.


    Yes, simple multiplication will not change the frequency. You can refer to the specific motor control examples instead of generic examples.
    C:\ti\controlSUITE\development_kits\HVMotorCtrl+PfcKit_v2.1\HVPM_Sensored
    Also, i think you would be using electrical theta for your computations here.



  • In the example that you have refererred, following code is given for theta calculation,

    /* Check the rotational direction */															\
         v.DirectionQep = (*eQEP[m]).QEPSTS.bit.QDF;												\
    																								\
    /* Check the position counter for EQEP1 */														\
         v.RawTheta = (*eQEP[m]).QPOSCNT + v.CalibratedAngle;										\
         																							\
         if (v.RawTheta < 0)																		\
           v.RawTheta = v.RawTheta + (*eQEP[m]).QPOSMAX;											\
         else if (v.RawTheta > (*eQEP[m]).QPOSMAX)													\
           v.RawTheta = v.RawTheta - (*eQEP[m]).QPOSMAX;											\
           																							\
    /* Compute the mechanical angle in Q24 */														\
         v.MechTheta = __qmpy32by16(v.MechScaler,(int16)v.RawTheta,31);  /* Q15 = Q30*Q0 */			\
         v.MechTheta &= 0x7FFF;                                          /* Wrap around 0x07FFF*/	\
         v.MechTheta <<= 9;                                              /* Q15 -> Q24 */			\
    																								\
    /* Compute the electrical angle in Q24 */														\
         v.ElecTheta = v.PolePairs*v.MechTheta;            /* Q24 = Q0*Q24 */						\
         v.ElecTheta &= 0x00FFFFFF;                        /* Wrap around 0x00FFFFFF*/				\
    																								\
    /* Check an index occurrence*/																	\
         if ((*eQEP[m]).QFLG.bit.IEL == 1)    														\
         {  																						\
         	v.IndexSyncFlag = 0x00F0;																\
            v.QepCountIndex = (*eQEP[m]).QPOSILAT;													\
        	(*eQEP[m]).QCLR.bit.IEL = 1;	/* Clear interrupt flag */								\
         }	

    Now the question remains the same. Here for getting electrical theta from mechanical, only multiplication is used. So how do you get the correct electrical theta, since electrical and mechanical frequency are different?

    Another thing is I am generating theta by integrating electrical speed in my application code. But dont know due to some reason, theta goes out of synchronization and motor starts taking more current. So any ideas for the same?

  • Hi,

    There is a wrap around after multiplication in the code above. THat would take care of the conversion.
    Basically, you are ignoring the integer portion and looking at the normalized number after multiplication.
    Since it's a Q24 number v.ElecTheta &= 0x00FFFFFF; would make sure fraction is retained.

  • I have implemented the above code in my software and it is calculating correct frequency. But still I am confused how the wrap around helps in calculating correct electrical frequency. I doubt instead of wrap around, __qmpy32by16 is taking care of conversion. I have referred SPRU514 document, but didnt get any explanation. Can you please tell what operation it does? ( I want to implement  __qmpy32by16 in float, to reduce execution time.)

  • Hi,

    Since the numbers (position etc.) are normalized i.e. scaled from 0 to 1, your calculations are working as expected.
    Then you are further ignoring the integer portion and taking the fraction only which results in correct frequency.
    If you are doing operations in float, then also you can do a similar arithmetic. 

  • I have implemented PMSM sensored control as given in controlsuite example code "HVPM SENSORED". Now motor is running smoothly upto its rated frequency. But it is having problems in starting up. First the motor rotates one revolution in opposite direction and then with a jerk it starts rotating smoothly. Also while it rotates in opposite direction, huge current is drawn.

    I have used pull in method for locking rotor with its nearest poles before giving run command.

  • Hi,
    I'll include motor experts on our team to answer this. Thank you.

  • The initial reverse rotation is probably alignment of the rotor to zero degree. This is needed for calibrating QEP interface. QEP is an incr angle encoder and does not give absolute angle. In order to know the initial position of the encoder with respect to the motor windings, this step is necessary. 

    You may repeat this test few times and find out what the calibrated angle is. You can take a mean of this and hard code the value in your program and skip lsw=0 stage. Pls review the code. Hope it helps.

  • Actually I have implemented only lsw = 0 and lsw= 2 stage.

    As you already know lsw=0 is pull-in, lsw=1 is i/f, and lsw=2 is closed loop vector.

    Now calibrated angle is measured only after lsw =0, because index IEL flag is continuously cleared during lsw=0, and calibrated angle is measured from POSILAT flag(which is not possible, because IEL flag is cleared).

    So I don't understand how are you saying to measure calibrated angle in lsw=0 stage.

    And secondly I am facing issue in close loop vector stage. After pull in when motor is started in Vector, it takes high frequency high current for a moment, and then with a vigorous jerk, it starts rotating properly taking zero current.

    I have checked both with and without calibrated angle, but result is same.

    Regards

    Rishabh

  • I did not say you can get calibrated angle value during lsw=0. After the motor starts running smoothly, read the value of calibrated angle. Like wise, repeat the test for some more readings of the same. Then do a mean and hardcode teh value of calibrated angle and then modify the code to use it at all times. Hope it helps.