const byte aPin = 2, bPin = 3; const int8_t transitions[16] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0}; byte previous = 0; int quarterSteps = 0; long count = 0; long reportedCount = 0; unsigned long reportedAt = 0; byte readState() { return (digitalRead(aPin) << 1) | digitalRead(bPin); } void setup() { pinMode(aPin, INPUT_PULLUP); pinMode(bPin, INPUT_PULLUP); previous = readState(); Serial.begin(9600); Serial.println("Turn slowly; count is full quadrature cycles, not necessarily detents"); } void loop() { const byte current = readState(); if (current != previous) { if ((current ^ previous) == 3) quarterSteps = 0; // Invalid two-bit jump. else quarterSteps += transitions[(previous << 2) | current]; previous = current; if (quarterSteps >= 4) { ++count; quarterSteps -= 4; } if (quarterSteps <= -4) { --count; quarterSteps += 4; } } const unsigned long now = millis(); if (now - reportedAt >= 100 && count != reportedCount) { reportedAt = now; reportedCount = count; Serial.println(count); } }