.st0{fill:#FFFFFF;}

Arduino

Why should I call detachInterrupt at the start of an interrupt service routine? 

 September 29, 2018

By  Peter

Join Our Mailing List

We publish fresh content each week. Read how-to's on Arduino, ESP32, KiCad, Node-RED, drones and more. Listen to interviews. Learn about new tech with our comprehensive reviews. Get discount offers for our courses and books. Interact with our community.

One email per week, no spam, unsubscribe at any time.

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.


Tags


You may also like

{"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}

In my new course, “Introduction to Electronics: Filters,” I guide you through the essential concepts and hands-on experiments that make filters such a fundamental topic in electronics. In this post, I give you a preview

Read More
Impulse response of first-order filters: A preview from “Introduction to Electronics: Filters”

Over the last few weeks, I’ve had the opportunity to test and explore the CrowPi 3, the latest iteration of Elecrow’s educational laptop-style workstation built around the Raspberry Pi 5. What I’ve been using is a late-stage

Read More
CrowPi 3: A hands-on review of a versatile STEM learning platform