Presentation is loading. Please wait.

Presentation is loading. Please wait.

Arduino Interrupts Paul MacDougal September 8, 2014.

Similar presentations


Presentation on theme: "Arduino Interrupts Paul MacDougal September 8, 2014."— Presentation transcript:

1 Arduino Interrupts Paul MacDougal September 8, 2014

2 What are they? Interrupts are a way for a microcontroller to temporarily stop what it is doing to handle another task. The currently executing program is paused, an ISR (interrupt service routine) is executed, and then your program continues, none the wiser.

3 Kinds of interrupts There are 26 different interrupts on an Arduino Uno –1 Reset –2 External Interrupt Request 0 (pin D2) –3 External Interrupt Request 1 (pin D3) –4 Pin Change Interrupt Request 0 (pins D8 to D13) –5 Pin Change Interrupt Request 1 (pins A0 to A5) –6 Pin Change Interrupt Request 2 (pins D0 to D7) –7 Watchdog Time-out Interrupt –8 Timer/Counter2 Compare Match A –… –18 SPI Serial Transfer Complete –19 USART Rx Complete –… –25 2-wire Serial Interface (I2C) –…

4 When would you use one? Interrupts can detect brief pulses on input pins. Polling may miss the pulse while you are doing other calculations. Interrupts are useful for waking a sleeping processor. Interrupts can be generated at a fixed interval for repetitive processing. And more …

5 Example 1 (no interrupts) const byte LED = 13, SW = 2; void setup() { pinMode(LED, OUTPUT); pinMode(SW, INPUT_PULLUP); } void handleSW() { digitalWrite(LED, digitalRead(SW)); } void loop() { handleSW(); }

6 Example 2 (no interrupts) const byte LED = 13, SW = 2; void handleSW() { digitalWrite(LED, digitalRead(SW)); } void handleOtherStuff() { delay(250); } void setup() { pinMode(LED, OUTPUT); pinMode(SW, INPUT_PULLUP); } void loop() { handleSW(); handleOtherStuff(); }

7 Example 3 (interrupt) const byte LED = 13, SW = 2; void handleSW() { // ISR digitalWrite(LED, digitalRead(SW)); } void handleOtherStuff() { delay(250); } void setup() { pinMode(LED, OUTPUT); pinMode(SW, INPUT_PULLUP); attachInterrupt(INT0, handleSW, CHANGE); } void loop() { // handleSW();  commented out handleOtherStuff(); }

8 ISR Interrupt Service Routines should be kept short. Interrupts are disabled when the ISR is called, so other interrupts are postponed. Do not call millis() or delay() or Serial or … This one is good: void myISR () { count++; }

9 What we have learned The hardware can call a routine for us based on activity on pin 2 (INT0) Our loop() code does not need to know what is happening But, we often want to know what is going on. How do we share that information?

10 Example 4 const byte LED = 13, SW = 2; volatile unsigned char count = 0; void handleSW () { digitalWrite(LED, digitalRead(SW)); count++; } unsigned char lastCount = -1; void handleOtherStuff() { if (count != lastCount) { Serial.print("Count "); Serial.println(count); lastCount = count; } void loop () { handleOtherStuff(); } void setup () { //Start up the serial port Serial.begin(9600); Serial.println(F(“Example4")); pinMode (LED, OUTPUT); pinMode (SW, INPUT_PULLUP); attachInterrupt(INT0, handleSW, CHANGE); }

11

12 A little more on sharing data An interrupt can happen at any time. If you share a multi-byte value (e.g. short int) between an ISR and your code, you have to take additional precautions. volatile short count; if (count == 256) … 1fa: 80 91 10 01 lds r24, 0x0110 ; count lower 1fe: 90 91 11 01 lds r25, 0x0111 ; count upper 202: 80 50 subi r24, 0x00 204: 91 40 sbci r25, 0x01 206: 69 f5 brne.+90

13 Sharing continued // Disable interrupts and copy noInterrupts(); short int myCount = count; interrupts(); if (myCount == 256) … 1fa: f8 94 cli 1fc: 80 91 10 01 lds r24, 0x0110 200: 90 91 11 01 lds r25, 0x0111 204: 78 94 sei 206: 80 50 subi r24, 0x00 208: 91 40 sbci r25, 0x01 20a: 69 f5 brne.+90

14 What we have learned Switches bounce and we may be interrupted more often than expected We must take precautions when sharing data between an ISR and the main code

15 Pin Change Interrupt Pin 2 is INT0 Pin 3 is INT1 But, what about pins 0,1,4,5,6,… Pin Change Interrupts can monitor all pins

16 Example 5 #include const byte LED = 13, SW = 5; volatile unsigned char count = 0; void handleSW () { digitalWrite(LED, digitalRead(SW)); count++; } unsigned char lastCount = -1; void handleOtherStuff() { if (count != lastCount) { Serial.print("Count "); Serial.println(count); lastCount = count; } void loop () { handleOtherStuff(); } void setup () { //Start up the serial port Serial.begin(9600); Serial.println(F(“Example4")); pinMode (LED, OUTPUT); pinMode (SW, INPUT_PULLUP); PCintPort::attachInterrupt(SW, handleSW, CHANGE); }

17 What we have learned We can monitor any pin and have it generate an interrupt Different pins can have different ISRs

18 Example 6 #include void wake() { // ISR sleep_disable(); // first thing after waking from sleep: PCintPort::detachInterrupt(SW); // stop LOW interrupt } void sleepNow() { set_sleep_mode(SLEEP_MODE_PWR_DOWN); noInterrupts(); // stop interrupts sleep_enable(); // enables sleep bit in MCUCR PCintPort::attachInterrupt(SW, wake, LOW); interrupts(); // allow interrupts sleep_cpu(); // here the device is put to sleep }

19 Timer Interrupts There are three timers on an Uno. Two are 8 bit and one is 16 bit. They can generate an interrupt when they overflow or when they match a set value. The frequency at which the timers increment is programmable Arduino uses the timers for PWM and for timing (delay(), millis(), micros())

20 Timers Timer0 – 8 bit – controls PWM on pins 5 and 6. Also controls millis() Timer1 – 16 bit – controls PWM on pins 9 and 10. Timer2 – 8 bit – controls PWM on pins 11 and 3.

21 Example 7 #include const byte LED = 13; void handleOtherStuff() { delay(250); } unsigned int led = LOW; void timerISR() { digitalWrite(LED, led); led ^= (HIGH^LOW); } void setup () { pinMode (LED, OUTPUT); Timer1.initialize(); // breaks analogWrite() for digital pins 9 and 10 Timer1.attachInterrupt(timerISR, 500000); // attaches timerISR() as a timer overflow interrupt -- blinks at 1 Hz } void loop () { handleOtherStuff(); } http://playground.arduino.cc/Code/Timer1 http://code.google.com/p/arduino-timerone

22 What have we learned The fundamental Arduino code uses each of the timers. We can sacrifice some functionality and use them for our own purposes. The timers are very complex (pages 94- 165 in the datasheet). They can be used for lots of cool things.

23 Watchdog Timer The watchdog timer is a separate timer. A selectable timeout is programmable (15ms, 30ms, 60ms, 120ms, 250ms, 500ms, 1s, 2s, 4s, 8s) Times are approx. If the SW does not reset the WDT (kick the dog) within the timeout period, an interrupt or a reset (or both) occur.

24 Example 8 #include const byte LED = 13; uint8_t led = LOW; ISR (WDT_vect) { wdt_setup(WDTO_500MS); digitalWrite(LED, led); led ^= (HIGH^LOW); } void setup () { // configure the pins pinMode (LED, OUTPUT); noInterrupts(); wdt_setup(WDTO_500MS); interrupts(); } void loop () { delay(250); } void wdt_setup(uint8_t duration) { // interrupts should be disabled wdt_reset(); // kick the dog WDTCSR = (1<<WDCE) |(1<<WDE) |(1<<WDIF); WDTCSR = (0<< WDE)|(1<<WDIE) |(duration&0x7) |((duration&0x8)<<2); }

25 Resources Interrupts http://www.gammon.com.au/forum/?id=11 488http://www.gammon.com.au/forum/?id=11 488 Timers http://www.avrfreaks.net/index.php?name= PNphpBB2&file=viewtopic&t=50106http://www.avrfreaks.net/index.php?name= PNphpBB2&file=viewtopic&t=50106

26 Q/A Questions?

27 Notes All examples were compiled using arduino 1.0.5 and run on an Arduino Uno R3

28 #if defined(__AVR_ATtiny45__) #error "__AVR_ATtiny45" #elif defined(__AVR_ATtiny84__) #error "__AVR_ATtiny84" #elif defined(__AVR_ATtiny85__) #error "__AVR_ATtiny85" #elif defined (__AVR_ATtiny2313__) #error "__AVR_ATtiny2313" #elif defined (__AVR_ATtiny2313A__) #error "__AVR_ATtiny2313A" #elif defined (__AVR_ATmega48__) #error "__AVR_ATmega48" #elif defined (__AVR_ATmega48A__) #error "__AVR_ATmega48A" #elif defined (__AVR_ATmega48P__) #error "__AVR_ATmega48P" #elif defined (__AVR_ATmega8__) #error "__AVR_ATmega8" #elif defined (__AVR_ATmega8U2__) #error "__AVR_ATmega8U2" #elif defined (__AVR_ATmega88__) #error "__AVR_ATmega88" #elif defined (__AVR_ATmega88A__) #error "__AVR_ATmega88A" #elif defined (__AVR_ATmega88P__) #error "__AVR_ATmega88P" #elif defined (__AVR_ATmega88PA__) #error "__AVR_ATmega88PA" #elif defined (__AVR_ATmega16__) #error "__AVR_ATmega16" #elif defined (__AVR_ATmega168__) #error "__AVR_ATmega168" #elif defined (__AVR_ATmega168A__) #error "__AVR_ATmega168A" #elif defined (__AVR_ATmega168P__) #error "__AVR_ATmega168P" #elif defined (__AVR_ATmega32__) #error "__AVR_ATmega32" #elif defined (__AVR_ATmega328__) #error "__AVR_ATmega328" #elif defined (__AVR_ATmega328P__) #error "__AVR_ATmega328P" #elif defined (__AVR_ATmega32U2__) #error "__AVR_ATmega32U2" #elif defined (__AVR_ATmega32U4__) #error "__AVR_ATmega32U4" #elif defined (__AVR_ATmega32U6__) #error "__AVR_ATmega32U6" #elif defined (__AVR_ATmega128__) #error "__AVR_ATmega128" #elif defined (__AVR_ATmega1280__) #error "__AVR_ATmega1280" #elif defined (__AVR_ATmega2560__) #error "__AVR_ATmega2560" #else #error "Unknown processor" #endif

29 Arduino main() #include int main(void) { init(); #if defined(USBCON) USBDevice.attach(); #endif setup(); for (;;) { loop(); if (serialEventRun) serialEventRun(); } return 0; }

30 ISR(INT0_vect) { 2e8: 1f 92 push r1 2ea: 0f 92 push r0 2ec: 0f b6 in r0, 0x3f ; 63 2ee: 0f 92 push r0 2f0: 11 24 eor r1, r1 2f2: 2f 93 push r18 2f4: 3f 93 push r19 2f6: 4f 93 push r20 2f8: 5f 93 push r21 2fa: 6f 93 push r22 2fc: 7f 93 push r23 2fe: 8f 93 push r24 300: 9f 93 push r25 302: af 93 push r26 304: bf 93 push r27 306: ef 93 push r30 308: ff 93 push r31 30a: 80 91 13 01 lds r24, 0x0113 30e: 90 91 14 01 lds r25, 0x0114 312: 89 2b or r24, r25 314: 29 f0 breq.+10 ; 0x320 316: e0 91 13 01 lds r30, 0x0113 31a: f0 91 14 01 lds r31, 0x0114 31e: 09 95 icall 320: ff 91 pop r31 322: ef 91 pop r30 324: bf 91 pop r27 326: af 91 pop r26 328: 9f 91 pop r25 32a: 8f 91 pop r24 32c: 7f 91 pop r23 32e: 6f 91 pop r22 330: 5f 91 pop r21 332: 4f 91 pop r20 334: 3f 91 pop r19 336: 2f 91 pop r18 338: 0f 90 pop r0 33a: 0f be out 0x3f, r0 ; 63 33c: 0f 90 pop r0 33e: 1f 90 pop r1 340: 18 95 reti


Download ppt "Arduino Interrupts Paul MacDougal September 8, 2014."

Similar presentations


Ads by Google