Reliable use of mechanical encoders requires two components: a hardware tweak and (of course) code. Although there are many sample code for rotary encoder, I feel the following is the simplest code for rotary encoders. This version is interrupt-based.
The interrupt routine simply detects direction of motion:
void decoder()Here we connect terminal A of the rotary encoder to Arduino's digital pin 4 and terminal B to digitalpin 2. The third terminal of the encoder is connected to GND. In this configuration the rotary encoder pulses will be pulling the pins to GND. In this example, we are controlling volume so one direction is volume up and the other direction is volume down.
if (digitalRead(4) == digitalRead(2))
volUp = 1; //if encoder channels are the same, direction is CW
volDown = 1; //if they are not the same, direction is CCW
We attach the interrupt with:
attachInterrupt(0, decoder, CHANGE);and we detects CHANGE of the pulse. We need to detect rising edge and falling edge of the pulse in order to utilize the full resolution of the rotary encoder.
During set up, we want to enable the pull-up resistors for pin 2 and pin 4 with:
pinMode(VOLUPPIN, INPUT); // Pin 2Note: it doesn't matter which channel is connected to which pin to start with. You can always switch the connections if you expect the opposite result.
digitalWrite(VOLUPPIN, HIGH); // Enable pull-up resistor
pinMode(VOLDOWNPIN, INPUT); // Pin 4
digitalWrite(VOLDOWNPIN, HIGH); // Enable pull-up resistor
Then in a loop we detect when the flags are set and do accordingly:
while(volUp==1) // CW motion in the rotary encoder
volUp=0; // Reset the flag
// Do something
while(volDown==1) // CCW motion in rotary encoder
volDown=0; // clear the flag
// Do something else