However if you just want to halt that interrupt for a period of time and reinstate it later it would be sufficient to change the Interrupt Mask register. For example on an Uno this will disable INT0
EIMSK &= 0b00000010;
and you can enable it with
EIMSK |= 0b00000001;
It would be a good idea to clear the interrupt flag immediately before re-enabling an interrupt in case there was some old baggage that will immediately trigger the interrupt. Writing a 1 clears the flag
Robin2 thanks for your help, my plan was to detach interrupt after using it to wake up arduino from deep sleep and later attach interupt before putting arduino back to sleep (low power). While interrupt is detached i would use the same interrupt button for other functions.
Would using just attachInterrupt() and detachInterrupt() be good practice and should i clear interrupt flag while using this functions.
Nevermore555:
Robin2 thanks for your help, my plan was to detach interrupt after using it to wake up arduino from deep sleep and later attach interupt before putting arduino back to sleep (low power). While interrupt is detached i would use the same interrupt button for other functions.
Would using just attachInterrupt() and detachInterrupt() be good practice and should i clear interrupt flag while using this functions.
That sounds like you want the button to do different things based on the current state of the system. You should not detach and attach different functions. That operation is considered "expensive" on the Arduino. Just use one function and a global state variable so it knows what to do.
MorganS:
That sounds like you want the button to do different things based on the current state of the system. You should not detach and attach different functions.
First sentence is true i would like to use same button for different functions, i am working on a clock so first time when button is pressed i want to use interrupt and wake up atmega chip, later i would use the same button for changing time BUT i do not want to use interrupt while atmega is awake so my plan was to detach interrupt when it wake up and before putting it back to sleep attach it again.
About second sentence i would use always the same function when attaching interrupt, would this also be problematic?
Delta_G:
Yes you should still clear the flag. That keeps it from just firing off right when you first attach it.
So before i use detachInterrupt() i should always clear interrupt flag and i can do that with this line of code:
First sentence is true i would like to use same button for different functions, i am working on a clock so first time when button is
So before i use detachInterrupt() i should always clear interrupt flag and i can do that with this line of code:
Not quite.
You should do it immediately before attachInterrupt()
About second sentence i would use always the same function when attaching interrupt, would this also be problematic?
@MorganS was suggestion that you don't use detach and attach and instead leave the ISR attached all the time and have a variable that is changed elsewhere in the code and which is used by the ISR to determine what it does - something like
void myISR() {
if (myValue == 'a') {
// code for one action
}
else if (myValue == 'b') {
// code for another action
}
else {
// do nothing
}
}
This approach would have value if the interrupt needed to change its behaviour frequently and if the time taken for the combined detach and attach was a significant part of the iteration time.
Robin2: @MorganS was suggestion that you don't use detach and attach and instead leave the ISR attached all the time and have a variable that is changed elsewhere in the code and which is used by the ISR to determine what it does.
Thanks for fast reply, so in my case it would look like this:
void myISR() {
if (mode == 'sleeping') {
mode = 'awake';
}
//else if mode == 'awake' do nothing
}
But what is bugging me about this is that every time i would push that button while in 'awake' mode i would always trigger interrupt and myISR() function but if that is more optimized than detaching and attaching IRS i am happy, or maybe it will not trigger interrupt and myISR() since i would not reset the interrupt flag until moment before putting it back to sleep?
UKHeliBob:
Single quotes denote a single char
What type of variable is mode ?
You are right it is a mistake, i edited Robin2s code just to make the point and ignored single quotes. In my original sketch i use integer for mode variable (0 for sleep, 1 for awake), but in this context i don't think that is relevant i am more interested in functionality behind interrupts and how they work.
I'm late to this discussion, but would like to vote for detaching the interrupt in the ISR, and clearing the interrupt flag immediately thereafter - while still in the ISR. A push button can bounce a good bit, and you could have the flag set again immediately as you leave the ISR unless you clear it after you detach the interrupt. Then you don't have to clear the flag again when you attach the interrupt while in active mode, but you do need to be sure the button is not being pressed when you are trying to go to sleep.
I just finished a Nano remote control with a numeric keypad, and it uses pin change interrupts on the column pins to wake up the processor out of deep sleep, but then those pins function normally when decoding the keypress in awake mode. I actually left the interrupt enabled, but used the pin mask register to enable and disable any firing or flag setting on those pins. I think I did it that way to make sure I didn't interfere with the keypad library in case it was using pin change interrupts on other pins. So the overall PCI for the port is enabled in Setup and left that way, but the mask bits are fiddled with in the Loop. Anyway, the ISR just looks like this:
ISR (PCINT2_vect) { // pin change interrupt service routine
PCMSK2 = PCMSK2 & (~PCImask); // clear mask bits = disable further interrupts
PCIFR = PCIFR | PCIenable; // clear any pending interrupt flag bits
}
This works quite well. Even though the button is still being held down, and possibly bouncing, during the ISR, if you disable the interrupt, then clear the flag, there can be no interrupts after that until you enable the interrupt again.