#include // import debounce library #define encoder0PinA 2 // encoder pin A on pin 2 #define encoder0PinB 3 // encoder pin B on pin 3 #define button 4 // shaft button on pin 4 #define RED 5 // red LED on proto shield on pin 5 volatile unsigned int encoder0Pos = 0; // scratchpad within ints volatile unsigned int x = 0; // delay loop counter boolean ledValue = LOW; // LED on/off flag // Instantiate a Bounce object with a 5 millisecond debounce time Bounce bouncer = Bounce(button, 5); void setup() { Serial.begin (9600); delay(1000); pinMode(encoder0PinA, INPUT); digitalWrite(encoder0PinA, HIGH); pinMode(encoder0PinB, INPUT); digitalWrite(encoder0PinB, HIGH); pinMode(button, INPUT); digitalWrite(button, HIGH); pinMode(RED,OUTPUT); // encoder pin on interrupt 0 (pin 2) attachInterrupt(0, doEncoderA, CHANGE); // encoder pin on interrupt 1 (pin 3) attachInterrupt(1, doEncoderB, CHANGE); } void loop() { if (bouncer.update()) { if ( bouncer.read() == HIGH) { if ( ledValue == LOW ) { ledValue = HIGH; } else { ledValue = LOW; } digitalWrite(RED,ledValue); } } } void doEncoderA() { // detach interrupts to not interrupt the interrupts detachInterrupt(0); detachInterrupt(1); // a quick and dirty delay to let things settle // as delay() doesnt work within interrupts for(x=0; x<100; x++) { asm("nop\n"); } // look for a low-to-high on channel A if (digitalRead(encoder0PinA) == HIGH) { // check channel B to see which way encoder is turning if (digitalRead(encoder0PinB) == LOW) { encoder0Pos = encoder0Pos + 1; // CW } else { encoder0Pos = encoder0Pos - 1; // CCW } } else // must be a high-to-low edge on channel A { // check channel B to see which way encoder is turning if (digitalRead(encoder0PinB) == HIGH) { encoder0Pos = encoder0Pos + 1; // CW } else { encoder0Pos = encoder0Pos - 1; // CCW } } // use for debugging - remember to comment out Serial.println (encoder0Pos, DEC); // reattach interrupts attachInterrupt(1, doEncoderB, CHANGE); attachInterrupt(0, doEncoderA, CHANGE); } void doEncoderB() { // detach interrupts to not interrupt the interrupts detachInterrupt(1); detachInterrupt(0); // a quick and dirty delay to let things settle // as delay() doesnt work within interrupts for(x=0; x<100; x++) { asm("nop\n"); } // look for a low-to-high on channel B if (digitalRead(encoder0PinB) == HIGH) { // check channel A to see which way encoder is turning if (digitalRead(encoder0PinA) == HIGH) { encoder0Pos = encoder0Pos + 1; // CW } else { encoder0Pos = encoder0Pos - 1; // CCW } } // Look for a high-to-low on channel B else { // check channel B to see which way encoder is turning if (digitalRead(encoder0PinA) == LOW) { encoder0Pos = encoder0Pos + 1; // CW } else { encoder0Pos = encoder0Pos - 1; // CCW } } // use for debugging - remember to comment out Serial.println (encoder0Pos, DEC); // reattach interrupts attachInterrupt(0, doEncoderA, CHANGE); attachInterrupt(1, doEncoderB, CHANGE); }