Arduino + Rotary Encoders, rev2
/*
read a rotary encoder with interrupts
Encoder hooked up with common to GROUND,
encoderPinA to pin 2, encoderPinB to pin 3
it doesn't matter which encoder pin you use for A or B
uses Arduino pullups on A & B channel outputs
turning on the pullups saves having to hook up resistors
to the A & B channel outputs
initially based on http://www.arduino.cc/playground/Main/RotaryEncoders
*/
#define encoderPinA 2
#define encoderPinB 3
#define interruptPin 0
const long encoderDebounce = 175;
const long encoderDebounceFast = 10;
const long encoderFastTimeout = 200;
const int encoderStepsTilFast = 2;
long nextEncoderTime = 0;
boolean encoderActive = false;
int encoderLastDirection = 0;
void setup() {
pinMode(encoderPinA, INPUT);
digitalWrite(encoderPinA, HIGH);
pinMode(encoderPinB, INPUT);
digitalWrite(encoderPinB, HIGH);
attachInterrupt(interruptPin, startEncoder, CHANGE); // encoder pin on interrupt 0 - pin 2
Serial.begin (9600);
Serial.println("start");
}
void loop() {
if (encoderActive) {
encoderActive = false;
long now = millis();
if (now > nextEncoderTime) {
//reset fast debounce since there was a pause
if (now > nextEncoderTime + encoderFastTimeout) {
encoderLastDirection = 0;
}
int a = digitalRead(encoderPinA);
int b = digitalRead(encoderPinB);
int encoderDirection = 0;
if (a == b && a == HIGH) {
encoderDirection = 1;
} else if (a != b && b == HIGH) {
encoderDirection = -1;
} else {
encoderDirection = 0;
}
boolean fastMode = abs(encoderLastDirection) > encoderStepsTilFast;
//if we get a random direction change while fast, ignore it
if (fastMode
&& (encoderLastDirection > 0 && encoderDirection < 0
|| encoderLastDirection < 0 && encoderLastDirection > 0)) {
encoderDirection = 0;
}
encoderLastDirection += encoderDirection;
if (encoderDirection != 0) {
nextEncoderTime = now + (fastMode ? encoderDebounceFast : encoderDebounce);
Serial.println(encoderDirection);
}
}
}
}
void startEncoder() {
encoderActive = true;
}
Labels: arduino, rotary encoder
