Problem with interrupts and 4x encoders on Nano 33 BLE I have a Pololu 4x encoder and am trying to write some code to make it work on my Nano 33 BLE. (Interestingly enough, the issue preventing some pre-existing libraries from working for me is the same issue that I'm about to describe here...)

When I turn the motor shaft clockwise, these are the signals that I get (first bit in each pair is channel A, second bit channel B):

11 -&gt; 10 -&gt; 11 -&gt; 10 -&gt; 11 -&gt; 10

Note how channel A's value never changes, and B's value toggles back and forth.

Likewise, for the counterclockwise direction:

01 -&gt; 11 -&gt; 01 -&gt; 11 -&gt; 01 -&gt; 11

This is of course wrong, as the channels' values should be something like 00 -&gt; 10 -&gt; 11 -&gt; 01 -&gt; 00 as the shaft turns. As a matter of fact, that is exactly what I get when I run the exact same code on a regular Arduino Nano.

Does anyone know what's going on? Here's my code. AFAIK I'm not using interrupts incorrectly or anything, at least for the regular Nano.

#define PIN_A 2
#define PIN_B 3

volatile int val = 0;
volatile bool newVal = true;

void encoder() {
  int a = digitalRead(PIN_A);
  int b = digitalRead(PIN_B);
  val = ((a &lt;&lt; 1) | b);
  newVal = true;
}

void setup() {
  Serial.begin(57600);

  pinMode(PIN_A, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(PIN_A), encoder, CHANGE);

  pinMode(PIN_B, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(PIN_B), encoder, CHANGE);
}

void loop() {
  if (newVal) {
    Serial.print(bool(val &amp; 0b10));
    Serial.print(bool(val &amp; 0b01));
    Serial.println();
    newVal = false;
  }
}


EDIT: After taking a look at the following diagram, it appears that the erroneous encoder patterns match those in which only rising edges are detected. So for some reason, attachInterrupt() is acting as if the CHANGE argument were RISING instead for the Nano BLE.
Best practice would be to use a single interrupt for the encoder.  BLE has a faster processor and your code is not frame-based so that just might affect it also.  This code doesn't do exactly what your code did but it will use val to track position as a number.
It can also be made a bit finer using CHANGE instead of RISING, but for debugging bare bones means less that can go wrong.

#define PIN_A 2
#define PIN_B 3

volatile int val = 0;
int oldVal;
//volatile bool newVal = true;

void encoder() {
  if(digitalRead(PIN_B)) ++val;
  else --val;
}

void setup() {
  Serial.begin(57600);

  pinMode(PIN_A, INPUT_PULLUP);
  pinMode(PIN_B, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(PIN_A), encoder, RISING);
}

void loop() {
  if (val != oldVal) {
    oldVal = val;
    Serial.println(oldVal);
  }
  delay(500);
}