Encoder library and rotary encoder

volatile uint8_t enc=4;
volatile uint8_t state=0;

void setup()
 {
  Serial.begin(115200);
  Serial.println("Ready");
  
  pinMode(13, OUTPUT);
  pinMode(2, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(2), ISR_P2, CHANGE);
  pinMode(3, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(3), ISR_P3, CHANGE);
 }

void ISR_P2()
 {
  enc = (enc & 0x06) | digitalRead(2);
  state = !state;
  Serial.println(enc, BIN);
 }

void ISR_P3()
 {
  enc = (enc & 0x05) | (digitalRead(3)<<1);
  Serial.println(enc,BIN);
 }

void loop()
 {
  digitalWrite(13, state);
 }

I did find an error in the program. The ISR for pin 3 was reading pin 2. The change in the program did not effect the output.

Just to clarify on encoder types. There are basically two types of these mechanical encoders. The first has the same number of pulses per revolution as detents per revolution. Between detents, both switches go though a complete cycle (one "pulse"). The switches are always both open at a detent. There are four switch transitions in a pulse, so software which counts transitions will divide by four to recognize one tick.

The other type has half as many pulses per revolution as detents per revolution. Each detent is half a pulse, and takes place after two transitions. At a detent, both switches may be open, or both may be closed. For this type the software would divide by two.

So if the software is written for the second type, but the actual encoder is the first type, the software will recognize two ticks per detent. And if it's the other was around, you would have to move it through two detents to get a single tick.

The bottom line is that the hardware and software have to match.

The encoder's datasheet will say how many pulses and detents per revolution it has. Or you can test an encoder - for the second type, a switch will alternate between closed and open on successive detents, but the first type will always be open.

Note that the second type will come to rest with closed switches half the time, and may therefore be drawing current through the pullup resistors when idle. So to avoid that it may be necessary to turn on the pullup resistors only when reading the switch states. That would not work for interrupt-based encoder servicing, but would work for polling.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.