Click here to Skip to main content
Click here to Skip to main content

Arduino Platform - Interrupts Introduction

By , 23 Feb 2010
 

Introduction

This is my second article relating to the Arduino Microprocessor Platform. The first one was a simple implementation of the SIMON game using the Arduino. The article can be found here.
For an introduction to the Arduino Hardware, see jeffb42's excellent articles, as there is no point in repeating things here.

What Is This Article About?

In this article, I am going to introduce hardware interrupts, and how they can be an important feature of the Arduino Platform.

What is an Interrupt?

Interrupts are a method of signaling to the microprocessor that something has happened. However, you may ask yourself, is that not what happens anyway when you use a digital input, etc.? Well quite simply - No.

When you use the likes of a digital input, you will typically read its value by issuing an instruction, then act on the read value by using some form of logic, i.e. the code is polling for a value. Depending on the complexity of your routines, and the duration of the state change on the input, it is quite possible to not see the change on the input occur at all.

By using an interrupt, the code is literally interrupted, and forced to branch off and do some other execution, i.e. the state change on the input is not 'missed'. So interrupts are like a hardware trigger.

What Benefit Are They?

Interrupts can help solve timing issues which may occur within your code/hardware setup. You may have had timing issues already and just not understood what happened. How many times have you said to yourself, "Why didn't that fire?" or "It worked last time I ran it. What is different?"

Getting Down To Business

I am using the Arduino Duemilanove Board for this example, and will be using the Release 18 of the development IDE. This can be downloaded directly from Arduino.cc.

If you are using a different type of Arduino Board, you will need to check out the specs to see which pins are which, as the different types of board can have different allocations and numbers of interrupts/digital pins/analog pins, etc.

On the Duemilanove, there are 2 hardware interrupts available. These are located on Digital Pins 2 and 3. In this demo, we will use Pin 2, and also use Digital Pin 4 as an output to control an LED. The schematic for this is shown below:

arduino_interrupts

Standard Digital Input and Output - No Interrupts

Set up the Arduino as per the schematic and upload the code below to the microprocessor. Here you read the value of an input, do a conditional comparison, run some lengthy routine and repeat.

This will give unpredictable outputs on the LED due to the lengthy process being at an undetermined point in relation to when the input button is triggered. Sometimes the LED will change state immediately, other times nothing happens, and then sometimes you need to hold the button for a while for the state changed to be recognised. [This is code PART A in the downloaded source file.]

int pbIn = 2;          // Digital input on pin 2
int ledOut = 4;        // The output LED pin
int state = LOW;       // The input state

void setup()
{
  // Set up the digital Pin 2 to an Input and Pin 4 to an Output
  pinMode(pbIn, INPUT);
  pinMode(ledOut, OUTPUT);
}

void loop()
{
  state = digitalRead(pbIn);      //Read the button

  digitalWrite(ledOut, state);    //write the LED state

  //Simulate a long running process or complex task
  for (int i = 0; i < 100; i++)
  {
     // do nothing but waste some time
     delay(10);
  }
}

Making Use of Interrupts

We will use the same schematic diagram and modify the code to make use of hardware interrupts. Now when you upload the code, the LED changes state whenever the button is pressed even though the code is still running the same long delay in the main loop. [This is code PART B in the downloaded source file.]

int pbIn = 0;                  // Interrupt 0 is on DIGITAL PIN 2!
int ledOut = 4;                // The output LED pin
volatile int state = LOW;      // The input state toggle

void setup()
{
  // Set up the digital pin 2 to an Interrupt and Pin 4 to an Output
  pinMode(ledOut, OUTPUT);

  //Attach the interrupt to the input pin and monitor for ANY Change
  attachInterrupt(pbIn, stateChange, CHANGE);
}

void loop()
{
  //Simulate a long running process or complex task
  for (int i = 0; i < 100; i++)
  {
    // do nothing but waste some time
    delay(10);
  }
}

void stateChange()
{
  state = !state;
  digitalWrite(ledOut, state);
}

The volatile keyword is added to the state variable, this causes the compiler to use RAM instead of a storage register. This is done because the storage register can be temporarily inaccurate if they are being modified by areas other than the main thread. In the Arduino, this relates to code being triggered by interrupts.

The attachInterrupt(param1, param2, param3) requires 3 parameters, these are;

  • param1 = Which interrupt to listen for. This is the Interrupt Number not the Digital In number
  • param2 = Which code function to call, this must be a method that takes no parameters and returns no value.
  • param3 = Which condition to watch for.

The Arduino can listen for 4 types of condition changes. These are:

  • LOW = The input is at a LOW state
  • RISING = The input state changes from LOW to HIGH
  • FALLING = The input state changes from HIGH to LOW
  • CHANGE = The input state changed from HIGH to LOW or LOW to HIGH, i.e. has changed its state

ReAssigning Interrupts

Interrupts can be changed at any point by using the attachInterrupt() method. As soon as this is done, any previously assigned interrupt on the associated pin is removed.

Starting / Stopping Interrupts

The Arduino also has the ability to temporarily ignore all the interrupts. You may want to do this if you have some sensitive code that must be executed without interruption. In this case, you would issue a noInterrupts() call. Once your sensitive code block has completed, interrupts can be restarted by calling interrupts().

Removing Interrupts

Interrupts can also be removed by using the detachInterrupt(interrupt_number) method.

So, that is it, a quick basic introduction to hardware Interrupts on the Arduino platform. Now, you just need to see how they fit in with your projects, and how you can make use of them.

Associated Links

  • Arduino Homepage - For all references about Arduino and IDE downloads
  • My Website - There are more How-To's and Arduino information available there

History

  • 20th February, 2010- 1st version of article

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

DaveAuld
Engineer
Scotland Scotland
I have been working in the Oil & Gas Industry for over 20 years now.
 
Core Discipline is Instrumentation and Control Systems.
 
Completed Bsc Honours Degree (B29 in Computing) with the Open University in 2012.
 
Currently, Offshore Installation Manager for the Forties Charlie Platform, which is located ~110Miles NE of Aberdeen, Scotland in the North Sea.
Follow on   Twitter   Google+

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5memberMax Holder17-Apr-13 1:30 
Thanks for the nice article.
SuggestionThanks and Advanced Interrupt Topicsmemberengblaze10-Dec-11 6:57 
Hi Dave,
 
Great intro to attachInterrupt() and the available options on Arduino. My only suggestion might be to make it clearer that the two available interrupts are INT 0 and 1, and which pins they map to? You mention digital pins 2 and 3, but only reference the relationship indirectly in your sample code. I see you address it in a prior comment as well, so maybe that could go in the article itself. Otherwise a very good read.
 
If any of your readers are interested in learning about advanced interrupts and how to use AVR interrupts in their code, we have an extended Arduino interrupt tutorial on our site, EngBlaze.
 
Thanks for the article!

GeneralMy vote of 5memberAWdrius11-Oct-10 6:19 
Interesting. As you mentioned in the article I have spotted that sometimes arduino "ignores" user input.
Thanks for a nice article!
GeneralMessage Automatically Removedmemberaasser1-May-10 8:44 
Message Automatically Removed
GeneralRe: My vote of 1 [modified]memberdaveauld7-May-10 3:41 
Wow, you really are challenged. I leave it upto you to figure out in what sense.
 
Please explain why you think this is as you say 'none sense'....
 
I see from your comment in my other Arduino article, combined with your comment here, that you really have to get out more.
Dave
 
Don't forget to rate messages!
Find Me On: Web|Facebook|Twitter|LinkedIn


modified 26-Jul-12 5:34am.

GeneralRe: My vote of 1mvpPete O'Hanlon7-May-10 3:58 
I pity you. Your sad and lonely existence must be unbearable seeing that you have to spew out this mindless arsewipery of drooling, sputum wipe.

"WPF has many lovers. It's a veritable porn star!" - Josh Smith

As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.

My blog | My articles | MoXAML PowerToys | Onyx



GeneralRe: My vote of 1mentorTrollslayer7-May-10 4:39 
Read the votes.
Join the cool kids - Come fold with us[^]

GeneralMy vote of 1memberWes Aday7-May-10 4:42 
For not knowing how to spell "nonsense".
Why is common sense not common?
Never argue with an idiot. They will drag you down to their level where they are an expert.
Sometimes it takes a lot of work to be lazy
Individuality is fine, as long as we do it together - F. Burns

AnswerinterruptsmemberFair Wind25-Mar-10 4:22 
Hi Dave, the code works perfect for what I am trying to do. Debounce a button using interrupts.
There is a but here,
I need 2 buttons, 1 to increase a value and 1 to decrease a value.
Your code works for my switch on int0 (Dpin2)
Any ideas to add another button using statechange?
Thanks
Larry
GeneralRe: interruptsmemberdaveauld25-Mar-10 7:10 
Hi Larry,
 
Stated in the article, although it doesn't jump out at you, is that the Duemilanove supports 2 input interrupts. The second being on pin 3. You could attach an interrupt here in the same way as has been done for the first.
 
So remember when making reference to the interrupt, use 0 or 1 not the pin number, so for a state change on the second interrupt use
 
attachInterrupt(1,functionNameToCall,CHANGE)
 
If your code is not critical and running short of IO, you could always use an analog input and a resistor bridge. Look at my other arduino article (The Simon Game one) you will see i have 4 pushbuttons being read from a single analog input.
 
cheers,
Dave
 
Don't forget to rate messages!
Find Me On: Web|Facebook|Twitter|LinkedIn
Waving? dave.m.auld[at]googlewave.com


General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130617.1 | Last Updated 24 Feb 2010
Article Copyright 2010 by DaveAuld
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid