Feedback Control
You can tell a motor to spin, but without an Encoder, you don't know if it actually did. Encoders provide the feedback loop necessary for precision. Incremental encoders are cheap and fast (speed control), while Absolute encoders are critical for robotic arms that need to know their exact pose on startup.
Incremental Optical Encoders
Outputs pulses as it rotates. Counts pulses to measure relative movement. Loses position if power is lost.
Category: Relative Motion
Spec: resolution:CPR (Counts Per Revolution),outputs:A, B (Quadrature), Z (Index)
Spec: resolution:CPR (Counts Per Revolution),outputs:A, B (Quadrature), Z (Index)
Absolute Encoders
Outputs a unique digital code for every angle. Knows exact position immediately on power-up.
Category: Absolute Position
Spec: resolution:Bits (e.g. 12-bit = 4096 steps),interface:SPI, SSI, BiSS
Spec: resolution:Bits (e.g. 12-bit = 4096 steps),interface:SPI, SSI, BiSS
Linear Encoders
A "ruler" that can be read electronically proficiently. Used for precise linear motion stages.
Category: Linear Distance
Spec: accuracy: Microns (µm),length:Variable
Spec: accuracy: Microns (µm),length:Variable
Arduino - Reading Quadrature Encoder (Interrupts)
// Rotary Encoder Inputs
#define CLK 2 // Use interrupt pin
#define DT 3
volatile int counter = 0;
int currentStateCLK;
int lastStateCLK;
String currentDir ="";
void setup() {
pinMode(CLK,INPUT);
pinMode(DT,INPUT);
Serial.begin(9600);
lastStateCLK = digitalRead(CLK);
// Attach interrupt for high speed reading
attachInterrupt(digitalPinToInterrupt(CLK), updateEncoder, CHANGE);
attachInterrupt(digitalPinToInterrupt(DT), updateEncoder, CHANGE);
}
void loop() {
// Main loop is free to do other things!
Serial.print("Position: ");
Serial.println(counter);
delay(100);
}
void updateEncoder(){
currentStateCLK = digitalRead(CLK);
// If the state has changed -> Pulse occurred
if (currentStateCLK != lastStateCLK && currentStateCLK == 1){
// If the DT state looks different than the CLK state then
// the encoder is rotating CCW so decrement
if (digitalRead(DT) != currentStateCLK) {
counter --;
} else {
counter ++;
}
}
lastStateCLK = currentStateCLK;
}