0

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

6
  • 1
    Generally, Serial.println() does not work correctly from within an ISR, as println() uses interrupts itself Commented Jul 6, 2017 at 12:41
  • 1
    I believe adding the 2nd interrupt disables the first. Use a single interrupt with CHANGE. Also, digitalPinToInterrupt() might help.
    – 001
    Commented Jul 6, 2017 at 12:42
  • @JamesWaldby-jwpat7 thanks. But does this explain the lack of the 1 sec delay as well? i.e. does the ISR fails completely as is because of println()?
    – Neinstein
    Commented Jul 6, 2017 at 12:54
  • 1
    Neinstein, you missed what @JohnnyMopp is saying. Number '2' or '3' are not valid interrupts for the Pro Mini. The function digitalPinToInterrupt is preferred. arduino.cc/en/Reference/AttachInterrupt (read the whole page). No one sets two interrupts for a single pin, it does not work, a CHANGE does work. Set a volatile byte in the ISR and use that byte in the loop. If you have an encoder, why not use the Encoder library that you have already downloaded ? pjrc.com/teensy/td_libs_Encoder.html
    – Jot
    Commented Jul 6, 2017 at 13:24
  • @jot the Encoder libary does not support buttons AFAIK.
    – Neinstein
    Commented Jul 6, 2017 at 13:44

2 Answers 2

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.

0

They, however, refuse to work,

more accurately, you are unable to make them work.

  1. don't delay large amount of time;
  2. be careful with calling routines that are also called outside of the isr;
  3. one isr for one pin.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.