1

I am using an encoder motor for one of my projects and i was reading encoder values manually through Arduino. It was working fine when i turned it slowly, but whenever i would rotate it at some higher speed, data input to the arduino would stop. I am using the encoder at 4 x.

Can somebody help me with some code to read the data from encoder faster.

    int pulses, A_SIG=0, B_SIG=1;

void setup(){
  attachInterrupt(0, A_RISE, RISING);
  attachInterrupt(1, B_RISE, RISING);
  Serial.begin(115200);
}//setup


void loop(){

}

void A_RISE(){
 detachInterrupt(0);
 A_SIG=1;

 if(B_SIG==0)
  pulses++;//moving forward
 if(B_SIG==1)
  pulses--;//moving reverse
 Serial.println(pulses);
 attachInterrupt(0, A_FALL, FALLING);
}

void A_FALL(){
  detachInterrupt(0);
 A_SIG=0;

 if(B_SIG==1)
    pulses++;//moving forward
 if(B_SIG==0)
     pulses--;//moving reverse
 Serial.println(pulses);
 attachInterrupt(0, A_RISE, RISING);  
}

void B_RISE(){
  detachInterrupt(1);
  B_SIG=1;

  if(A_SIG==1)
     pulses++;//moving forward
  if(A_SIG==0)
      pulses--;//moving reverse
  Serial.println(pulses);
  attachInterrupt(1, B_FALL, FALLING);
}

 void B_FALL(){
    detachInterrupt(1);
    B_SIG=0;

    if(A_SIG==0)
       pulses++;//moving forward
    if(A_SIG==1)
       pulses--;//moving reverse
    Serial.println(pulses);
    attachInterrupt(1, B_RISE, RISING);
}
Adnan
  • 19
  • 1
  • 2
  • 8

2 Answers2

1
volatile long rawTacho[2];      // interrupt 0 & 1 tachometers

ISR(MotorISR1)
{
    int b = digitalReadFast(8);
    if (digitalReadFast(2))
        b ? rawTacho[0]-- : rawTacho[0]++;
    else
        b ? rawTacho[0]++ : rawTacho[0]--;
}

ISR(MotorISR2)
{
    int b = digitalReadFast(9);
    if (digitalReadFast(3))
        b ? rawTacho[1]-- : rawTacho[1]++;
    else
       b ? rawTacho[1]++ : rawTacho[1]--;
}

void setup()
{
    pinMode(2, INPUT_PULLUP);
    pinMode(3, INPUT_PULLUP);
    pinMode(8, INPUT_PULLUP);
    pinMode(9, INPUT_PULLUP);

   attachInterrupt(PCINT0, MotorISR1, CHANGE);  // pin 2
   attachInterrupt(PCINT1, MotorISR2, CHANGE); // pin 3
}

something similar to that - it was extracted from bigger code so you will have read it and understand it as opposed to copy paste.

Update note: This is not complete in a pure form - the cpu doesnt tell you what pin had an interrupt - thus some underlying Arduino code figures that out for me, but it is fairly efficient, and I used it as is. Also if it is not obvious, this is reading encoders from 2 motors. 1 interrupt is assigned to each motor, the second phase of each is on a non-interrupt pin. Never lost a reading to my knowledge.

The problem with your code is probably the print in the interrupt as pointed out in a comment.

0

I built a measuring bench using a glass slide (intended for DRO) with quadrature output. I found the Arduino was easily overwhelmed and would miss beats. I also tried implementing a D flip flop to halve the resolution of the slide. Ultimately, I put a LS7166 IC in the prototyping area of the freeduino eleven I was using and then performed a PORT read on D0-D7.

Krista K
  • 526
  • 3
  • 9