Pin interrupts on Rpi pico with arduno-pico code

I'm using the Arduino IDE with the arduino-pico core and I'm trying to get pin interrupts working for a rotary encoder application. Here is the code:

#define ROTA       6    // GPIO6    rotary encoder A
#define ROTB       7    // GPIO7    rotary encoder B

// rotary encoder pin change interrupt handler
void readEncoder() {
  encoder_state = (encoder_state << 4) | (digitalRead(ROTB) << 1) | digitalRead(ROTA);

  Serial2.println(encoder_state);

  switch (encoder_state) {
    case 0x23:  encoder_val++; break;
    case 0x32:  encoder_val--; break;
    default: break;
  }
}

// rotary encoder init
void encoder_init() {
  attachInterrupt(ROTA, readEncoder, RISING);
  attachInterrupt(ROTB, readEncoder, RISING);
  encoder_state = (digitalRead(ROTB) << 1) | digitalRead(ROTA);
  interrupts();
}

The print statement never executes when I turn the encoder.

Hi
There is neither setup nor loop in this code... Please show your full sketch.

// ============================================================================
//  encoder ::  rotary ecoder interrupt test
//
//  Arduino IDE settings:
//  board: Raspberry Pi Pico (Arduino-Pico)
//  programmer: none
//
// ============================================================================

#define TXD1       8    // GPIO8   PIN11  UART1 Tx
#define RXD1       9    // GPIO9   PIN12  UART1 Rx
#define ROTA       6    // GPIO6   PIN8   rotary encoder A
#define ROTB       7    // GPIO7   PIN9   rotary encoder B

int8_t  encoder_val = 0;
uint8_t encoder_state;

// rotary encoder pin change interrupt handler
void readEncoder() {
  encoder_state = (encoder_state << 4) | (digitalRead(ROTB) << 1) | digitalRead(ROTA);
  Serial2.println(encoder_state);
  switch (encoder_state) {
    case 0x23:  encoder_val++; break;
    case 0x32:  encoder_val--; break;
    default: break;
  }
}

// rotary encoder init
void encoder_init() {
  // enable pin change interrupts
  attachInterrupt(digitalPinToInterrupt(ROTA), readEncoder, RISING);
  attachInterrupt(digitalPinToInterrupt(ROTB), readEncoder, RISING);
  encoder_state = (digitalRead(ROTB) << 1) | digitalRead(ROTA);
  interrupts();
}

// startup initialization
void setup() {
  pinMode(ROTA, INPUT_PULLUP);
  pinMode(ROTB, INPUT_PULLUP);
  #define BAUD  115200
  Serial2.setRX(RXD1);
  Serial2.setTX(TXD1);
  Serial2.begin(BAUD);
  delay(100);
}

// main program loop
void loop() {
  delay(10);
}

1 Like

???
There is no print statement in the code.

How did you know the encoder was not working?

Serial2.println(encoder_state);

where?

I had such high hopes.

Help others help you providing full and complete info.

You shouldnt use Serial.print() in the irq routine.

Serial2.println() may not work if called from an ISR.
(Iirc, it’s been made to work on AVRs, but Pico/MBed might be different.)
Try toggling an led or something instead…

(Btw: actual Pico, or nano rp2040? Arduino rp2040 mBed core, or Philhower rp2040 core?)

I found the problem: encoder_init() was not being called from setup()
It works fine now :slight_smile:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.