Download as pdf or txt
Download as pdf or txt
You are on page 1of 5

1

Polling and Interrupts


Polling:
-process of having the microprocessor repeatedly checking a peripheral device to see if it is
ready to send or accept data (eg. periodically looking at the door to see if someone is entering the
room)
Interrupt:
-peripheral devices such as a button can trigger external interrupts on Arduino pins which
activate a separate interrupt request line which results in the microprocessor suspending
execution of its main program and jumping to an interrupt service routine (ISR) for the
peripheral. After the ISR, the microprocessor continues executing the main program from where
it was interrupted.
-internal timer/counters can also be configured to trigger an interrupt
(eg. looking at the door when someone knocks on it to enter the room)
Arduino Interrupts:
https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/
attachInterrupt()
This function is only used for external interrupts on pins. The ISR() function can be used for
internal interrupts (such as from a Timer)
The first parameter to attachInterrupt() is an interrupt number such as #0 or #1. Normally, for
generality of code, you should use digitalPinToInterrupt(pin) to translate the actual digital pin to
the specific interrupt number for the board being used. For example, if you connect to pin 3 on
an Arduino UNO, it corresponds to interrupt#1 and you would use digitalPinToInterrupt(3) as
the first parameter to attachInterrupt().
Arduino UNO has two pins that can be used for external interrupts: Pin 2 (corresponding to
interrupt#0) and Pin 3 (corresponding to interrupt#1)

Notes:
Inside the attached ISR function, delay() will not work and the value returned by millis() will not
increment (since both delay() and millis() relies on interrupts to work). delayMicroseconds()
does not use any counter, so it will work as normal.
Serial data received while in the ISR function may be lost.
You should declare as “volatile” any variables that you modify within the attached ISR function.
2

About Interrupt Service Routines


ISRs are special kinds of functions that have some unique limitations most other functions do not
have. An ISR cannot have any parameters, and they should not return anything.
Generally, an ISR should be as short and fast as possible. If your sketch uses multiple ISRs, only
one can run at a time, other interrupts will be executed after the current one finishes in an order
that depends on the priority they
Typically global variables are used to pass data between an ISR and the main program. To make
sure variables shared between an ISR and the main program are updated correctly, you
need to declare them as volatile. Volatile tells the compiler that the value of the variable in
the main program can be change outside the current code (such as in an ISR).

External Interrupts: interrupts that are triggered based on the value of an Arduino pin that is set
by an external source, such as a button press. To use external interrupts, you need to associate an
internal interrupt (interrupt#0 or interrupt#1) with an Arduino pin via the attachInterrupt()
function:

Syntax
attachInterrupt(digitalPinToInterrupt(pin), ISR, mode) (recommended)

Parameters

interrupt: the number of the interrupt. Allowed data types: int.


pin: the Arduino pin number. Note the use of the function “digitalPinToIntterrupt(pin)” which
converts the Arduino pin number being used (D2 or D3 on Arduino UNO) and translates that
pin number into the corresponding Arduino internal interrupt number (pin 2 is interrupt #0, pin
3 is interrupt #1 on Arduino UNO). Using this conversion function allows your code to be
seamlessly ported to other types of Arduino microcontrollers (such as Arduino MEGA) which
generally have different pin-to-interrupt# mappings.
ISR: the ISR to call when the interrupt occurs; this function must take no parameters and return
nothing. This function is sometimes referred to as an interrupt service routine (ISR).
mode: defines when the interrupt should be triggered. Four constants are predefined as valid
values:

• LOW trigger interrupt whenever the pin is low

• CHANGE trigger interrupt whenever the pin changes value


3

• RISING trigger when the pin goes from low to high

• FALLING for when the pin goes from high to low

Returns

Nothing

Example Code
const byte ledPin = 13; // set LED pin to D13
const byte interruptPin = 2; // interrupt pins can be
// D2 or D3 on Arduino UNO
volatile bool state = LOW; // volatile used since boolean
// variable “state” changes
// in ISR

void setup() {
pinMode(ledPin, OUTPUT); // since we are setting
// the value of the LED pin
// it is configured as an
// OUTPUT
pinMode(interruptPin, INPUT_PULLUP); // since the
// value of the interrupt
// pin is being monitored
// to trigger an interrupt
// it is set as an INPUT
attachInterrupt(digitalPinToInterrupt(interruptPin), blink,
CHANGE); // initiate the interrupt on the
// correct pin to call function “blink”
// when the state of interruptPin
// CHANGES from HIGH to LOW or LOW to
// HIGH
}

void loop() {
digitalWrite(ledPin, state); // turn LED on/off
// depending on the
// state variable
}

void blink() {
state = !state; // toggle the state variable
// from LOW to HIGH or HIGH to LOW
}
4

Debouncing
-when a button is pressed, there are two metal contacts which can generate multiple signals high-
low-high-low as the contacts make and break contact several times instead of producing the
desired clean transition step signal from low to high (or high to low)
-eg. for the case where the button signal is high unless pressed, pushing the button down once
might change the value of the pin monitoring the button press as follows:

-if the pushbutton signal is connected to Pin 2 (corresponding to interrupt#0) on the Arduino
UNO and the attachInterrupt function is set to “FALLING” then to prevent the software from
interpreting the above as 3 separate button presses, can “debounce” an input by checking over a
long enough period (each time the ISR is called) to ensure the button was actually pressed only
once, eg. within the ISR:
// store the number of milliseconds that have elapsed since
// the Arduino was turned on
current_time = millis();

if(current_time - lastButtonDetectedMillis > debounce_interval)


// wait until debouncing time interval has elapsed to give
// enough time for debouncing
// oscillations to decay
{
// update lastButtonDetectedMillis to reflect the
// current time
lastButtonDetectedMillis = current_time;
// do something in ISR such as
// change a boolean state variable, state = !state;
// or increment a counter, count++;
}
5

// ** ensure current_time and lastButtonDetectedMillis variables


// are declared as:
// “volatile unsigned long”
// at the top of the code before the setup() function
// why before the setup() function?
// global variable
// why volatile?
// value of the variable changes in ISR, so need to ensure
// variables shared between an ISR and the main program are
// updated correctly
// why unsigned long?
// to allow the code to run for as long as possible before
// millis() resets
// if millis() resets then
// current time < lastButtonDetectedMillis
// so “if(negative number > debounce interval)” is FALSE
// and it will not be true for a very long time
// so the code cannot reach the eg. state or counter change
// that the ISR is meant to carry out
//
// note: some timing application may require more accuracy
// than milliseconds, so there is also a micros() function
// which, as the name implies, returns the number of
// microseconds that have elapsed since the Arduino was
// turned on.
//

How long should the debounce interval be?


1. for “FALLING”: referring to fig on previous page, if debounce interval is shorter than the
time the button is pressed, then ISR will trigger on button press and on any debouncing
after the button is released
2. if debouncing interval is too long, then button cannot be pressed again until the
debounce_interval has elapsed
-may choose to set ISR to “RISING” in which case, referring to fig on previous page, releasing
the button causes ISR to be called and on any debouncing after the button is released

You might also like