Last active
March 30, 2021 16:08
-
-
Save kinverarity1/8ca395b85bb63e1e7471d7db0284c30b to your computer and use it in GitHub Desktop.
Read incremental rotary encoder (optical) using Arduino Uno
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Read optical incremental rotary encoder output. | |
Serial output columns: | |
1. Absolute encoder position (pulses, integer) | |
2. Change in encoder position (pulses, integer) | |
3. Time since Arduino start in (microseconds, integer) | |
4. Change in time (microseconds, integer) | |
5. Speed (pulses per second, float) | |
Working well. | |
volatile directive is used for variables that are modified in the | |
interrupt service routines. | |
*/ | |
// Pin definitions. | |
// - enc_a is ENC Signal A line (Arduino digital pin 2) | |
// - enc_b is ENC Signal B line (Arduino digital pin 3) | |
#define ENC_A 2 | |
#define ENC_B 3 | |
// Main loop refresh period. | |
#define REFRESH_MS 50 | |
// Main serial data connection to computer. | |
#define BAUD_RATE 115200 | |
// Encoder signal line states | |
volatile boolean state_a = 0; | |
volatile boolean state_b = 0; | |
// Encoder position | |
volatile int enc_pos = 0; | |
int enc_pos_prev = 0; | |
int enc_pos_change = 0; | |
// Timing | |
unsigned long micros_current = 0; | |
unsigned long micros_prev = 0; | |
long micros_change = 0; | |
void setup() | |
{ | |
pinMode(ENC_A, INPUT); | |
pinMode(ENC_B, INPUT); | |
state_a = (boolean) digitalRead(ENC_A); | |
state_b = (boolean) digitalRead(ENC_B); | |
attachInterrupt(0, interrupt_enc_a, CHANGE); | |
attachInterrupt(1, interrupt_enc_b, CHANGE); | |
micros_prev = micros(); | |
Serial.begin(BAUD_RATE); | |
} | |
void loop() | |
{ | |
// Calculate elapsed time | |
micros_current = micros(); | |
if (micros_current < micros_prev) { | |
micros_change = micros_current + (4294967295 - micros_prev); | |
} else { | |
micros_change = micros_current - micros_prev; | |
} | |
// Calculate change in encoder position. | |
enc_pos_change = enc_pos - enc_pos_prev; | |
enc_pos_change = abs(enc_pos_change); | |
// Emit data | |
Serial.print(enc_pos); | |
Serial.print("\t"); | |
Serial.print(enc_pos_change); | |
Serial.print("\t"); | |
Serial.print(micros_current); | |
Serial.print("\t"); | |
Serial.print(micros_change); | |
Serial.print("\t"); | |
Serial.print(enc_pos_change / (micros_change / 1e6)); | |
Serial.print("\n"); | |
enc_pos_prev = enc_pos; | |
micros_prev = micros_current; | |
delay(REFRESH_MS); | |
} | |
// Detect pulses from depth encoder. | |
void interrupt_enc_a() | |
{ | |
if (!state_a) { | |
state_b ? enc_pos++: enc_pos--; | |
} | |
state_a = !state_a; | |
} | |
void interrupt_enc_b() | |
{ | |
state_b = !state_b; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment