Hi Folks,
I am not sure if this is the correct place to post my info (apologies if not). Firstly - many thanks for the great site and content. The effort is really appreciated and all the info you present is massively helpful.
Just a thought on the "Using Rotary Encoders With Arduino" content. I've tweaked the code to account for those pesky cheaper rotary encoders that can be a little twitchy/jerky in operation. Also I wanted to limit the decrement/increment count over the range 0 - 255, and so we could possibly account for the limits of 8-bit architecture/integer limitations further down the line.
Anyway - here is the code (verified on the Uno). I hope this is useful.
#define inputCLK 4
#define inputDT 5
#define ledCW 8
#define ledCCW 9
int encoderPos = 0;
int lastEncoded = 0;
String encdir = "";
int direction = 0; // 1 = CW, -1 = CCW, 0 = unknown
int damperCounter = 0;
const int damperThreshold = 2;
const int encoderMin = 0;
const int encoderMax = 255;
void setup() {
pinMode(inputCLK, INPUT);
pinMode(inputDT, INPUT);
pinMode(ledCW, OUTPUT);
pinMode(ledCCW, OUTPUT);
Serial.begin(9600);
int clk = digitalRead(inputCLK);
int dt = digitalRead(inputDT);
lastEncoded = (clk << 1) | dt;
digitalWrite(ledCW, LOW);
digitalWrite(ledCCW, LOW);
}
void loop() {
int clk = digitalRead(inputCLK);
int dt = digitalRead(inputDT);
int encoded = (clk << 1) | dt;
int sum = (lastEncoded << 2) | encoded;
// CW movement
if (sum == 0b0001 || sum == 0b0111 || sum == 0b1110 || sum == 0b1000) {
if (direction == -1) {
damperCounter++;
if (damperCounter >= damperThreshold) {
direction = 1;
incrementEncoder();
damperCounter = 0;
}
} else {
direction = 1;
incrementEncoder();
damperCounter = 0;
}
}
// CCW movement
else if (sum == 0b0010 || sum == 0b0100 || sum == 0b1101 || sum == 0b1011) {
if (direction == 1) {
damperCounter++;
if (damperCounter >= damperThreshold) {
direction = -1;
decrementEncoder();
damperCounter = 0;
}
} else {
direction = -1;
decrementEncoder();
damperCounter = 0;
}
}
lastEncoded = encoded;
delay(1);
}
void incrementEncoder() {
if (encoderPos < encoderMax) {
encoderPos++;
showDirection("CW");
}
}
void decrementEncoder() {
if (encoderPos > encoderMin) {
encoderPos--;
showDirection("CCW");
}
}
void showDirection(String d) {
encdir = d;
if (d == "CW") {
digitalWrite(ledCW, HIGH);
digitalWrite(ledCCW, LOW);
} else {
digitalWrite(ledCW, LOW);
digitalWrite(ledCCW, HIGH);
}
Serial.print("Direction: ");
Serial.print(encdir);
Serial.print(" -- Value: ");
Serial.println(encoderPos);
}
Feel free to use/change/tweak etc.
All the best and have fun 🙂
Dave E.
Thanks for posting this.