Skip to content
This repository was archived by the owner on Apr 16, 2021. It is now read-only.

attachInterrupt() fails to detect falling edges when mode is set to CHANGE #68

Closed
f-jiang opened this issue Apr 26, 2020 · 1 comment · Fixed by #69
Closed

attachInterrupt() fails to detect falling edges when mode is set to CHANGE #68

f-jiang opened this issue Apr 26, 2020 · 1 comment · Fixed by #69

Comments

@f-jiang
Copy link
Contributor

f-jiang commented Apr 26, 2020

When I set my interrupt to detect both rising and falling edges using CHANGE, what ends up happening is that falling edges are ignored. I'm using a Nano 33 BLE.

My test setup consists of the code at the bottom, along with an LED connected to ledPin and a pushbutton connected to interruptPin. Note that interruptPin is pulled high.

What I expect to happen, given the CHANGE mode, is that LED should toggle when the button is both pressed (falling edge) and released (rising edge); however, it only toggles during button release.

(At first, I was having problems with my quadrature encoder code, but after some investigation it boiled down to the above issue).

const byte ledPin = 4;
const byte interruptPin = 2;
volatile byte state = LOW;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
}

void loop() {
  digitalWrite(ledPin, state);
}

void blink() {
  state = !state;
}
@f-jiang f-jiang changed the title attachInterrupt() only detects rising edges when mode is set to CHANGE attachInterrupt() fails to detect falling edges when mode is set to CHANGE Apr 26, 2020
@f-jiang
Copy link
Contributor Author

f-jiang commented Apr 26, 2020

I dug through the repo a bit, and it appears that every mode other than FALLING is being treated as rising edge detection (cores/arduino/Interrupts.cpp, line 49):

void attachInterruptParam(PinName interruptNum, voidFuncPtrParam func, PinStatus mode, void* param) {
  detachInterrupt(interruptNum);
  mbed::InterruptIn* irq = new mbed::InterruptIn(interruptNum);
  if (mode == FALLING) {
    irq->fall(mbed::callback(func, param));
  } else {
    irq->rise(mbed::callback(func, param));
  }
#ifdef digitalPinToInterruptObj
  digitalPinToInterruptObj(interruptNum) = irq;
#endif
}

According to this old forum post, you can detect both rising and falling edges on an interrupt. How would I go about implementing and testing this change? Thanks!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant