I connected two AMT 103 rotary encoders (mounted on two separate DC motors) to a dspic30f4011(http://www.kynix.com/Detail/635415/DSPIC30F4011T-30I%2FPT.html) and read the values using interrupts (instead of qei as the dspic only has one). However, the error in the values increase the farther and faster we go when running the motors simultaneously. One of the theories is that since the interrupts have different priorities one of them overrides the other and causes the error, note that when only one motor is run we don’t have an error. Is this causing the error? If yes how can it be fixed? Will using one qei and one interrupt fix this? Here’s the dspic code:
#include “p30f4011.h”
#include
#include
#include
_FWDT(WDT_OFF)
#define InterruptFlag0_A IFS0bits.INT0IF //Rising Edge on Signal A, Encoder 1
#define InterruptFlag1_A IFS1bits.INT1IF //Rising Edge on Signal A, Encoder 2
#define Encoder0_B PORTBbits.RB0 // Signal B of Encoder 1
#define Encoder1_B PORTBbits.RB1 // Signal B of Encoder 2
//Variables for Calculations
long T1=0;
int counter=0;
int NR=0;
long T2=0;
int counterone=0;
int NRone=0;
long i;
//-------------------------
int main()
{
ADCON1=0x0F;//digital
TRISBbits.TRISB0=1;//RA inputs
TRISBbits.TRISB1=1;//RA inputs
//Interrupts init
IFS1bits.INT1IF = 0; /*Reset INT1 interrupt flag */
IEC1bits.INT1IE = 1; /*Enable INT1 Interrupt Service Routine */
IFS0bits.INT0IF = 0; /*Reset INT1 interrupt flag */
IEC0bits.INT0IE = 1; /*Enable INT1 Interrupt Service Routine */
while(1) //NEGATIVE ROTATIONS ARE CW. POSITIVE ROTATIONS ARE CCW
{
T1= ((long)NR*10000)+(long)counter;
T2= ((long)NRone*10000)+(long)counterone;
}
return 0;
}
void attribute((interrupt)) _INT0Interrupt(void);
void attribute((interrupt, auto_psv)) _INT0Interrupt(void)
{
if(InterruptFlag0_A==1) {
if(Encoder0_B==1) {
counter=counter-1;
InterruptFlag0_A=0;
} else if (Encoder0_B==0) {
counter=counter+1;
InterruptFlag0_A=0;
}
}
if(counter==10000) {
counter=0;
NR=NR+1;
} else if(counter==-10000) {
counter=0;
NR=NR-1;
}
}
void attribute((interrupt)) _INT1Interrupt(void);
void attribute((interrupt, auto_psv)) _INT1Interrupt(void)
{
if(InterruptFlag1_A==1) {
if(Encoder1_B==1) {
counterone=counterone+1;
InterruptFlag1_A=0;
} else if (Encoder1_B==0) {
counterone=counterone-1;
InterruptFlag1_A=0;
}
}
if(counterone==10000) {
counterone=0;
NRone=NRone+1;
} else if(counterone==-10000) {
counterone=0;
NRone=NRone-1;
}
}