I am working on a code including interrupts. They, however, refuse to work, even in this simple code that could be the most basic example of interrupts.
In this simplified extract I have a momentary push button attached to an Arduino Pro Mini's PIN 2, with the other side grounded. I have this code uploaded:
#include <Encoder.h> // is this library the cause??...
#define PIN_1 4
#define PIN_2 3 //interrupt pin //using these for a rotary encoder, not in this extract
#define PIN_B 2 //interrupt pin // the rotary encoder also works as a push-button
void setup() {
pinMode(PIN_B, INPUT_PULLUP);
Serial.begin(9600);
attachInterrupt(PIN_B, ButtonPressISR, FALLING);
attachInterrupt(PIN_B, ButtonReleaseISR, RISING);
}
void loop() {
Serial.println("Don't interrupt me");
delay(10);
}
void ButtonPressISR() {
Serial.println("Yay, I'm pressed!");
delay(1000);
}
void ButtonReleaseISR() {
Serial.println("Yay, I'm released!");
delay(1000);
}
One would expect that without action, the Arduino floods the serial console with "Don't interrupt me". And that's correct.
When I press the button, however, nothing on Earth happens, neither of the interrupt service routines starts. No matter how hard I try, "Yay, I'm pressed" and "Yay, I'm released" never appears on the console output, and the 1 s delay never happens.
The circuit, shown below, is tested with a multimeter, and is error-free. Pin 2 does get pulled down, and back, upon button press/release.
schematic
simulate this circuit – Schematic created using CircuitLab
2 Answers 2
Neither delay or print should be used in an interrupt routine as they use interrupts themselves, instead set a flag (usually a volatile variable) and test for that in the loop. Also be aware that due to contact bounce the interrupt will trigger multiple times for each button press.
They, however, refuse to work,
more accurately, you are unable to make them work.
- don't delay large amount of time;
- be careful with calling routines that are also called outside of the isr;
- one isr for one pin.
Serial.println()
does not work correctly from within an ISR, asprintln()
uses interrupts itselfCHANGE
. Also,digitalPinToInterrupt()
might help.