Adjustment to the QEI routines
The initialization routine stays pretty much the same, except that now we don’t want the index pulse to reset POSCNT. So the only change is
Now, how could we detect when overflow/underflow occurs? No big deal, since QEI module provides interrupt service for such event. The procedure is the same as other interrupt routines in dsPIC. We only have to enable it, and reset the interrupt flag. Add these two lines at the end of QEI initialization routine.
The last task for the QEI section is to implement the update of upper 16-bit encoder count. Simply check the QEICONbits.UPDN
bit for the rotation direction, and increase/decrese the value accordingly. Then reset the interrupt flag before leaving the ISR.
void __attribute__((interrupt, auto_psv)) _QEIInterrupt(void)
if (QEICONbits.UPDN) EncCnt.half++;
_QEIIF = 0;
Update of the lower 16-bit count EncCnt.half
by a copy of POSCNT must be done elsewhere before it is used, to avoid the slim chance of inconsistent data. Indeed, for best result the lower 16-bit should be updated very frequently by a timer routine.
With the above mechanism to achive a 32-bit accumulated position, the velocity computation is now much easier. Here we use timer 2 with sampling period 50 millisecond (defined by DELTAT2
refers to 4 times the actual encoder lines minus one. Our eMotor
has 100 encoder lines, so ENCPPRx4 = 100*4 – 1
#define DELTAT2 50
#define ENCPPRx4 399 //
long EncCnt_old; // global variable to keep previous position
void __attribute__((__interrupt__)) _T2Interrupt (void)
IFS0bits.T2IF = 0; // Clear timer 2 interrupt flag
dEnc = EncCnt.full - EncCnt_old;
Velf = (double)dEnc*1000/(ENCPPRx4*DELTAT2);
EncCnt_old = EncCnt.full;