0
\$\begingroup\$

I have a quadrature encoder both connected to the Interrupt pins on my arduino. I want to read the encoder values in the range of 0-255 with increment in the clockwise direction and decrement in the counter-clockwise direction. With the code below, only the alternative encoder turns are detected. What am I doing wrong?

#define outputA 6
#define outputB 5

int counter = 0;
int aState;
int aLastState;

void setup() {
  pinMode(outputA, INPUT);
  pinMode(outputB, INPUT);

  Serial.begin(9600);
  // Reads the initial state of the outputA
  aLastState = digitalRead(outputA);
}

void loop() {
  aState = digitalRead(outputA);  // Reads the "current" state of the outputA
  // If the previous and the current state of the outputA are different, that means a Pulse has occured
  if (aState != aLastState) {
    // If the outputB state is different to the outputA state, that means the encoder is rotating clockwise
    if (digitalRead(outputB) != aState) {
      counter++;
    } else {
      counter--;
    }
    Serial.print("Position: ");
    Serial.println(counter);
  }
  aLastState = aState;  // Updates the previous state of the outputA with the current state
}

enter image description here

\$\endgroup\$
2
  • \$\begingroup\$ Have you tried reading encoder A & B inputs using "interrupt " ? in my experience they 're far more stable and accurate. \$\endgroup\$
    – Prashant
    Sep 21, 2023 at 13:19
  • \$\begingroup\$ wait for a transition in A ... read A and B ... state of A and B determines direction \$\endgroup\$
    – jsotola
    Sep 21, 2023 at 14:54

1 Answer 1

1
\$\begingroup\$

It is because you are not checking all possible states of the encoder. Specifically, you are only looking at encoder changes when Encoder A changes.

The easiest way I have found to perform manual quadrature decoding is to create a 16 entry table that represents all of the possible combinations of "Old A", "Old B", "New A", "New B". Four of those entries will consist of "Not possible" states (both signals change, i.e. 0 1 1 0 at index 6). Four of those entries will consist of "No change" states (i.e. 0 1 0 1 at index 5). Four states will consist of "Forward motion" states (i.e. 0 0 1 0 at index 2). Four states will consist of "Negative motion" states (i.e. 0 0 0 1 at index 1). The "Not Possible" and "No change" entries in the table should contain 0, the "Forward motion" entries should contain 1 and the "Negative motion" entries should contain -1.

If you keep the "Old A" and "Old B" in a variable, shift it left twice and OR in the "New A" and "New B" values, it will give you an index into the table. Simply add the value in the table to your position. Finally, just clear the upper two bits of the saved encoder state before reading the new encoder states.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.