Pololu Robotics & Electronics
Menu
My account Comments or questions? About Pololu Contact Ordering information Distributors

Pololu Forum

Counts of Quadrature Encoder

Hi all

Simply ,I had Rover 5 with 2 DC motors and 2 quadrature encoders , I just want to use encoders to measure the distance of traveling for each wheel ,
In the start, I just want to determine the total counts per revolution. I read the article about quadratic encoder from letsmakerobots.com/node/24031

In Rover 5 , each encoder has four wires: red (5V or 3.3V), black(Ground), yellow (Signal 1) and white (Signal 2). I connected each wire in its right place on Arduino Uno board ,

The circuit:
-rotary encoder ChannelA attached to pin 2
-rotary encoder ChannelB attached to pin 3
-rotary encoder 5V attached to 5V
-rotary encoder ground attached to ground

For one encoder, I test these two codes below to determine the total counts or ticks per revolution , the first code by using loop and second by using an interrupt .
But unfortunately while I run each code separately with rotating the wheel by hand 360 degree , the outputs of these two codes was just “gibberish” and I don’t know where is the problem . Could anyone help?

Arduino codes posted below.

First code

// Constants
const int  ChanAPin = 2;    // pin for encoder ChannelA
const int  ChanBPin = 3;    // pin for encoder ChannelB

// Variables
int encoderCounter = -1;   // counter for the number of state changes
int ChanAState = 0;         // current state of ChanA
int ChanBState = 0;        // current state of ChanB
int lastChanAState = 0;     // previous state of ChanA
int lastChanBState = 0;    // previous state of ChanB
void setup() {
  // initialize the encoder pins as inputs:
  pinMode(ChanAPin, INPUT);
  pinMode(ChanBPin, INPUT);
  // Set the pullup resistors
  digitalWrite(ChanAPin, HIGH);
  digitalWrite(ChanBPin, HIGH);

  // initialize serial communication:
  Serial.begin(19200);
  Serial.println("Rotary Encoder Counter");
}
void loop() {
  // read the encoder input pins:
  ChanAState = digitalRead(ChanAPin);
  ChanBState = digitalRead(ChanBPin); 
  // compare the both channel states to previous states
  if (ChanAState != lastChanAState || ChanBState != lastChanBState) {
    // if the state has changed, increment the counter
      encoderCounter++;
      Serial.print("Channel A State = ");
      Serial.println(ChanAState);
      Serial.print("Channel B State = ");
      Serial.println(ChanBState);      
      Serial.print("State Changes = ");
      Serial.println(encoderCounter, DEC);
    // save the current state as the last state, 
    //for next time through the loop
    lastChanAState = ChanAState;
    lastChanBState = ChanBState;    
  }
}

The second code (with interrupt)

static long s1_counter=0;
static long s2_counter=0;
 
void setup()
{
  Serial.begin(115200);
 
  attachInterrupt(0, write_s1, CHANGE); /* attach interrupt to pin 2*/
  attachInterrupt(1, write_s2, CHANGE); /* attach interrupt to pin 3*/
  Serial.println("Begin test");
 
}
 
void loop()
{
}
 
void write_s1()
{
  s1_counter++;
  Serial.print("S1 change:");
  Serial.println(s1_counter);
}
void write_s2()
{
  s2_counter++;
  Serial.print("S2 change:");
  Serial.println(s2_counter);
}
 
  1. You should never print within an interrupt routine (or do anything that takes a significant amount of time, unless you absolutely cannot avoid it).

  2. Printing takes time, so in the first program while you are printing, you are probably missing encoder state changes.

Here is a very simple program that doesn’t skip encoder state changes (for the Pololu Orangutan) Quadrature encoder for the O