Chapter 9. Dealing with Interrupts

In all our previous projects, we have been constantly looking for events to occur. We have been polling, but looking for events to occur involves a relatively big effort and a waste of CPU cycles to only notice that nothing happened.

In this chapter, we will learn about interrupts as a totally new way to deal with events, being notified about them instead of looking for them constantly.

Interrupts may be really helpful when developing projects in which fast or unknown events may occur, and thus we will see a very interesting project that will lead us to develop a digital tachograph for a computer-controlled motor.

Are you ready? Here we go!

The concept of an interruption

As you may have intuited, an interrupt is a special mechanism the CPU incorporates to have a direct channel to be noticed when some event occurs.

Most Arduino microcontrollers have two of these:

  • Interrupt 0 on digital pin 2
  • Interrupt 1 on digital pin 3

But some models, such as the Mega2560, come with up to five interrupt pins.

Once an interrupt has been notified, the CPU completely stops what it was doing and goes on to look at it, by running a special dedicated function in our code called Interrupt Service Routine (ISR).

When I say that the CPU completely stops, I mean that even functions such as delay() or millis() won't be updated while the ISR is being executed.

Interrupts can be programmed to respond on different changes of the signal connected to the corresponding pin and thus the Arduino language has four predefined constants to represent each of these four modes:

  • LOW: It will trigger the interrupt whenever the pin gets a LOW value
  • CHANGE: The interrupt will be triggered when the pins change their values from HIGH to LOW or vice versa
  • RISING: It will trigger the interrupt when the signal goes from LOW to HIGH
  • FALLING: It is just the opposite of RISING; the interrupt will be triggered when the signal goes from HIGH to LOW

The ISR

The function that the CPU will call whenever an interrupt occurs is so important to the micro that it has to accomplish a pair of rules:

  • They can't have any parameter
  • They can't return anything
  • The interrupts can be executed only one at a time

Regarding the first two points, they mean that we can neither pass nor receive any data from the ISR directly, but we have other means to achieve this communication with the function.

We will use global variables for it. We can set and read from a global variable inside an ISR, but even so, these variables have to be declared in a special way. We have to declare them as volatile as we will see later on in the code.

The third point, which specifies that only one ISR can be attended at a time, is what makes the function millis() not able to be updated. The millis() function relies on an interrupt to be updated, and this doesn't happen if another interrupt is already being served.

As you may understand, ISR is critical to the correct code execution in a microcontroller. As a rule of thumb, we will try to keep our ISRs as simple as possible and leave all heavyweight processing that occurs outside of it, in the main loop of our code.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset