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.

CCS/TMS320F28335: Controlling Motor direction and position using Motor encoder

Part Number: TMS320F28335
Other Parts Discussed in Thread: CONTROLSUITE

Tool/software: Code Composer Studio

  I am trying to control a direction and position of encoder-mounted Motor  via  EQEP.   Position control is working good, where as direction reading fluctuates from 0 to 1 and vice versa, though it is keep moving to the same  direction. The code is here below:

#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File

/* Define for this example */
#define ENCODER_REV  200  /* Pulse/Revolution */
/* Prototype statements for functions found within this file */
void InitEQep1(Uint32 PositionMax);

interrupt void eqep1_isr(void);
/* Global variables used in this system */
Uint16 BackTicker;
Uint32 PositionMax;
Uint32 PositionCounter;
Uint32 RotateDirection;
float32 RotateAngleUnit;
float32 RotateAngleDegree;
void main(void)
{
/*-----------------------------------------------------------------------------
 Step 1
 Disable Global Interrupt & Interrupt Flag Clear
-----------------------------------------------------------------------------*/
 DINT;
 InitPieCtrl();
 IER = 0x0000;
 IFR = 0x0000;

     InitSysCtrl();
    InitPieVectTable();
 
    EALLOW;  // This is needed to write to EALLOW protected registers
    PieVectTable.EQEP1_INT= &eqep1_isr;
    EDIS;    // This is needed to disable write to EALLOW protected registers

 /* for Qep */
 EALLOW;
 GpioCtrlRegs.GPAPUD.bit.GPIO20 = 0;  /* Enable pull-up on GPIO50 (EQEP1A) */
 GpioCtrlRegs.GPAPUD.bit.GPIO21 = 0;  /* Enable pull-up on GPIO51 (EQEP1B) */
 GpioCtrlRegs.GPAPUD.bit.GPIO22 = 0;  /* Enable pull-up on GPIO52 (EQEP1S) */
 GpioCtrlRegs.GPAPUD.bit.GPIO23 = 0;  /* Enable pull-up on GPIO53 (EQEP1I) */
 GpioCtrlRegs.GPACTRL.bit.QUALPRD2 = 0xFF; /* Specifies the qualification sampling period for GPIO48 to GPIO55 */
 GpioCtrlRegs.GPAQSEL2.bit.GPIO20 = 2;  /* Qualification using 6 samples */
 GpioCtrlRegs.GPAQSEL2.bit.GPIO21 = 2;  /* Qualification using 6 samples */
 GpioCtrlRegs.GPAQSEL2.bit.GPIO22 = 2;  /* Qualification using 6 samples */
 GpioCtrlRegs.GPAQSEL2.bit.GPIO23 = 2;  /* Qualification using 6 samples */
 GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 1; /* Configure GPIO50 as EQEP1A */
 GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 1; /* Configure GPIO51 as EQEP1B */
 GpioCtrlRegs.GPAMUX2.bit.GPIO22 = 1; /* Configure GPIO52 as EQEP1S */
 GpioCtrlRegs.GPAMUX2.bit.GPIO23 = 1; /* Configure GPIO53 as EQEP1I */
 EDIS;
 
 BackTicker = 0;
 PositionMax = ENCODER_REV * 20;
 PositionCounter = 0;
 RotateDirection = 0;
 RotateAngleUnit = 0;
 RotateAngleDegree = 0;
 IER |= M_INT5;
 // Enable TINT0 in the PIE: Group 5 interrupt 1
    PieCtrlRegs.PIEIER5.bit.INTx1 = 1;

     InitEQep1(PositionMax);

    EINT;   /* Enable Global interrupt INTM */
 ERTM; /* Enable Global realtime interrupt DBGM */

 for(;;)
 {
  
 }
}

interrupt void eqep1_isr(void)
{

          BackTicker++;
   /* Check Position & Direction */
   PositionCounter = EQep1Regs.QPOSCNT;
   RotateDirection = EQep1Regs.QEPSTS.bit.QDF;
   RotateAngleUnit = (float32)PositionCounter / PositionMax;
   RotateAngleDegree = RotateAngleUnit * 360;
      EQep1Regs.QCLR.bit.INT=1;
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP5;
}
/*-----------------------------------------------------------------------------
 Step 10
 10.1 Local Interrupt Service Routines & Functions
-----------------------------------------------------------------------------*/
void InitEQep1(Uint32 PositionMax)
{
     EQep1Regs.QDECCTL.bit.QSRC=00;      // QEP quadrature count mode
     EQep1Regs.QEPCTL.bit.FREE_SOFT = 2;
     EQep1Regs.QEPCTL.bit.PCRM=1;       // 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 = 0xFFF ;         // for an encoder with 12-bits
     EQep1Regs.QPOSMAX = PositionMax - 1; /* 24 x 4 QCLK @ 1 revolution */
     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

     EQep1Regs.QPOSCTL.bit.PCE = 1 ; // enable position compare unit
     EQep1Regs.QEINT.bit.PCM = 1 ;   // enable pos compare interrupt
}
The variable 'RotateDirection' in the interrupt handler function keeps changing all the time whether the motor is moving clockwise or anticlockwise.
would you help me in solving this problem?
(F.Y.I :  the motor with  encoder is pkp264d28a-r2el)
Thank you

  • Hi,

    I checked the encoders that you are using, they have 3 channel output. Can you please make sure whether they are 2 channel quadrature encoders or not. Because you have configured eqep in Quadrature mode that requires only two output signals to figure out the direction. But this encoder gives 3 signals, once check that.

    Also there is not really much need for qualification for GPIOs used in eqep. Try once without using qualification. 

    Thanks

    Himanshu

  • As Himanshu mentioned above, it is important to ensure that the physical connections are done correctly and configure the EQEP to a right count mode, Quadrature count mode.

    What do you mean PositionMax = ENCODER_REV * 20 and EQep1Regs.QPOSMAX = PositionMax - 1, the QPOSMAX should equal to 4*Encoder Lines.

    You might refer to below example project if you install controlSUITE.
    www.ti.com/.../controlsuite

    C:\ti\controlSUITE\development_kits\HVMotorCtrl+PfcKit_v2.1\HVPM_Sensored_Servo
  • Himanshu, Thanks a lot.
    As to my understanding the third signal is just to count number of revolutions. it is triggered once per revolution., which doesn't matter much in my application. I have also tried by avoiding GPIO qualification, but no change. I have an Delifino EVM form SyncWorks. The same thing is true in that too, however it is not as frequent as my own board(the change of direction  reading is not as frequent as  a controller I made by myself). Thank you once again.

  • Yanming,
    Thank you very much .

    Physically, I don't see some thing wrong in the connection. As I mentioned in the reply to Himanshu , I have also tried with a delfino EVM which has on board encoder and it is the same. ENCODER_REV * 20 is just to indicate a number of revolution is 20. Do you have any more suggestion?

    Thank you
  • It seems like pkp264d28a-r2e is a stepper motor you mentioned, I can't find more detailed information about the encoder in it's manual. Could you please ensure the encoder signal is quadrature pulse and an index pulse for EQEP module, and there is Voltage-Level Translator between encoder and C2000 controller since the power supply of encoder is 5V.
  • Yanming,

    Thank your for your help,

    yes ,it is quadrature pulse. You may find  specification and  operation manual for the encoder on the following link.

    catalog.orientalmotor.com/.../pkp264d28a-r2el

    There is also voltage-level regulator added  between the encoder and controller.

    Thank you once again.

  • You might refer to the EQEP configuration in below example project if you installed controlSUITE, I have tested both, that's fine for a motor with an encoder on my hand. The major difference is that it enables Index input.
    C:\ti\controlSUITE\development_kits\HVMotorCtrl+PfcKit_v2.1\HVPM_Sensored
    C:\ti\controlSUITE\development_kits\HVMotorCtrl+PfcKit_v2.1\HVPM_Sensored_Servo
  • I haven’t heard from you for two weeks, so I’m assuming you were able to resolve your issue. If this isn’t the case, please reject this resolution and reply to this thread. If this thread locks, please make a new thread describing the current status of your issue.
  • Dear Yanming,

    Thank you very much for your suggestion. I have tried all the examples you mentioned. No difference. Even I have tried Delfino TMS32028335 evaluation board  which is from Syncworks.  There is encoder onboard.  Still the direction fluctuates though it goes to same direction.  

    Thank you once again.

    ,

  • You might change the input qualification setting of GPIO, it seems like you have set a too higher sampling period, you should ensure the sampling period is far less than the minimum period of the output signal of an encoder.