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
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.
-
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– L1nuS0108/28/2020 12:35:56Commented Aug 28, 2020 at 12:35
-
1You 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 quicklychrisl– chrisl08/28/2020 13:37:45Commented Aug 28, 2020 at 13:37
Explore related questions
See similar questions with these tags.