Two cheap Chinese Quadrature Encoders on a NANO

Useful experience to save others time and aggravation:

  1. 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).

  2. 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--;
}

For better performance (debounce) it's a good idea to add a 0.1 uF capacitor on both A and B connections to ground.

0.1 µF & 4k7 pull-ups will limit you to no more than about 1000 ticks per second, due to the RC delay (RC constant is 470 µs - fall time will still be fast). As OP needs interrupts, they may very well be working with that kind of speeds.

Roberto48:
For better performance (debounce) it's a good idea to add a 0.1 uF capacitor on both A and B connections to ground.

No, don't do that. Quadrature signals need absolutely no debouncing as they are unambigious
even with contact bounce. 4k7 or 2k2 pull-ups will be fine.

If there are optical encoders you don't want to limit the bandwidth anyway - its not clear whether this
thread is talking about encoder switches or high speed shaft encoders.