100% found this document useful (1 vote)
76 views20 pages

Arduino Interrupts and Volatile Variables

This document discusses interrupts in Arduino. It provides examples of code that uses interrupts and explains some key aspects of using interrupts. Specifically, it covers attaching interrupts, using volatile variables, limitations of using functions like delay() in interrupts, and enabling interrupts within interrupts. The document is intended to teach about interrupts and provide sample code for working with interrupts in Arduino projects.

Uploaded by

pmihai12
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
76 views20 pages

Arduino Interrupts and Volatile Variables

This document discusses interrupts in Arduino. It provides examples of code that uses interrupts and explains some key aspects of using interrupts. Specifically, it covers attaching interrupts, using volatile variables, limitations of using functions like delay() in interrupts, and enabling interrupts within interrupts. The document is intended to teach about interrupts and provide sample code for working with interrupts in Arduino projects.

Uploaded by

pmihai12
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 20

Interrupts in Arduino

Reference: Arduino Cookbook (1st ed.) by Michael Margolis.

CPE 355 - Real Time Embedded Kernels - Spring 12 Nuno Alves ([email protected]), College of Engineering

Sample Code
You have an IR detector
connected to pin 2.

This program monitors pulses

on pin 2 and stores the duration of each pulse in an array.

When the array has been lled

each duration is displayed on the Serial Monitor.

CPE 355 - Real Time Embedded Kernels - Spring 12 Nuno Alves ([email protected]), College of Engineering

Volatile Keyword
Its a variable qualier; it is
used before the datatype of a variable, to modify the way in which the compiler and subsequent program treats the variable.

Compiler will load the variable

from RAM and not from a storage register.

Under certain conditions, such


as through interrupts, the value for a variable stored in registers can be inaccurate.
CPE 355 - Real Time Embedded Kernels - Spring 12 Nuno Alves ([email protected]), College of Engineering

attachInterrupt function
The attachInterrupt(0, analyze,
CHANGE); call enables the program to handle interrupts.

The rst number in the call


species which interrupt to initialize.

On a standard Arduino board

(such as UNO), two interrupts are available: number 0, which uses pin 2, and number 1 on pin 3.

Interrupt 0 and interrupt 1 have


the same priorities (with Wiring).
CPE 355 - Real Time Embedded Kernels - Spring 12 Nuno Alves ([email protected]), College of Engineering

A lot more interrupts


Yes, there are a lot of other We will user the timer
interrupts very soon. interrupts, but they are internal.

Unsurprisingly the RESET


interrupt has the highest priority.

This table is from Russells


book (listed on syllabus).

CPE 355 - Real Time Embedded Kernels - Spring 12 Nuno Alves ([email protected]), College of Engineering

attachInterrupt function
The second parameter species
what function to call (interrupt handler) when the interrupt event happens.

The nal parameter species

what should trigger the interrupt: - CHANGE: whenever the pin level changes (low to high or high to low). - LOW: when the pin is low. - RISING: when the pin goes from low to high. - FALLING: when the pin goes from high to low.
CPE 355 - Real Time Embedded Kernels - Spring 12 Nuno Alves ([email protected]), College of Engineering

Main loop
The main loop just checks the
index variable to see if all the entries have been set by the interrupt handler. the array results only once.

... And it will print the contents of Nothing in loop changes the
value of index. The index is changed inside the analyze function when the interrupt condition occurs.
CPE 355 - Real Time Embedded Kernels - Spring 12 Nuno Alves ([email protected]), College of Engineering

Termination condition

The code stays in the while loop

at the end of the inner block, so you need to reset the board when you want to do another run.

CPE 355 - Real Time Embedded Kernels - Spring 12 Nuno Alves ([email protected]), College of Engineering

micros() function
The micros() function returns
the number of micro-seconds since the Arduino began running the current program.

This number will overow after

This number will overow (go back to zero), after approximately 70 minutes.

On 16 MHz Arduino boards

(e.g. UNO), this function has a resolution of four microseconds (i.e. the value returned is always a multiple of four).
CPE 355 - Real Time Embedded Kernels - Spring 12 Nuno Alves ([email protected]), College of Engineering

analyze() function
The index value is used to store
the time since the last state change into the next slot in the results array.

The time is calculated by

subtracting the last time the state changed from the current time in microseconds.

The current time is then saved


as the last time a change happened.
CPE 355 - Real Time Embedded Kernels - Spring 12 Nuno Alves ([email protected]), College of Engineering

Changing variables
The variables that are changed in
an interrupt function are declared as volatile. the values could change at any time (by an interrupt handler).

This lets the compiler know that

Without using the volatile

keyword, the compiler would think these variables are not being changed by any code getting called and would replace these variables with constant values.
CPE 355 - Real Time Embedded Kernels - Spring 12 Nuno Alves ([email protected]), College of Engineering

Whats the code doing?


Each time an interrupt is
triggered, index is incremented and the current time is saved.

The time difference is calculated


and saved in the array (except for the rst time the interrupt is triggered, when index is 0).

When the maximum number of


entries has occurred, the inner block in loop runs, and it prints out all the values to the serial port.
CPE 355 - Real Time Embedded Kernels - Spring 12 Nuno Alves ([email protected]), College of Engineering

Another sample code


int pin = 13; volatile int state = LOW; void setup() { pinMode(pin, OUTPUT); attachInterrupt(0, blink, CHANGE); } void loop() { digitalWrite(pin, state); } void blink() { state = !state; }

Attach something that will

trigger an interrupt in digital pin #2 (e.g. resistive sensor, button, ...) Make sure its either pulled-up or pull-down, as shown on the right. the interrupt is triggered (through pin #2 changes), the LED will change state.

Attach a LED to digital pin 13. Whenever,

CPE 355 - Real Time Embedded Kernels - Spring 12 Nuno Alves ([email protected]), College of Engineering

Arduino wiring C limitations


int pin = 13; volatile int state = LOW; void setup() { pinMode(pin, OUTPUT); attachInterrupt(0, blink, CHANGE); } void loop() { digitalWrite(pin, state); } void blink() { state = !state; }

Inside the interrupt function, delay() won't


work

Values returned by the millis() and micros()


functions will not increment. function may be lost!

Serial communications while in the You should declare as volatile any variables
that you modify within the attached function.

By default, interrupts are atomic.


CPE 355 - Real Time Embedded Kernels - Spring 12 Nuno Alves ([email protected]), College of Engineering

Atomic sections in Arduino


We can enable/disable interrupts on certain
sections of code with interrupts() and noInterrupts().

Interrupts in Arduino are enabled by default. Some functions will not work while
interrupts are disabled, and incoming communication may be ignored. Interrupts can slightly disrupt the timing of code, however, and may be disabled for particularly critical sections of code.

CPE 355 - Real Time Embedded Kernels - Spring 12 Nuno Alves ([email protected]), College of Engineering

Interrupts default
By default you can not have interrupts inside interrupts. With C-Wiring both interrupt 0 and interrupt 1 are assigned the same
priority.

If you have a way to have interrupts inside interrupts, then when an


interrupt is issued, you immediately leave the current interrupt and execute the new interrupt.

Enabling interrupts inside interrupts is a hack :

Is not recommended as it raises all sorts of issues with preserving the state of the machine before the interrupting interrupt is serviced.

CPE 355 - Real Time Embedded Kernels - Spring 12 Nuno Alves ([email protected]), College of Engineering

Enabling interrupts inside interrupts


volatile int i,j,z; void artificialdelay() { for (i=0; i<900; i++){ for (j=0; j<900; j++){ z=i*10;}} } void setup() { Serial.begin(9600); attachInterrupt(0, interrupt0, CHANGE); attachInterrupt(1, interrupt1, CHANGE); pinMode(13, OUTPUT); pinMode(12, OUTPUT); } void loop() { Serial.println("entering main loop"); artificialdelay(); Serial.println("leaving main loop"); } void interrupt0() { interrupts(); digitalWrite(13,HIGH); artificialdelay(); digitalWrite(13,LOW); noInterrupts(); //not really needed } void interrupt1() { interrupts(); digitalWrite(12,HIGH); artificialdelay(); digitalWrite(12,LOW); noInterrupts(); //not really needed }

If I press pin2 will go into interrupt0(). While it is processing, I can press pin3 and
jump into function interrupt1().

CPE 355 - Real Time Embedded Kernels - Spring 12 Nuno Alves ([email protected]), College of Engineering

Operation scenarios

CPE 355 - Real Time Embedded Kernels - Spring 12 Nuno Alves ([email protected]), College of Engineering

What happens if you trigger interrupt0 when inside interrupt0 ?


volatile int i,j,z; void artificialdelay() { for (i=0; i<900; i++){ for (j=0; j<900; j++){ z=i*10;}} } void setup() { Serial.begin(9600); attachInterrupt(0, interrupt0, CHANGE); attachInterrupt(1, interrupt1, CHANGE); pinMode(13, OUTPUT); pinMode(12, OUTPUT); } void loop() { Serial.println("entering main loop"); artificialdelay(); Serial.println("leaving main loop"); } void interrupt0() { interrupts(); digitalWrite(13,HIGH); artificialdelay(); digitalWrite(13,LOW); noInterrupts(); //not really needed } void interrupt1() { interrupts(); digitalWrite(12,HIGH); artificialdelay(); digitalWrite(12,LOW); noInterrupts(); //not really needed }

Nothing! Each interrupt has a register ag that indicates which interrupt needs attention. If we are inside a particular interrupt, the interrupt ag is already ON.

CPE 355 - Real Time Embedded Kernels - Spring 12 Nuno Alves ([email protected]), College of Engineering

What happens if you trigger interrupt1 when inside interrupt0 ?


volatile int i,j,z; void artificialdelay() { for (i=0; i<900; i++){ for (j=0; j<900; j++){ z=i*10;}} } void setup() { Serial.begin(9600); attachInterrupt(0, interrupt0, CHANGE); attachInterrupt(1, interrupt1, CHANGE); pinMode(13, OUTPUT); pinMode(12, OUTPUT); } void loop() { Serial.println("entering main loop"); artificialdelay(); Serial.println("leaving main loop"); } void interrupt0() { //interrupts(); digitalWrite(13,HIGH); artificialdelay(); digitalWrite(13,LOW); //noInterrupts(); } void interrupt1() { //interrupts(); digitalWrite(12,HIGH); artificialdelay(); digitalWrite(12,LOW); //noInterrupts(); }

function will be executed immediately after we are done interrupt0().


interrupt1()

CPE 355 - Real Time Embedded Kernels - Spring 12 Nuno Alves ([email protected]), College of Engineering

You might also like