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.
- Connect Channel A and Channel B of the encoder to interrupt-capable pins on the Arduino (for example, pins 2 and 3).
- Define a global variable in the Arduino code to store the encoder count.
- 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;
}
- 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);
}
- In the main
loop(), read theencoderCountvariable 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.
- Connect each data pin of the encoder to a digital input pin on the Arduino.
- 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
}
- 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;
}
- In the main
loop(), call thereadEncoder()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.