arduino / arduino/ArduinoCore-mbed

attachInterrupt unexpectedly resets the pin mode

Open
#427 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
C
Stars
411
Forks
225
PR merge metrics
No merged PRs in 30d

Description

Platform: Nano 33 BLE Sense
Version: Arduino IDE 1.8.19, Arduino Mbed OS Nano Boards 2.8.0

`attachInterrupt` incorrectly resets the mode of an input pin back to the default pull mode (`INPUT_PULLUP`). This silently overrides an existing `pinMode` declaration.

This occurs because `attachInterrupt` calls `attachInterruptParam`, which constructs an `InterruptIn` object. The `mbed::InterruptIn::InterruptIn(PinName)` constructor calls `gpio_init_in` at the end, which reinitializes the target pin to `PullDefault`.

## Steps to reproduce

Attach an input to pin 2 (e.g. button) which is high when active and high-z (disconnected) when inactive. Run the following sketch:

```c
void setup() {
pinMode(2, INPUT_PULLDOWN);
pinMode(LED_BUILTIN, OUTPUT);
attachInterrupt(digitalPinToInterrupt(2), buttonISR, CHANGE);
}

void buttonISR() {
static int state = 0;
state = !state;
digitalWrite(LED_BUILTIN, state);
}

void loop() {
}
```

Expected behaviour: clicking or releasing the button toggles the builtin LED state
Observed behaviour: clicking the button does nothing (because the input is now `INPUT_PULLUP`, so the active-high input of the button does nothing).

## Possible fix

One possible fix would be to simply reset the pin to the configured pin mode, if set, in `attachInterrupt` after using the `InterruptIn` object. (If unset, `attachInterrupt` already configures the pin with a default configuration).

A workaround is to simply call `pinMode` *after* `attachInterrupt`; however, this goes against the usual way that `attachInterrupt` is used (even the `attachInterrupt` example on the [official documentation](https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/) puts `pinMode` before `attachInterrupt`).

Contributor guide

No contributing guide indexed for this repository

Research direction

Start at attachInterrupt and attachInterruptParam, then inspect how the mbed::InterruptIn constructor initializes the target pin. Run the supplied Nano 33 BLE Sense sketch and verify that the existing INPUT_PULLDOWN configuration remains effective, so button changes toggle the built-in LED without requiring pinMode after attachInterrupt.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
embedded-iot
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.