Using a Rotary Encoder with Arduino

Arduino / rotary encoder wiring example

A rotary encoder is essential in most analog to digital measurements. Everything from volume control to robot movement can be tracked with a good rotatry encoder. Conveniently, everything you need to know is in Wikipedia. This code is a variation on Metsfan’s contribution to the Sparkfun forums. This version avoids unnecessary if statements. SO NERDY.

#define PIN_HIGHBIT (7)
#define PIN_LOWBIT  (5)
#define PIN_PWR     (3)
#define BAUDRATE    (9600)
#define DEBUG         (1)

// globals
int state, prevState = 0, count = 0;
/* old state, new state, change (+ means clockwise)
 * 0 2 +
 * 1 0 +
 * 2 3 +
 * 3 1 +
 * 0 1 -
 * 1 3 -
 * 2 0 -
 * 3 2 -
 */
int encoderStates[4][4] = {
 {  0, -1,  1,  0 }, 
 {  1,  0,  0, -1 }, 
 { -1,  0,  0,  1 }, 
 {  0,  1, -1,  0 }, 
};

void setup() {
  pinMode(PIN_HIGHBIT, INPUT);
  pinMode(PIN_LOWBIT, INPUT);
  pinMode(PIN_PWR, OUTPUT);
  digitalWrite(PIN_PWR, LOW);
  digitalWrite(PIN_LOWBIT, HIGH);
  digitalWrite(PIN_HIGHBIT, HIGH);
  Serial.begin(BAUDRATE); 
}

void loop() {
  state = (digitalRead(PIN_HIGHBIT) << 1) | digitalRead(PIN_LOWBIT);
  count += encoderStates[prevState][state];

#ifdef DEBUG
  if (state != prevState) {
    Serial.print(state, DEC);
    Serial.print(' ');
    Serial.print(prevState, DEC);
    Serial.print(' ');
    Serial.println(count, DEC);
  }
#endif

  prevState = state;
}

3 Responses to “Using a Rotary Encoder with Arduino”

  1. yogi says:

    Cheers!

  2. Dan Thompson says:

    Thanks for this! I have designed a breakout board that may work with this encoder if you’re interested.
    http://www.inmojo.com/store/disassemble-reassemble/item/rotary-encoder-breakout-pcb-only/
    Dan

  3. in my case, it does 2 counts each time i do a step?
    cheers, good stuff here!

Leave a Reply