How to Use Interrupts with Arduino

Interrupts is a very useful feature of Arduino. They let you respond to external events, while doing something else. It is a section of hardware on the microcontroller which is capable of monitoring the state of an input pin by itself and can literally interrupt the microcontroller in whatever it’s doing. The beauty of this is that the interrupts are all taken care of with hardware flags and some very low-level microcontroller instructions. This means you can be doing other things to not have to worry about constantly checking the button.

There are three types of interrupts-Change, Rising and Falling. When you tell the Arduino that you wish for a pin to have interrupt enabled you tell under what condition you wish to trigger the interrupts on a rising edge or a falling edge. When the conditions are met Arduino will run a specific function that is unique to that interrupt. This function is known as the Interrupt Service Routine.

The key to the interrupts is that the code it executes in your ISR should be as short as possible because as soon as the interrupt is triggered it will jump from whatever your microcontroller was in your program and service the interrupted.

If you are using an LCD display or connecting to a Wi-Fi network or something that requires tight timing and integration those processes will often fail. This is because whilst they might appear running in the background if your microcontroller is locked up executing an ISR it can’t do anything else.

Basic do’s and don’ts when using interrupts with Arduino

1.Make sure the ISR to function the cause of the interrupts as short as possible. Usually you’re only using these ISRs to set the flag or change a state rather than executing an entire section of code.

2.ISR cannot return values or take parameters. The Delay and Millis function native to Arduino will not work inside ISR because they’re based on interrupt functions. They need to only have one interrupts being executed at a time. The Delayed microseconds which is a subcategory of the delay function except it stores and measures in microseconds will work because it’s not interrupt based. Any variable which is changed inside an ISR should be declared with the volatile modifier and only certain pins have interrupts capabilities on the Arduino.

3.On the Arduino, you note only digital pins 2 and 3 have interrupt capabilities and be aware that not all chips support all three kinds of interrupts across all of the pins. Some pins may only allow for a change interrupt which can determine whether the signal is rising or falling but it will be run on either. You will have to run additional code to determine the state of the input to determine whether it was a rising or falling edge. Other pins will have the option for all three so you can set it for a falling edge, a rising edge or a pin change.

Now that we’ve talked about what interrupts are let’s look at how to use them. In the given example we are debouncing a push-button and using some If logic and some variables to keep track of the state using debouncing to ensure that our switches press cleanly.

Here an Int button flag is used. The button flag used is a binary one. Here a modifier is used which is called volatile. This declares that this integer can be changed without the rest of the Arduino body knowing about it. You need to declare as volatile to make sure the Arduino knows this variable could change at any time inside an interrupt service routine.

Example Code for ‘Interrupt Debouncing’

/ pin definitions

int ledPin = 3;

int buttonPin = 2;

// global variables

int toggleState;

int lastButtonState = 1;

long unsigned int lastPress;

volatile int buttonFlag;

int debounceTime = 20;


void setup() {

  // setup pin modes

  pinMode(ledPin, OUTPUT);

  pinMode(buttonPin, INPUT_PULLUP);

  attachInterrupt(digitalPinToInterrupt(2), ISR_button, CHANGE);

}


void loop() {

  if((millis() - lastPress) > debounceTime && buttonFlag)

  {

    lastPress = millis();   //update lastPress                                                     

    if(digitalRead(buttonPin) == 0 && lastButtonState == 1)    //if button is pressed and was released last change

    {

      toggleState =! toggleState;                 //toggle the LED state

      digitalWrite(ledPin, toggleState);

      lastButtonState = 0;    //record the lastButtonState

    }

   
    else if(digitalRead(buttonPin) == 1 && lastButtonState == 0)    //if button is not pressed, and was pressed last change

    {

      lastButtonState = 1;    //record the lastButtonState

    }

    buttonFlag = 0;

  }
}


void ISR_button()

{

  buttonFlag = 1;

}

 

sarah ali

sarah ali

Sarah is a passionate writer and blogger. As an early adopter, she enjoys trying out new social media and Internet tools along with WordPress plugins and Web apps.
sarah ali

Leave a Reply

Your email address will not be published.