Hello everyone,
I am trying to use a incremental rotary encoder to measure the rotation of a shaft. The application for measuring human movement so the fastest rotation I am going to be measuring is 500 degrees/s. I am using a ES0S8-1024-6-L-5 and reading it using digital interrupts on an arduino Mega. I have a lot of experience in writing code in MATLAB, but not much experience with arduino. I have cobbled together an arduino script that uses the A and B pulses with interrupts to measure angular position based on examples, however I am observing a non-trivial amount of angular drift.
Based on what I have seen on this wonderful message board, it seems like the drift is most likely due to missed counts. Based on my understanding of this process, this is either because either Serial.print or digitalRead.
I found this solution online for the digitalRead issue. I have tried to implement the "digitalReadFast.h" library as suggested, however this has not remedied the issue.
With regards to the Serial.print, I am reading the serial output and displaying it live using a MATLAB GUI. This serial functionality is important for the final use case. Arduinos and rotary encoders seem to be used for much more complicated things than what I am attempting to do so this is really killing me.
My code is below, does anyone have any insight into what this issue is?
Thank you all in advance!
/* wire diagram
* red - 5V
* black - ground
* white - signal digital pin2
* green - signal digital pin3
*/
long pulses;
const int encoderA = 2; // black wire
const int encoderB = 3; // white wire
const int encoderZ = 21; // white wire
#include "digitalWriteFast.h"
const int cortex = 8; // pin for cortex signal for syncing
int trigger = 0;
static const int WRITE_INTERVAL = 20; // 10ms - 100Hz
unsigned long last_millis;
void setup(){
Serial.begin(115200);
pinMode(encoderA, INPUT);
pinMode(encoderB, INPUT);
pinMode(cortex, INPUT);
last_millis = 0;
attachInterrupt(0, A_CHANGE, CHANGE);
attachInterrupt(1, B_CHANGE, CHANGE);
}//setup
void loop(){
unsigned long this_millis = millis();
if (this_millis - last_millis > WRITE_INTERVAL) {
last_millis = this_millis;
trigger=digitalReadFast(cortex);
Serial.print(last_millis);
Serial.print(';');
Serial.print(trigger);
Serial.print(';');
Serial.println(pulses*-0.0876d);
}
}
void A_CHANGE(){
if( digitalReadFast(encoderB) == 0 ) {
if ( digitalReadFast(encoderA) == 0 ) {
// A fell, B is low
pulses--; // moving reverse
} else {
// A rose, B is low
pulses++; // moving forward
}
} else {
if ( digitalReadFast(encoderA) == 0 ) {
// A fell, B is high
pulses++; // moving forward
} else {
// A rose, B is high
pulses--; // moving reverse
}
}
}
void B_CHANGE(){
if ( digitalReadFast(encoderA) == 0 ) {
if ( digitalReadFast(encoderB) == 0 ) {
// B fell, A is low
pulses++; // moving forward
} else {
// B rose, A is low
pulses--; // moving reverse
}
} else {
if ( digitalReadFast(encoderB) == 0 ) {
// B fell, A is high
pulses--; // moving reverse
} else {
// B rose, A is high
pulses++; // moving forward
}
}
}