Interrupt on digital pin does not work on Nano RP2040 Connect

I tried to configure an interrupt on digital input 7 (= GPIO19).
Digital input 7 is configured as INPUT_PULLUP, with a push button I connected digital input 7 several times to GND but the interrupt service routine ( onInterrupt() ) was never called. I tried other pins and other modes (e.g. CHANGE, RISING, FALLING ...).

const int interruptPin = 7;       // Input D7 (= GPIO19)

void setup() {
  Serial.begin(9600);      // initialize serial communication
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), onInterrupt, CHANGE);
  Serial.println("started ");
}

void onInterrupt() {
  Serial.println("onInterrupt  ");
}



void loop() {
  // put your main code here, to run repeatedly:

}

I tested on Nano_RP2040_Connect using ArduinoCore-mbed core and attachInterrupt() is working OK as expected.

Be sure to use good enough PULL_UP resistor (4.7K-10K) from the pin to +3.3V

Use this test program with debounce

/*
 * Pin_Interrupt_Test.ino
 * Written by Khoi Hoang (https://github.com/khoih-prog/)
 */

#if !( defined(ARDUINO_NANO_RP2040_CONNECT) && defined(ARDUINO_ARCH_MBED) )
  #error This code is intended to run on ARDUINO_NANO_RP2040_CONNECT uaing the mbed_nano platform! Please check your Tools->Board setting.
#endif

#include <Arduino.h>
#include "pinDefinitions.h"

const int interruptPin = 7;    //7;       // Input D7 (= GPIO19)

volatile bool buttonPressed = false;

void onInterruptRising();

void onInterruptFalling()
{
  if (!buttonPressed && digitalRead(interruptPin) == 0)
  {
    buttonPressed = true;
  }
}

void onInterruptRising()
{
  if (buttonPressed && digitalRead(interruptPin) == 1)
  {
    buttonPressed = false;
  }
}

void heartBeatPrint()
{
  static int num = 1;

  Serial.print(F("H"));        // H means Heartbeat

  if (num == 80)
  {
    Serial.println();
    num = 1;
  }
  else if (num++ % 10 == 0)
  {
    Serial.print(F(" "));
  }
}

void check_status()
{
  static uint32_t checkstatus_timeout  = 0;
  static uint32_t checkbutton_timeout  = 0;

  static uint32_t current_millis;
  
  static bool pressedAck  = false;
  static bool releasedAck = false;
  
#define HEARTBEAT_INTERVAL      5000L

// Debouncing time
#define DEBOUNCE_INTERVAL       100L

  current_millis = millis();

  // Debounce
  if ((current_millis > checkbutton_timeout) || (checkbutton_timeout == 0))
  {  
    if (buttonPressed)
    {      
      digitalWrite(LED_BUILTIN, 1);

      if (!pressedAck)
      {
        Serial.println("\nPin_Interrupt Pressed");
        pressedAck  = true;
        releasedAck = false;
      }

      attachInterrupt(interruptPin, onInterruptRising, RISING);
    }
    else
    {
      digitalWrite(LED_BUILTIN, 0);

      if (!releasedAck)
      {
        Serial.println("\nPin_Interrupt Released");
        releasedAck = true;
        pressedAck  = false;
      }
      
      attachInterrupt(interruptPin, onInterruptFalling, FALLING);
    }
    
    checkbutton_timeout = current_millis + DEBOUNCE_INTERVAL;
  }

  // Print hearbeat every HEARTBEAT_INTERVAL (10) seconds.
  if ((current_millis > checkstatus_timeout) || (checkstatus_timeout == 0))
  {
    heartBeatPrint();
    checkstatus_timeout = current_millis + HEARTBEAT_INTERVAL;
  }
}

void setup()
{
  pinMode(LED_BUILTIN, OUTPUT);

  // Don't need pinMode(). Must use PULL_UP resistor, from 4.7K to 10K from interruptPin to +3.3V 
  //pinMode(interruptPin, INPUT_PULLUP);

  Serial.begin(115200);      // initialize serial communication
  while (!Serial);

  delay(2000);

  Serial.println("\nStart Pin_Interrupt_Test");

  Serial.print("Started interrupt for digitalPinToInterrupt(pin) = "); Serial.println(digitalPinToInterrupt(interruptPin));
  Serial.print("Started interrupt for digitalPinToPinName(pin) = GPIO"); Serial.println(digitalPinToPinName(interruptPin));
  Serial.print("Started interrupt for PinNameToIndex(pin) = D"); Serial.println(PinNameToIndex(digitalPinToPinName(interruptPin)));

  // CHANGE, RISING, FALLING
  attachInterrupt(interruptPin, onInterruptFalling, FALLING);
}

void loop()
{
  check_status();
}

and the debug terminal

Start Pin_Interrupt_Test
Started interrupt for digitalPinToInterrupt(pin) = 7
Started interrupt for digitalPinToPinName(pin) = GPIO19
Started interrupt for PinNameToIndex(pin) = D7

Pin_Interrupt Released
H
Pin_Interrupt Pressed
H
Pin_Interrupt Released

Pin_Interrupt Pressed
HHHHHHHH HHHHHHHHHH HHHHHHHHHH

Thanks a lot khoih-prog for the fast response and the Pin_Interrupt_Test.ino, it works perfectly on my Nano_RP2040_Connect.

Why do I have to use an external pull up resistor and can not use the internal one ???

pinMode(interruptPin, INPUT_PULLUP);

1 Like

Because there is some unknown bug in Nano_RP2040_Connect core that the INPUT_PULLUP doesn't work as expected. Without the resistor, the voltage is fluctuating like crazy and triggers billions of interrupts per seconds, and crashes the board (orange blinking LED of dead)

Thanks a lot.

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