Im currently testing an incremental rotary encoder the GHH60. Goal is to tell the absolute position of the shaft. At first everything seems to work fine but after a bit of time my values are getting super weird.
The setup:
-Arduino DUE
-GHH60-10G1024BMP526 (PNP+NPN Output) run with 5V and the the ouputs are brought down to 3.3V by voltage dividers (i know not optimal but currently dont have Schmitttriggers around me)
and here the code:
constexpr uint8_t PIN_A = 53;
constexpr uint8_t PIN_B = 51;
constexpr uint8_t PIN_Z = 49;
#define ZERO_ON_Z_RISING 1
#define PLOT_INTERVAL_MS 5
#define BAUDRATE 115200
#define Z_LOCKOUT_US 1000
volatile long encoderPos = 0;
volatile uint8_t lastA = 0;
volatile int8_t lastDir = 0;
volatile long z_counter = 0;
volatile unsigned long lastZMicros = 0;
unsigned long lastPlot = 0;
void isrA() {
uint8_t a = (uint8_t)digitalRead(PIN_A);
uint8_t b = (uint8_t)digitalRead(PIN_B);
if (a != lastA) {
if (a == b) {
encoderPos--;
lastDir = -1;
} else {
encoderPos++;
lastDir = +1;
}
lastA = a;
}
}
void isrZ() {
unsigned long now = micros();
if ((unsigned long)(now - lastZMicros) < (unsigned long)Z_LOCKOUT_US) {
return;
}
lastZMicros = now;
#if ZERO_ON_Z_RISING
encoderPos = 0;
#endif
if (lastDir >= 0) {
z_counter++;
} else {
z_counter--;
}
}
void setup() {
Serial.begin(BAUDRATE);
while (!Serial) {;}
pinMode(PIN_A, INPUT_PULLUP);
pinMode(PIN_B, INPUT_PULLUP);
pinMode(PIN_Z, INPUT_PULLUP);
lastA = (uint8_t)digitalRead(PIN_A);
attachInterrupt(digitalPinToInterrupt(PIN_A), isrA, CHANGE);
attachInterrupt(digitalPinToInterrupt(PIN_Z), isrZ, RISING);
}
void loop() {
unsigned long now = millis();
if (now - lastPlot >= PLOT_INTERVAL_MS) {
lastPlot = now;
int a = digitalRead(PIN_A);
int b = digitalRead(PIN_B);
int z = digitalRead(PIN_Z);
long pos;
long zc;
noInterrupts();
pos = encoderPos;
zc = z_counter;
interrupts();
Serial.print(a); Serial.print('\t');
Serial.print(b); Serial.print('\t');
Serial.print(z); Serial.print('\t');
Serial.print(pos); Serial.print('\t');
Serial.println(zc);
}
}
Behaviour:
-at first everything works wonderful. Position and the Z_counter changing as expected even if rotated fast
-after a bit of time things get buggy:
-> big jumps in the z_counter (even with the software debounce)
-> position variable changes only between [-1, 0, 1]
-> z_counter behaves like position variable: increments on every AB signal but doesn't reset
-> i also witnessed that sometimes the values jumped back and everything from then on seemed to work again as expected
-> i noticed also that if the encoder kept moving there was a lower tendency for the unexpected behaviour above. If the encoder did not move at all the buggy behavior showed up quite fast.
Any thoughts? After hours of debugging im stuck;(
Thanks in regards


