Useful experience to save others time and aggravation:
-
I couldn't get my cheap Chinese Ebay rotary encoders to work until I added 4.7K pull-up resistors between the A and B outputs and the +5v supply. The internal NANO pull-ups were not enough to pull-up the NPN open collector outputs (I think they are about 30K).
-
Most info I found on quadrature encoders says you need two interrupt inputs for each encoder. NANOs and UNOs only have two interrupt inputs. So what to do if you have two robot wheels? Thanks to Nick Gammon and many others the following code counts two quadrature encoders with only one NANO or UNO:
// Two quadrature encoders on a NANO/UNO (thanks to: Nick Gammon and many others)
//PIN's definition
#define encoderLPinA 2 //interrupt pin
#define encoderLPinB 7 //no need to use an interrupt pin here
#define encoderRPinA 3 //interrupt pin
#define encoderRPinB 8 //no need to use an interrupt pin here
volatile long posL = 0; // long can hold far more pulses than int; signed to know direction since start.
volatile boolean CWL = true; // direction if false it is CCWL
volatile long posR = 0; // long can hold far more pulses than int; signed to know direction since start.
volatile boolean CWR = true; // direction if false it is CCWR
void setup()
{
// SERIAL COM
Serial.begin (115200);
Serial.println("Start app");
// CONFIG IRQ
pinMode(encoderLPinA, INPUT);
attachInterrupt(0, doEncoderL, CHANGE); //600/rev RISING 1200/rev CHANGE will work too but gives you twice the amount of irq's! Do you need that much?
pinMode(encoderRPinA, INPUT);
attachInterrupt(1, doEncoderR, CHANGE); //600/rev RISING 1200/rev CHANGE will work too but gives you twice the amount of irq's! Do you need that much?
}
void loop()
{
// OUTPUT ENCODER INFO
Serial.print("posL: ");
Serial.print(posL);
Serial.print(" posR: ");
Serial.println(posR);
delay(10); // simulate other activities.
}
void doEncoderL()
{
// determine direction
CWL = (digitalRead(encoderLPinB) != digitalRead(encoderLPinA));
// update Left wheel position
if (CWL) posL++;
else posL--;
}
void doEncoderR()
{
// determine direction
CWR = (digitalRead(encoderRPinB) != digitalRead(encoderRPinA));
// update Right wheel position
if (CWR) posR++;
else posR--;
}