arduino / arduino/ArduinoCore-mbed
attachInterrupt unexpectedly resets the pin mode
- 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