/* interrupt routine for Rotary Encoders 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 */ // usually the rotary encoders three pins have the ground pin in the middle enum PinAssignments { encoderPinA = 2, // right (labeled DT on our decoder, yellow wire) encoderPinB = 3, // left (labeled CLK on our decoder, green wire) clearButton = 8 // switch (labeled SW on our decoder, orange wire) // connect the +5v and gnd appropriately }; 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_PULLUP); // new method of enabling pullups pinMode(encoderPinB, INPUT_PULLUP); pinMode(clearButton, INPUT_PULLUP); // turn on pullup resistors (old method) //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; } }