Sunday, 30 June 2013

Rotary Encoder Library for Arduino

Here is a simple library for the Arduino which polls and decodes a rotary encoder. It is based on a timer interrupt, just like my IR decoder, so it runs in the background, and doesn't affect your main sketch.

If you're using a mechanical encoder, you'll need to use pull-up resistors, and a hardware debouncer for each of the two pins.

The library can be downloaded here:

Here's an example sketch:

#include "RotaryEncoder.h"

const int encoderPin_A = 8;
const int encoderPin_B = 9;

void setup()
  encoder_begin(encoderPin_A, encoderPin_B); // Start the decoder

void loop()
  int dir = encoder_data(); // Check for rotation
  if(dir != 0)              // If it has rotated...
    Serial.println(dir);    // Print the direction

The encoder_begin() function takes in the pins connected to your encoder, and sets them as inputs, then it sets up timer2 to trigger the ISR every 300 us.

The encoder_data() function will return a 1 or a -1 depending on the direction of rotation. If the encoder hasn't rotated at all since the last time the function was called, it will just return a 0.

The decoder is implemented by a state machine in the ISR. It has three states, standby, waiting, and idle.

  • In the standby state, it reads in the value of pin_A into a variable. It then moves on to the waiting state.
  • In the waiting state, it continually polls pin_A, looking for a change. If it sees a change, it then reads in the value of pin_B to determine the direction of rotation. It stores the direction in the data variable, then it moves on to the idle state.
  • Finally, in the idle state, it simply does nothing and waits for your sketch to read in the data, and reset the state machine with the encoder_data() function.

There are only two functions, encoder_begin() and encoder_data() so the library is very easy to use. One thing to note, is that the library configures timer2 in a way which might conflict with the Tone library, and also may cause problems when trying to use pwm on digital pins 9 and 10.

No comments:

Post a Comment