Arduino programming Interrupts, Lecture notes of Computer Science

this doc will help you to understand what are the interrupts and how to use them

Typology: Lecture notes

2018/2019

Uploaded on 12/03/2019

ghubaida-hassani
ghubaida-hassani 🇺🇬

2 documents

1 / 33

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
11/28/12%
1%
Interrupts
Arduino, AVR, and deep dark programming secrets
What is an Interrupt?
! A transfer of program control that is not directed by
the programmer
! Like a phone call in the middle of a conversation
! Stop what you are doing, deal with the interruption,
then continue where you left off
! Very handy for handling events that need immediate
attention
! Or that need to occur at regular intervals
! Or that need to run automatically without the
programmer keeping track
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21

Partial preview of the text

Download Arduino programming Interrupts and more Lecture notes Computer Science in PDF only on Docsity!

Interrupts

Arduino, AVR, and deep dark programming secrets

What is an Interrupt?

! A transfer of program control that is not directed by

the programmer

! Like a phone call in the middle of a conversation ! Stop what you are doing, deal with the interruption, then continue where you left off

! Very handy for handling events that need immediate

attention

! Or that need to occur at regular intervals ! Or that need to run automatically without the programmer keeping track

Waiting vs. Polling vs. Interrupts

! How to check for an infrequent condition?

! Busy-Wait ! Stand by the curb waiting for the mail ! while (mail-not-here){}; ! Can’t do anything else while you’re waiting…

! Polling ! Like going to the mailbox every 10 min to see if the mail has arrived yet ! Check every time through the “loop” function ! Simple, but time consuming

! Interrupt ! Like getting a phone call when the mail has arrived ! Set up an “interrupt service routine” on the condition you’re waiting for ! You can ignore it and do other things until you get the call

What Happens

! An interrupt is signaled somehow

! A phone rings

! The AVR stops running user code and checks to see what

caused the interrupt

! Stop your conversation and check which phone is ringing

! The AVR runs an Interrupt Service Routing (ISR) related

to that interrupt

! Answer the phone and handle the call

! The AVR restores the system state and picks up the user

code where it left off

! Hang up and resume your previous conversation

Example: USART

! USART handles the serial communication between

Arduino and the host

! Why not just check for a new character in a loop? ! How frequently would you have to check? ! How much processor time would be spend checking?

Example: USART

! Serial port at 9600 baud (9600 bits/sec)

! Each bit is sent at 9.6 kHz (close to 10kHz) ! Each bit takes around 100usec ! Around 10 bits required for each character ! So, one character every 1msec or so ! If the USART is buffered, you have about 1msec to get a character before it’s overwritten by the next one

! So, you have to check faster than once every

millisecond to keep up (around 1000 times a sec)

! If your main loop is not doing anything else, you can do this, but if you’re doing other things, or communicating at faster speeds, it gets ugly fast

Example: USART

! Instead – set up an interrupt handler for the USART

! The USART will cause an interrupt each time it receives a complete character ! The Interrupt Service Routine (ISR) for this USART- receive event will be called ! The ISR will take the character from the USART and put it in a buffer for your program to use ! You never have to check the USART directly, characters just show up in your program’s buffer as they arrive

Types of Interrupts

! On Arduino/AVR, there are three types

! External : A signal outside the chip (connected to a pin) ! Timer : Internal to the chip, like an alarm clock ! Device : One of the AVR devices (USART, SPI, ADC, EEPROM) signals that it needs attention

From the Arduino Reference

  • Two other Arduino functions:
    • interrupts(); // enables interrupts
    • sei(); // enables interrupts (AVR)
    • noInterrupts(); // disables interrupts
    • cli(); // disables interrupts (AVR)

External Interrupt Example

int pin = 13; // the builtin LED pin

volatile int state = LOW; // Hold the state of the LED

// Note that external interrupt 0 looks for changes on

// digital pin 2 of the Arduino board

void setup() {

pinMode(pin, OUTPUT);

attachInterrupt(0, blink, CHANGE); // attach ISR

interrupts(); // enable interrupts (actually not needed)

void loop() {

digitalWrite(pin, state); // Main code writes to LED

void blink() { state = !state; } // ISR changes LED state

Aside: Volatile Qualifier

Another External Interrupt Example

// Interrupt-Driver Bumper Example for a robot // A bumper switch on the front of the robot should be tied to digital pin 2 and ground

#include <avr/interrupt.h> // Some important interrupt-related definitions (needed?)

volatile int bumper; // Indicator to the main code have we hit something

void setup(){ pinMode(2, INPUT); // Make digital 2 an input (for the bumper switch) digitalWrite(2, HIGH); // Enable pull up resistor (bumper switch pulls low)

// attach our interrupt pin (pin 2) to its ISR attachInterrupt(0, bumperISR, FALLING);

interrupts(); // interrupts are enabled by default, but this doesn’t hurt

// start moving bumper = 0; DriveForward(); }

Aside – more external interrupts

! Arduino (AVR) has only 2 external interrupt pins

! Actually, if you want CHANGE mode, there are lots more pins

you can use (pretty much all the Arduino pins)

! But, that requires a little deep dark secret AVR-hacking ! So, unless you need it, don’t worry about it ! If you do need it – Look at the PC Int code on the Arduino site ! Magic code that allows triggering an interrupt from any pin on the Arduino… ! I’ll put a link on the class web site

Types of Interrupts

! On Arduino/AVR, there are three types

! External : A signal outside the chip (connected to a pin) ! Timer : Internal to the chip, like an alarm clock ! Device : One of the AVR devices (USART, SPI, ADC, EEPROM) signals that it needs attention

Motivation

! Arduino 101 – blinky LED

! Problem – Arduino is just wasting time during the delay. It can’t be used for anything else.

int ledPin = 13; // LED connected to digital pin 13

void setup() { pinMode(ledPin, OUTPUT); // initialize the digital pin as an output: }

void loop() { digitalWrite(ledPin, HIGH); // set the LED on delay(1000); // wait for a second digitalWrite(ledPin, LOW); // set the LED off delay(1000); // wait for a second }

Motivation

! Arduino 101 – blinky LED

! Non-delay version – use a timer to see if it’s time to blink ! Can use the Arduino for other things in the meantime ! But, the programmer has to manage this activity

! Don’t use delay – that ties up the processor while it’s

delaying

! Instead, there is a millis(); function that returns the current number of milliseconds since the last system reset ! Based on internal timers! ! Use that to check occasionally if enough time has passed that you should flip the LED again ! You can do other things between checking

Agenda

! First look at timers

! What are they? ! How to read/write timer values? ! How to configure them?

! Then look at how a timer can cause an interrupt

! Like an alarm clock ! When a timer alarm goes off, an ISR may be called

AVR Timers

! Timers are like on-chip alarm clocks

! They count (tick) once for each system clock tick ! 16MHz for Arduino ! Your program can check, and reset the count value ! You can also “prescale” the timer’s clock so that it’s counting more slowly than the 16MHz Arduino clock ! You can also have the timer set an alarm when the count gets to some particular value ! The alarm is an interrupt ! You can define the ISR for that timer alarm

AVR Timers

! Our Arduino’s AVR has three internal timers

! Timer0: an 8-bit timer (counts 0 to 255) ! Used for system timing, millis(); micros();, etc. ! and PWM on pins 5 and 6 ! Timer1: a 16-bit timer (counts 0 to 65,535) ! Used for PWM on pins 9 and 10 ! Timer 2: an 8-bit timer (counts 0 to 255) ! Used for PWM on pins 3 and 11

! Don’t use Timer0 – it will mess things up…

! If you use Timer1 or Timer2, you will lose PWM on

some pins…

Timer Normal Mode

! Start counting on system reset

! Count until you get to your TOP, then start again at 0

! 8bit timer TOP is 255 ! 16bit timer TOP is 65,

! Access a timer’s current value using a special register

! TCNT0, TCNT1, TCNT

! A = TCNT2; // Read the value of timer 2 ! TCNT1 = 0; // Reset the value of timer 1 to 0

Resolution/Timing with Prescaler

Prescale Value Tick Time OVF frequency

OVF Period

1 62.5nsec ~244.14Hz 4.096msec 8 500nsec ~30.52HZ 32.768msec 64 4usec ~3.815Hz 262.144msec 256 16usec ~0.954Hz ~1.05sec 1024 64usec ~0.238Hz ~4.19sec

16-bit counter at 16MHz system clock frequency (Timer1)

OVF = Overflow (time it takes to count from 0 to TOP)

TOP = 16,535 for a 16-bit counter

Example: Flash LED at 1Hz

! Find a counter prescale that lets us count slowly

enough that we can count to 1sec

! Figure out what to count to to get to 1sec

timer_count = ((16,000,000/prescale)/target_freq) – 1

! Set up counter with the right prescaler, then check if the count is up to timer_count. ! Flash the LED and reset the timer to 0

! (16,000,000Hz/1024)/1Hz –1 = 15, (–1 because we count starting at 0!) ! So, if you count 0 to 15,624 at a 1024 prescale, that’s (15,625)x( 64usec)=1,000,000usec = 1sec

Flash LED at 1Hz

int LEDPin = 13; // Built-in LED pin

void setup () { pinMode(LEDPin, OUTPUT); // Make sure it’s an output

// set up timer1 (16-bit timer) in normal up-counting mode // set up timer1 (16-bit timer) for prescale of 1024 }

void loop (){ if (TCNT1 >= 15624) { // reached 1sec on timer digitalWrite(LEDPin, !digitalRead(LEDPin)); // toggle LEDPin TCNT1 = 0; // reset counter to 0 } }

Aside: toggle-tweaking

digitalWrite(LEDPin, !digitalRead(LEDPin));

boolean FlipFlop = 0;

digitalWrite(LEDPin, FlipFlop); FlipFlop = !FlipFlop;

Easy…

Faster…

Detour: Setting bits inside bytes

! TCCR1B is an 8-bit byte ! Want to set bits 2 (CS12) and 0 (CS10) to 1, leave others 0 ! TCCR1B = B00000101; // overwrite whole byte ! TCCR1B = TCCR1B | B00000101; // leave other bits unchanged ! TCCR1B |= B00000101; // shorthand version of above ! CS12 = 2 and CS10 = 0 – these are magically set in an included header file ! bitSet(TCCR1B, CS12); // Arduino functions for setting an individual bit bitSet(TCCR1B, CS10); // There’s also bitClear(reg,bit); for clearing a bit… ! TCCR1B |= ((1<<CS10) | (1<< CS12)); // Register bits all have names ! TCCR1B |= _BV(CS10) | _BV(CS12); // _BV(bit) is another Arduino function ! TCCR1B |= bit(CS10) | bit(CS12); // Yet another Arduino function

Detour: Setting Bits

! | = logical OR

! If there’s a 1 in A or B, there’s a 1 in C

! (1<<CS12)

! CS12 is defined to be 2 (in a secret included file) ! (1<<2) is 1 shifted two places to the left in the byte ! this is 00000100 ! CS10 = 0 ! So ((1<<CS12) | (1<<CS10)) = 00000100 | 00000001 ! This equals 00000101

! _BV(CS12) = bit(CS12) = (1<<CS12) = 00000100

Flash LED at 1Hz

int LEDPin = 13; // Built-in LED pin

void setup () { pinMode(LEDPin, OUTPUT); // Make sure it’s an output

// set up timer1 (16-bit timer) in normal up-counting mode // set up timer1 (16-bit timer) for prescale of 1024 }

void loop (){ if (TCNT1 >= 15624) { // reached 1sec on timer digitalWrite(LEDPin, !digitalRead(LEDPin)); // toggle LEDPin TCNT1 = 0; // reset counter to 0 } }