2

Hardware: Arduino Uno Software Version: 1.8.13

My sketch has an interrupt service routine that triggers with the rising edge of digital pin 2. What I want to do now is detaching the interrupt as soon as it has been triggered once and reattaching it as soon as a certain amount of time (>1s) has passed.

However despite of trying I haven't found a possibility to do this.

I have tried detaching it in the ISR itself and reattaching it in the main loop with a delay after manually clearing the interrupt flag. However with this approach the time the interrupt is detached for depends on the point of time the interrupt is triggered, which is undesirable.

Is there a better solution for this? Thank you in advance for every answer

1 Answer 1

0

The standard way to do this is just as you described (but with the non-blocking coding style like in the BlinkWithoutDelay example): Detach in the ISR and setting a flag and a timestamp. Then in the main code check the flag and the time since the timestamp was took. In code that looks somewhat like this (Note, that I left out some arguments of the attaching/detachting functions):

volatile byte flag = 0;
volatile unsigned long timestamp = 0;
#define REACTIVATE_INTERVAL  1000

void ISR_function(){
    detachInterrupt(...);
    flag = 1;
    timestamp = millis();
}

void setup(){
    attachInterrupt(..., ISR_function, ...);
}

void loop(){
    if(flag && millis() - timestamp > REACTIVATE_INTERVAL){
        flag = 0;
        attachInterrupt(..., ISR_function, ...);
    }
    // Rest of your main code from here on
}

For this to work correct, you must of course use a non-blocking coding style in your main code, meaning no delay()s (except for really small ones) and no blocking while loops. If you have those in your main code, you should rewrite it to be non-blocking. Not only for this feature, but for any further extension of your project. A non-blocking coding style is an important principle to embrace, especially microcontrollers.


Without a non-blocking coding style, you would need to use a timer interrupt, to reattach the pin interrupt. While that is totally possible, it does not make much sense to configure extra peripherals of the Arduino just for this.

2
  • That's exactly what I was looking for. I was irritated by the fact that the interrupt causes the timer to stop incrementing but now it makes sense. Thank you :)
    – L1nuS01
    Aug 28, 2020 at 12:35
  • 1
    You mean, that millis() will stop counting while inside the ISR? Thats correct. But it doesn't matter here, since we just get the current value and them leave the ISR very quickly
    – chrisl
    Aug 28, 2020 at 13:37

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.