To understand the explanation below, please consider this example sketch. This sketch is used to debounce a rotary encoder:
(Original is sourced from the Arduino Step by Step Your Complete Guide Github repository)
//Original sketch: https://bigdanzblog.wordpress.com/2014/08/16/using-a-ky040-rotary-encoder-with-arduino/ //Modified by Peter Dalmaris, July 2015 const int PinCLK=2; // Used for generating interrupts using CLK signal const int PinDT=3; // Used for reading DT signal const int PinSW=8; // Used for the push button switch volatile long virtualPosition =0; // must be volatile to work with the isr void isr0 () { detachInterrupt(0); if (!digitalRead(PinDT)) virtualPosition++; else virtualPosition--; attachInterrupt (0,isr0,RISING); } // ISR0 void setup () { pinMode(PinCLK,INPUT); pinMode(PinDT,INPUT); pinMode(PinSW,INPUT); attachInterrupt (0,isr0,RISING); // interrupt 0 is always connected to pin 2 on Arduino UNO Serial.begin (9600); Serial.println("Start"); } void loop () { int lastCount = 0; while (true) { if (!(digitalRead(PinSW))) { // check if pushbutton is pressed virtualPosition = 0; // if YES, then reset counter to ZERO while (!digitalRead(PinSW)) {} // wait til switch is released Serial.println("Reset"); } if (virtualPosition != lastCount) { lastCount = virtualPosition; Serial.print("Count:"); Serial.println(virtualPosition); } } // while }
When an interrupt “fires”, the Arduino goes into the interrupt service routine (isr).
Imagine that the Arduino is already executing code in the isr, when another interrupt fires. What do you think it is that the Arduino will do next?
The Arduino will stop what its doing and jump back at the start of the ISR.
But that’s not what we want. Normally, the ISR function contains code that is critical to our application, and we want that code to complete its execution always, regardless if another interrupt arrives.
To prevent repeated calls to the ISR before a previous ISR has finished, we must turn off interrupts as soon as one is received. That is what we do in line 12 with the “detachInterrupt” function.
But then, just before the Arduino finished the execution of the ISR, we turn interrupts back on so that the next interrupt is captured. Thats what the call to attachInterrupt does in line 23.