Go Down

Topic: Trouble shooting Quadrature Encoders (Read 1 time) previous topic - next topic

D-bot

Hello, i'm new to this forum so please be gentle

I've been playing with some optical quadrature encoders and I've observed some unusual behavior  which has left me a little confused.    The Story so far

I'm using a optical quadrature encoder with 600P/R Incremental Rotary Encoder AB 2 phase 6mm Shaft 5V-24V 12V, i got the encoder from china so no data sheet, it did have this printed on it though
TYPE LPD3806-600BM-85-24C.
 
This is the circuit i've been using



the one difference is that i havn't attached that large black wire (which is attached to the sheath around the other wires)

Using this code 

Code: [Select]
// code start

# include "digitalWriteFast.h" //

const byte pin_A =  2; // connect white wire here
const byte pin_B =  3; // connect green wire here
int A_set =         0;
int B_set =         0;
long pulses =       0;


void setup()
{
  pinMode(pin_A, INPUT);
  digitalWrite(pin_A, HIGH); // enables pull-up resistor
  pinMode(pin_B, INPUT);
  digitalWrite(pin_B, HIGH); // enables pull-up resistor 

  A_set = digitalRead(pin_A);
  B_set = digitalRead(pin_B);

  attachInterrupt(0, encoderPinChange_A, CHANGE); // pin 2
  attachInterrupt(1, encoderPinChange_B, CHANGE); // pin 3

  Serial.begin(9600); 
}


void loop()
{
  Serial.println(pulses);
}


void encoderPinChange_A()
{
  A_set = digitalReadFast2(pin_A) == HIGH;
  pulses += (A_set != B_set) ? +1 : -1;
}


void encoderPinChange_B()
{
  B_set = digitalReadFast2(pin_B) == HIGH;
  pulses += (A_set == B_set) ? +1 : -1;
}


Reading from the serial port i'm able to see the position value (pulses) increase and decrease as i turn the encoder shaft however something isn't quite right.  The position value doesn't increment consistently, also sometimes when i move the shaft quickly over a small angle the position value doesn't change at all.  I did these tests both by hand (hard to be accurate i know) and using a stepper motor linked to the encoder with a timing belt.

After this i tried the following code

Code: [Select]
      volatile long enc_count = 0;
 
void setup() {
    // all your normal setup code
    attachInterrupt(0,encoder_isr,CHANGE);
    attachInterrupt(1,encoder_isr,CHANGE);
}

void loop()
{
  Serial.println(enc_count);
}

void encoder_isr() {
    static int8_t lookup_table[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
    static uint8_t enc_val = 0;
   
    enc_val = enc_val << 2;
    enc_val = enc_val | ((PIND & 0b1100) >> 2)
 
    enc_count = enc_count + lookup_table[enc_val & 0b1111];
}


which only outputted 0 on the serial port, interestingly however when i miss entered the code line

    static int8_t lookup_table[] = {0.-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};

(. instead of , in the array) the code only decreased the position variable for both directions of rotation on the shaft, however it seemed to be incrementing constantly with the shaft turning. 

Now i'm aware that the Serial.print function utilizes a interrupt and this could cause missed pulses or just muddle things up with the ISR, however i have no idea how to trouble shoot with out it (if someone does i would love to hear your ideas).

also not sure if its relevant but my arduino sometimes has the error message, when i upload code
 
avrdude: stk500v2_ReceiveMessage(): timeout

I would appreciate anyones thoughts on how i might trouble shoot this issue.



 

cattledog

Your circuit diagram did not post correctly. Try it as an attachment.

The encoder is likely open collector output and requires external pullup resistors on the AB outputs? The Arduino internal pullups may not not strong enough. Use 2.2K or 4.7K .

Both your codes have some issues, but they both should be giving you counts if the interrupts are present.

D-bot

Hi cattledog thanks for the reply

i'm using 10k resistors which i think I've set up as pull up.

Using the first code, i do read the pulses, my issue is that the pulses don't always correlate to the shaft angle.  For example using a stepper motor linked to the encoder shaft with a timing belt

Stepper motor step    Encoder
0                             0
120                          256
0                             -95

0                             0
-120                         -664
0                             -469

looking at the serial output during part of the 120 steps sometimes over 50 steps elapse with out the encoder value changing. 

i suppose what i'm trying to determine is if my issue relates to a faulty encoder, poor code, some issue with my circuit implementation or if its my using the serial print function.

D-bot

I tired using another encoder that i had, and using the same code it seems to behaving as i expected.

Using a stepper motor and a timing belt i moved forward and back a number of times and the encoder pulses are consistently between 8-25 counts out, given i'm using both channels on a 600p/r encoder and the interrupts are being triggered on changes that will mean 2*600*2=2400 pulses per revolution.  So 25 pulses would be about 4 degrees or so, which could plausibly be caused by backlash, belt stretching and inaccuracy in the stepper.  

So i'm guessing that the first encoder is just faulty :(

Go Up