/* Based on Oleg Mazurov's code for Reading rotary encoder on Arduino, here
https://chome.nerpa.tech/mcu/reading-rotary-encoder-on-arduino/ and here
https://chome.nerpa.tech/mcu/rotary-encoder-interrupt-service-routine-for-avr-micros/
This example does not use the port read method. Tested with Nano and ESP32
Connections
===========
Encoder | ESP32 | Nano
--------------------------
A | D5 | Nano D2
B | D21 | Nano D3
GND | GND | GND
*/
// Define rotary encoder pins
#define ENC_A 23
#define ENC_B 18
volatile int counter = 0;
void setup() {
// Set encoder pins
pinMode(ENC_A, INPUT_PULLUP);
pinMode(ENC_B, INPUT_PULLUP);
// Start the serial monitor to show output
Serial.begin(115200); // Change to 9600 for Nano, 115200 for ESP32
delay(500); // Wait for serial to start
Serial.println("Start");
}
void loop() {
static int lastCounter = 0;
read_encoder();
// If count has changed print the new value to serial
if(counter != lastCounter){
Serial.println(counter);
lastCounter = counter;
}
}
void read_encoder() {
// Encoder routine. Updates counter if they are valid
// and if rotated a full indent
static uint8_t old_AB = 3; // Lookup table index
static int8_t encval = 0; // Encoder value
static const int8_t enc_states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0}; // Lookup table
old_AB <<=2; // Remember previous state
if (digitalRead(ENC_A)) old_AB |= 0x02; // Add current state of pin A
if (digitalRead(ENC_B)) old_AB |= 0x01; // Add current state of pin B
encval += enc_states[( old_AB & 0x0f )];
// Update counter if encoder has rotated a full indent, that is at least 4 steps
if( encval > 3 ) { // Four steps forward
counter++; // Increase counter
encval = 0;
}
else if( encval < -3 ) { // Four steps backwards
counter--; // Decrease counter
encval = 0;
}
}