Engineers Garage

  • Electronics Projects and Tutorials
    • Electronic Projects
      • Arduino Projects
      • AVR
      • Raspberry pi
      • ESP8266
      • BeagleBone
      • 8051 Microcontroller
      • ARM
      • PIC Microcontroller
      • STM32
    • Tutorials
      • Audio Electronics
      • Battery Management
      • Brainwave
      • Electric Vehicles
      • EMI/EMC/RFI
      • Hardware Filters
      • IoT tutorials
      • Power Tutorials
      • Python
      • Sensors
      • USB
      • VHDL
    • Circuit Design
    • Project Videos
    • Components
  • Articles
    • Tech Articles
    • Insight
    • Invention Stories
    • How to
    • What Is
  • News
    • Electronic Product News
    • Business News
    • Company/Start-up News
    • DIY Reviews
    • Guest Post
  • Forums
    • EDABoard.com
    • Electro-Tech-Online
    • EG Forum Archive
  • DigiKey Store
    • Cables, Wires
    • Connectors, Interconnect
    • Discrete
    • Electromechanical
    • Embedded Computers
    • Enclosures, Hardware, Office
    • Integrated Circuits (ICs)
    • Isolators
    • LED/Optoelectronics
    • Passive
    • Power, Circuit Protection
    • Programmers
    • RF, Wireless
    • Semiconductors
    • Sensors, Transducers
    • Test Products
    • Tools
  • Learn
    • eBooks/Tech Tips
    • Design Guides
    • Learning Center
    • Tech Toolboxes
    • Webinars & Digital Events
  • Resources
    • Digital Issues
    • EE Training Days
    • LEAP Awards
    • Podcasts
    • Webinars / Digital Events
    • White Papers
    • Engineering Diversity & Inclusion
    • DesignFast
  • Guest Post Guidelines
  • Advertise
  • Subscribe

How to use interrupts with Arduino

By Nikhil Agnihotri March 16, 2022

Microcontrollers are designed to run concise firmware that’s dedicated to a specific application. The firmware is embedded software, which is written into the program memory. The firmware codes are typically short and designed to manage and execute several micro tasks down to the hardware level. 

Since microcontrollers are dedicated to a single application, these devices have no parallel computing and, by default, code is run sequentially. This means that any external (hardware) changes or software conditions are polled in a linear order through the programming loop. 

In Arduino’s ecosystem, this programming loop is written and executed within the loop() function. 

Polling is the default by which a microcontroller functions. Polling is the process where the controller waits for its state or next task from the external device. This can be problematic when the controller needs to respond to a situation within a short time — or immediately. 

This can occur when there is a sudden change in programming conditions or the hardware state. Fortunately, microcontrollers have a function to deal with such challenges, called interrupts.   

What is an interrupt?
An interrupt in relation to microcontrollers is a mechanism that temporarily suspends the main program, passing control to an interim code. 

In terms of Arduino, this means the typical code as defined within the programming loop (i.e. loop() function) is suspended and a response code is executed, which relates to the specific software condition or hardware change. This response is defined within a well-structured block of code, called Interrupt Service Routine (ISR). 

Let’s suppose that a microcontroller in a robotic rover is programmed to navigate through rough terrain, overcoming different obstacles. The rover tracks its state by monitoring data, using ultrasonic and accelerometer sensors. At one point, a dark, pit is detected along the way. 

However, the pit is only perceived when the rover is a foot or so away from it, which is a problem. The data from the sensors are monitored in a regular programming loop, meaning this message about the pit would typically be relayed too late for the controller to respond in time. 

Fortunately, an interrupt saves the day for this rover. The accelerometer sensor, in this case, generates an interrupt whenever there is a sudden change in the orientation of the robotic rover, signaling it to stop. The interrupt code saved the rover from falling into the pit at the last minute. 

Understanding ISR
An interrupt service routine (ISR) is a block of code that’s executed in response to an interrupt. Of course, there are different types of interrupts. 

The key is that the interrupts for a microcontroller must always be well-defined and correspond to a specific software condition or hardware state. 

In Arduino, interrupts are identified by interrupt vectors.    

Interrupts in Arduino
There are several different boards under the Arduino portfolio, each with different microcontrollers. This table summarizes several of those platforms…

Note: This table does not include retired Arduino boards, such as Arduino Esplora, Arduino Industrial 101, Arduino 101, Arduino Ethernet Rev3, LilyPad Arduino, LilyPad Arduino Simple, LilyPad Arduino USB, LilyPad Arduino SimpleSnap, Arduino Gemma, Arduino Yún Mini, Arduino Yún, Arduino Leonardo ETH, Arduino Tian, Arduino M0, Arduino M0 Pro, Arduino Mega ADK Rev3, Arduino Robot, Arduino Pro, Arduino Mini, and Arduino Pro Mini.

Since every microcontroller has a set of built-in peripherals and input/output interfaces, it makes sense that the interrupts are different for each microcontroller platform.

The controller at the center of Arduino Uno and Arduino Nano — ATmega328 — supports these interrupts…

All of the interrupts are generated by ATmega328’s built-in peripherals or I/O interfaces, which are different in other microcontrollers. 

The interrupt priority noted in the above table is important when more than one interrupt is generated at the same time. When this happens, the interrupt of higher priority is executed while the one of lower priority is suppressed. 

“Reset” is the interrupt of highest priority and it has no interrupt vector. This means that on the reset/reboot, no user-defined routine can be run.   

Broadly speaking, interrupts are classified into two categories. 

1. Hardware interrupts: generated by the microcontroller’s input/output pins. An external hardware/component triggers a change in voltage signal for Arduino’s input/output pin. 

In Arduino, there are two types of hardware interrupts: external and pin change interrupts. 

2. Software interrupts: generated by user-defined program instructions. They’re always associated with the microcontroller’s built-in peripherals and communication port. These interrupts are not triggered by an external hardware component but by changes to the built-in peripherals or software configuration. 

The built-in peripherals must be configured to generate interrupts by writing program instructions. Otherwise, the interrupt is generated automatically on completion of a software instruction that’s associated with a communication port/peripheral. 

For example, timer interrupts are software interrupts. Timer interrupts must be configured by user-defined program instructions. The interrupts generated by communication ports are also software interrupts as they’re triggered when the data communication process is completed by the user-defined program instructions.    

Implementing interrupts in Arduino
The ISRs are defined as separate blocks of code other than the main loop() function. The interrupts are already enabled by default. All software interrupts require set programming. 

For instance, timers can be configured to generate interrupts only when they are programmed by the user. The hardware interrupts (meaning the external and pin-change interrupts) must be configured in the setup() function. 

It’s also possible to enable or disable interrupts in the loop() function to avoid interruptions in program execution or re-enable interrupts. 

To disable interrupts, call the noInterrupts() function within the loop() function as follows…

loop(){
…
noInterrupts();
} 

When the interrupts are disabled, a critical, time-sensitive code must follow and needs to run uninterrupted. The interrupts can be re-enabled in the loop() function by calling the interrupts() function.

loop(){
…
noInterrupts();//disabling interrupts
// critical, time-sensitive code ..
interrupts() //re-enabling interrupts
} 

The interrupts can be served by writing a routine, in which a particular interrupt is identified by passing its interrupt vector as a parameter. Typically, this routine is named ISR(). 

For example, to serve the timer interrupt, configure it in the loop() function and the ISR(). However, the timer interrupt must be defined outside the loop().  

loop(){
…
//instructions to configure and activate Timer/Counter0 Overflow interrupt
…
}
ISR(TIMER0_OVF_vect){
//Code serving Timer/Counter0 Overflow interrupt
} 

Both software and hardware interrupts can be served using their interrupt vectors. To configure and activate the software interrupts, Arduino’s associated built-in registers must be modified or programmed by the user. 

The external interrupts are configured by calling the attachInterrupt() function in the setup() function. The external interrupts are disabled in the loop() function, using the detachInterrupt() function. The pin-change interrupts are configured or activated by modifying or programming Arduino’s associated built-in registers.     

External interrupts
There are two types of hardware interrupts: external and pin-change interrupts. The external interrupts are available on Arduino’s selective pins. 

Here’s a list of the usable pins for external interrupts on different Arduino boards. 

The external interrupts must be configured using the attachInterrupt() function in the setup. 

setup() {
…
attachInterrupt(digitalPinToInterrupt(pin), ISR, mode);
}

The attachInterrupt() accepts three parameters. 

1. The first parameter specifies the pin number at which the external interrupt is activated. That pin number must be passed as a parameter to the digitalPinToInterrupt() function.
2. The second parameter is the name of the interrupt service routine serving the external interrupt at a given pin.
3. The third parameter is the mode of interrupt or signal transition at which the interrupt should be generated. 

Here are the possible modes of an external interrupt…

  • LOW: the interrupt is generated when the digital signal at the pin is low. 
  • CHANGE: the interrupt is generated when the pin values change.
  • RISING: the interrupt is generated when the digital signal at the pin moves from low to high.
  • FALLING: the interrupt is generated when the digital signal at the pin moves from high to low.

The Due, Zero, and MKR1000 boards also support a fifth mode.

  • HIGH: the interrupt is generated when the digital signal at the pin is high.

An external interrupt defined for Arduino Uno’s pin 2 is as follows…

volatile int interruptPin = 2;

setup() {
…
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), ISR, mode);
}

loop() {
…
}

ISR(){
//Code to deal with external interrupt at pin 2
…
}

If required, the external interrupts can also be disabled in the loop() function by calling the detachInterrupt() function.

loop() {
…
detachInterrupt(digitalPinToInterrupt(interruptPin))
}

Writing ISRs
There are several important considerations when writing interrupt service routines.

  • Make them short and sweet. ISRs are intended for sudden, emergency-like responses. They’re not meant for executing long blocks of codes. Therefore, ISRs should be short, precise, and relevant. 
  • Steer clear of timing functions. The timing functions — such as, millis(), micros(), delayMicroseconds() or delay() — should never be used in an ISR. This is because they use timer interrupts. It’s not possible to call or use an interrupt in another interrupt. So, there’s no point in using timing functions with ISRs. 
  • Avoid serial communication protocols. Communication interfaces raise their own interrupts, which are of lower priority and cannot override the hardware or timer interrupts. Also, any data exchanged when running an ISR is lost. If it’s important to store date while running an ISR, it can only be done by changing the global variables. In the loop() function, the state of these variables can be used to print or communicate messages. 
  • Remember: ISRs have no parameters. Interrupt service routines cannot accept any parameters except the interrupt vector. Additional arguments can be only passed to an ISR via the global variables. 
  • ISRs return nothing. ISRs have a data type of void. They cannot return any value. If a value must be passed to the main loop from the ISR, it can only be passed by modifying the global variables. (Although it’s possible to read and write digital input/output pins within an ISR.) 
  • Use volatile variables. The variables that are used inside and outside of the ISRs must be global variables and defined as volatile. Volatile variables are not optimized by the compiler and have no risk of removal during the compilation of source code. However, it’s important to avoid defining every variable in an ISR as volatile because they slow down the code. Therefore, only define those variables inside and outside the ISR as volatile.  

Conclusion
Interrupts provide an important function in the microcontroller world. They are the only resort when dealing with critical or challenging situations. 

There are hardware and software interrupts. Hardware interrupts are generated by external components at the controller’s input/output pins. Arduino has two types, external and pin-change interrupts. 

Software interrupts relate to the microcontroller’s built-in peripherals and communication ports. These interrupts must be activated and configured by user-defined program instructions. 

 

You may also like:


  • Arduino compatible coding 01: Arduino MCU family

  • Interrupts with NRF24LE1 (Part 3/14)

  • How to program an OLED display with Arduino

  • Arduino compatible coding 17: Using softwareSerial in Arduino

  • Beginners’ Guide to Electronics: 12 Basic Things you must know

Filed Under: Electronic Projects, Featured
Tagged With: Arduino, hardware, interrupts, interruptserviceroutine, irs, microcontrollers, pinchange, software
 

Next Article

← Previous Article
Next Article →

EE TECH TOOLBOX

“ee
Tech Toolbox: Internet of Things
Explore practical strategies for minimizing attack surfaces, managing memory efficiently, and securing firmware. Download now to ensure your IoT implementations remain secure, efficient, and future-ready.

EE Learning Center

EE Learning Center
“engineers
EXPAND YOUR KNOWLEDGE AND STAY CONNECTED
Get the latest info on technologies, tools and strategies for EE professionals.

HAVE A QUESTION?

Have a technical question about an article or other engineering questions? Check out our engineering forums EDABoard.com and Electro-Tech-Online.com where you can get those questions asked and answered by your peers!


RSS EDABOARD.com Discussions

  • DIY Buck Boost Converter using XL6019
  • Getting Started with Electronics: What Helped You the Most in the Beginning?
  • De-embedding using Y, Z parameter
  • i need an embedded c program that will read a 12 bit memory address from the io pins and output the data to pins from the memory in a 8051 mcontroller
  • Simple Active Bandpass Filter Oscillates

RSS Electro-Tech-Online.com Discussions

  • parallel-to-serial problem
  • STM32 checking self-written delay function
  • Behringer MX 1602 mixer - reading block diagram
  • Reclaiming missing motherboard header
  • 12v battery, 18v magic

Featured -USB Series

  • Controller Chip Selection for Developing USB Enabled Device (Part 6/6)
  • Signal and Encoding of USB System (Part 5/6)
  • USB Requests and Stages of Control Transfer (Part 4/6)
  • USB Descriptors and their Types (Part 3/6)
  • USB Protocol: Types of USB Packets and USB Transfers (Part 2/6)
  • Introduction to USB: Advantages, Disadvantages and Architecture (Part 1/6)

Recent Articles

  • Littelfuse driver achieves less than 1 µA standby current for energy-efficient designs
  • Microchip optimizes power consumption in transceiver-less FPGA design for automotive applications
  • What is an IoT platform and when is one useful?
  • Silanna launches laser driver IC with sub-2 ns FWHM pulse for LiDAR application
  • LEM introduces current sensors with bandwidth up to 2.5 MHz for precision applications

EE ENGINEERING TRAINING DAYS

engineering

Submit a Guest Post

submit a guest post
Engineers Garage
  • Analog IC TIps
  • Connector Tips
  • Battery Power Tips
  • DesignFast
  • EDABoard Forums
  • EE World Online
  • Electro-Tech-Online Forums
  • EV Engineering
  • Microcontroller Tips
  • Power Electronic Tips
  • Sensor Tips
  • Test and Measurement Tips
  • 5G Technology World
  • Subscribe to our newsletter
  • About Us
  • Contact Us
  • Advertise

Copyright © 2025 WTWH Media LLC. All Rights Reserved. The material on this site may not be reproduced, distributed, transmitted, cached or otherwise used, except with the prior written permission of WTWH Media
Privacy Policy

Search Engineers Garage

  • Electronics Projects and Tutorials
    • Electronic Projects
      • Arduino Projects
      • AVR
      • Raspberry pi
      • ESP8266
      • BeagleBone
      • 8051 Microcontroller
      • ARM
      • PIC Microcontroller
      • STM32
    • Tutorials
      • Audio Electronics
      • Battery Management
      • Brainwave
      • Electric Vehicles
      • EMI/EMC/RFI
      • Hardware Filters
      • IoT tutorials
      • Power Tutorials
      • Python
      • Sensors
      • USB
      • VHDL
    • Circuit Design
    • Project Videos
    • Components
  • Articles
    • Tech Articles
    • Insight
    • Invention Stories
    • How to
    • What Is
  • News
    • Electronic Product News
    • Business News
    • Company/Start-up News
    • DIY Reviews
    • Guest Post
  • Forums
    • EDABoard.com
    • Electro-Tech-Online
    • EG Forum Archive
  • DigiKey Store
    • Cables, Wires
    • Connectors, Interconnect
    • Discrete
    • Electromechanical
    • Embedded Computers
    • Enclosures, Hardware, Office
    • Integrated Circuits (ICs)
    • Isolators
    • LED/Optoelectronics
    • Passive
    • Power, Circuit Protection
    • Programmers
    • RF, Wireless
    • Semiconductors
    • Sensors, Transducers
    • Test Products
    • Tools
  • Learn
    • eBooks/Tech Tips
    • Design Guides
    • Learning Center
    • Tech Toolboxes
    • Webinars & Digital Events
  • Resources
    • Digital Issues
    • EE Training Days
    • LEAP Awards
    • Podcasts
    • Webinars / Digital Events
    • White Papers
    • Engineering Diversity & Inclusion
    • DesignFast
  • Guest Post Guidelines
  • Advertise
  • Subscribe