Created
November 8, 2019 11:28
-
-
Save dkgrieshammer/99c7e8d02ed97fe98a4cf092e9d9f753 to your computer and use it in GitHub Desktop.
Rotary Encoder Arduino Debounced precise
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* interrupt routine for Rotary Encoders | |
by rafbuff - thanks whereever u are! | |
tested with Noble RE0124PVB 17.7FINB-24 https://www.nobleusa.com/pdf/xre.pdf - available at pollin.de | |
and a few others, seems pretty universal | |
The average rotary encoder has three pins, seen from front: A C B | |
Clockwise rotation A(on)->B(on)->A(off)->B(off) | |
CounterCW rotation B(on)->A(on)->B(off)->A(off) | |
and may be a push switch with another two pins, pulled low at pin 8 in this case | |
[email protected] 20120107 | |
*/ | |
// usually the rotary encoders three pins have the ground pin in the middle | |
enum PinAssignments { | |
encoderPinA = 2, // right | |
encoderPinB = 3, // left | |
clearButton = 8 // another two pins | |
}; | |
volatile unsigned int encoderPos = 0; // a counter for the dial | |
unsigned int lastReportedPos = 1; // change management | |
static boolean rotating = false; // debounce management | |
// interrupt service routine vars | |
boolean A_set = false; | |
boolean B_set = false; | |
void setup() { | |
pinMode(encoderPinA, INPUT); | |
pinMode(encoderPinB, INPUT); | |
pinMode(clearButton, INPUT); | |
// turn on pullup resistors | |
digitalWrite(encoderPinA, HIGH); | |
digitalWrite(encoderPinB, HIGH); | |
digitalWrite(clearButton, HIGH); | |
// encoder pin on interrupt 0 (pin 2) | |
attachInterrupt(0, doEncoderA, CHANGE); | |
// encoder pin on interrupt 1 (pin 3) | |
attachInterrupt(1, doEncoderB, CHANGE); | |
Serial.begin(9600); // output | |
} | |
// main loop, work is done by interrupt service routines, this one only prints stuff | |
void loop() { | |
rotating = true; // reset the debouncer | |
if (lastReportedPos != encoderPos) { | |
Serial.print("Index:"); | |
Serial.println(encoderPos, DEC); | |
lastReportedPos = encoderPos; | |
} | |
if (digitalRead(clearButton) == LOW ) { | |
// encoderPos = 0; | |
} | |
} | |
// Interrupt on A changing state | |
void doEncoderA() { | |
// debounce | |
if ( rotating ) delay (1); // wait a little until the bouncing is done | |
// Test transition, did things really change? | |
if ( digitalRead(encoderPinA) != A_set ) { // debounce once more | |
A_set = !A_set; | |
// adjust counter + if A leads B | |
if ( A_set && !B_set ) | |
encoderPos += 1; | |
rotating = false; // no more debouncing until loop() hits again | |
} | |
} | |
// Interrupt on B changing state, same as A above | |
void doEncoderB() { | |
if ( rotating ) delay (1); | |
if ( digitalRead(encoderPinB) != B_set ) { | |
B_set = !B_set; | |
// adjust counter - 1 if B leads A | |
if ( B_set && !A_set ) | |
encoderPos -= 1; | |
rotating = false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment