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

per1234
4,2782 gold badges24 silver badges43 bronze badges
asked Jul 6, 2017 at 12:07
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. 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()? 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 Commented Jul 6, 2017 at 13:24
  • @jot the Encoder libary does not support buttons AFAIK. 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.

answered Jul 6, 2017 at 13:02
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.
answered Sep 8, 2017 at 11:05

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.