How to Use Arduino to Read Encoder Values

D

Daniel Zhang

Last updated on Jul 14, 2026

How you read an encoder value depends on the encoder type. The reading methods for incremental and absolute encoders are described below.

Incremental Encoder

Incremental encoders provide two output signal channels: Channel A and Channel B. These are pulse signals offset by 90 electrical degrees from each other. By detecting the state changes on Channel A and Channel B, you can determine both the direction and the angle of rotation. Below are the basic steps for reading an incremental encoder with an Arduino.

  1. Connect Channel A and Channel B of the encoder to interrupt-capable pins on the Arduino (for example, pins 2 and 3).
  2. Define a global variable in the Arduino code to store the encoder count.
  3. Write an interrupt service routine (ISR) to handle state changes on Channel A and Channel B. In this routine, determine the direction of rotation by comparing the current state of one channel with the previous state of the other, then update the encoder count accordingly.
volatile long encoderCount = 0;
int lastB = 0;

void encoderInterrupt() {
  int A = digitalRead(2);
  int B = digitalRead(3);
  // Simple quadrature decoding: compare current A with previous B
  if (A == lastB) {
    encoderCount++;
  } else {
    encoderCount--;
  }
  lastB = B;
}
  1. In the setup() function, configure the pin modes and attach the interrupts so that the ISR is triggered whenever the state of Channel A or Channel B changes.
void setup() {
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  lastB = digitalRead(3);
  attachInterrupt(digitalPinToInterrupt(2), encoderInterrupt, CHANGE);
  attachInterrupt(digitalPinToInterrupt(3), encoderInterrupt, CHANGE);
}
  1. In the main loop(), read the encoderCount variable to obtain the relative position and direction of rotation of the motor shaft.

Note: The example above uses a simplified quadrature decoding approach. For high-speed or high-resolution encoders, consider using a full quadrature state machine or a dedicated encoder interface library to avoid missed counts caused by signal jitter or contact bounce.

Absolute Encoder

Absolute encoders output a digital signal that represents the absolute position of the motor shaft. The example below applies specifically to parallel-output absolute encoders, where each bit of the position value is presented on a separate data wire.

Note: Most industrial absolute encoders use serial communication interfaces such as SSI, SPI, or RS-485 rather than parallel outputs. Those interfaces require different reading methods and, in some cases, dedicated protocol libraries. Always refer to your encoder's datasheet for the correct interface and wiring details.

  1. Connect each data pin of the encoder to a digital input pin on the Arduino.
  2. In the setup() function, set each data pin to input mode.
void setup() {
  pinMode(dataPin1, INPUT);
  pinMode(dataPin2, INPUT);
  // ... Additional data pins, depending on the number of encoder bits
}
  1. Write a function to read the encoder value. In this function, read the state of each data pin using digitalRead() and combine the results into a single integer value.
int readEncoder() {
  int value = 0;
  value |= digitalRead(dataPin1) << 0;
  value |= digitalRead(dataPin2) << 1;
  // ... Additional data pins, depending on the number of encoder bits
  return value;
}
  1. In the main loop(), call the readEncoder() function to obtain the absolute position of the motor shaft.

Note: These examples cover basic encoder types. Encoders in real-world applications may require more advanced processing, such as implementing signal debouncing or using a dedicated encoder interface IC. Always refer to the encoder's datasheet to ensure proper wiring and signal handling.