Skip to content
Mike Schwager edited this page Aug 8, 2015 · 3 revisions

Table of Contents

Introduction

The EnableInterrupt library has a mode whereby the ISRs do not call a user-defined subroutine but instead increment a chosen variable. This is called "HiSpeed mode". This limits the number of registers needed to be saved and restored and speeds up the ISR. Tests show that this greatly increases the speed of the ISRs. See HiSpeed for forther technical discussion and speed test results.

Here we see how to use this mode.

Howto

Fast Start

Refer to the examples/HiSpeed/HiSpeed.ino sketch for an example of the library in use in HiSpeed mode. Compare the instructions below to the code in that file.

To use the library:

To attach an interrupt to your Arduino Pin which will increment a variable of type uint8_t (that is, it will count up to 255 interrupts before cycling back to 0) with a name of your choice, and acting on the "mode", which is a change in the pin's state; either RISING or FALLING or CHANGE:

At the top of your sketch, define the NEEDFORSPEED macro:

#define NEEDFORSPEED
Choose the pin you want to use for your signal; in this example I will choose 8. Then I must define a macro that points to the variable I want to watch in my code. For example:
#define INTERRUPT_FLAG_PIN8 myvariable_pin8 // NOTICE: NO semicolon!!!
Note that this variable is declared




If I had chosen another pin, say A0, I would do this:

#define INTERRUPT_FLAG_PINA0 myhappyvariable // Did you notice no semicolon?
...and so on, for any pin that supports interrupts. You can define as many pins and variables as support interrupts on your Arduino:
#define INTERRUPT_FLAG_PIN1 myhappyvariable  // still no semicolon.
#define INTERRUPT_FLAG_PIN2 othervariable    // nope, no semicolon.
#define INTERRUPT_FLAG_PIN9 yetothervariable // Semicolon: no.
The interrupt flag macro name should be pretty intuitive, but see the INTERRUPT_FLAG_PIN bestiary, below, for the official list.

Now include the EnableInterrupt.h file. This MUST follow the NEEDFORSPEED definition and all the INTERRUPT_FLAG_PINxx definitions:

#include <EnableInterrupt.h>

In setup(), you will probably want to set the pin as an input, and you may want to turn on the INPUT_PULLUP resistor. Here "pin" represents an actual number, or A0, or SCK, etc.:

pinMode(pin, INPUT_PULLUP);
(see http://www.arduino.cc/en/Tutorial/DigitalPins). Now include
enableInterruptFast(pin, mode)
Finally, in loop(), monitor your chosen variable and act upon it as you wish:
if (myvariable) {
    EI_printPSTR("There were interrupts on the pin that incremented myvariable: ");
    Serial.println(myvariable, DEC);
    myvariable=0;
}

That's it. For an example of this, see the aforementioned HiSpeed.ino sketch. You can play with it- choose a supported pin on your Arduino, and connect a pushbutton switch to it. Put one terminal of the switch on Ground, the other on the pin, and observe the interrupts in action. Remember that switches are bouncy so you will usually see a number of interrupts for each switch press/release.

INTERRUPT_FLAG_PIN bestiary

Pins that you can use follow. Remember that for your chosen pin you should refer to it consistently throughout your code. This means, for example, to use A0 instead of pin 14 on the Arduino Uno.

ATmega328

  • ATmega328- All, except pins 0 and 1 are not recommended and not tested.
These are External interrupts:
INTERRUPT_FLAG_PIN2
INTERRUPT_FLAG_PIN3
</pre
these>are Pin Change interrupts:
<pre>
INTERRUPT_FLAG_PIN0
INTERRUPT_FLAG_PIN1
INTERRUPT_FLAG_PIN4
INTERRUPT_FLAG_PIN5
INTERRUPT_FLAG_PIN6
INTERRUPT_FLAG_PIN7
INTERRUPT_FLAG_PIN8
INTERRUPT_FLAG_PIN9
INTERRUPT_FLAG_PIN10
INTERRUPT_FLAG_PIN11
INTERRUPT_FLAG_PIN12
INTERRUPT_FLAG_PIN13
INTERRUPT_FLAG_PINA0
INTERRUPT_FLAG_PINA1
INTERRUPT_FLAG_PINA2
INTERRUPT_FLAG_PINA3
INTERRUPT_FLAG_PINA4
INTERRUPT_FLAG_PINA5

ATmega2560

These are External interrupt pins:

INTERRUPT_FLAG_PIN2
INTERRUPT_FLAG_PIN3
INTERRUPT_FLAG_PIN18
INTERRUPT_FLAG_PIN19
INTERRUPT_FLAG_PIN20
INTERRUPT_FLAG_PIN21
INTERRUPT_FLAG_PIN75 (fake Arduino pin)
INTERRUPT_FLAG_PIN76 (fake Arduino pin)
These are Pin Change interrupt pins:
INTERRUPT_FLAG_PIN10
INTERRUPT_FLAG_PIN11
INTERRUPT_FLAG_PIN12
INTERRUPT_FLAG_PIN13
INTERRUPT_FLAG_PIN15
INTERRUPT_FLAG_PIN14
INTERRUPT_FLAG_PIN70 (fake Arduino pin)
INTERRUPT_FLAG_PIN71 (fake Arduino pin)
INTERRUPT_FLAG_PIN72 (fake Arduino pin)
INTERRUPT_FLAG_PIN73 (fake Arduino pin)
INTERRUPT_FLAG_PIN74 (fake Arduino pin)
INTERRUPT_FLAG_PINA8
INTERRUPT_FLAG_PINA9
INTERRUPT_FLAG_PINA10
INTERRUPT_FLAG_PINA11
INTERRUPT_FLAG_PINA12
INTERRUPT_FLAG_PINA13
INTERRUPT_FLAG_PINA14
INTERRUPT_FLAG_PINA15
INTERRUPT_FLAG_PINSS
INTERRUPT_FLAG_PINSCK
INTERRUPT_FLAG_PINMOSI
INTERRUPT_FLAG_PINMISO

Leonardo

External interrupt pins:

INTERRUPT_FLAG_PIN0
INTERRUPT_FLAG_PIN1
INTERRUPT_FLAG_PIN2
INTERRUPT_FLAG_PIN3
INTERRUPT_FLAG_PIN7
Pin Change interrupt pins:
INTERRUPT_FLAG_PINSS (not available on Leonardo; third party boards only)
INTERRUPT_FLAG_PINSCK
INTERRUPT_FLAG_PINMOSI
INTERRUPT_FLAG_PINMISO
INTERRUPT_FLAG_PIN8
INTERRUPT_FLAG_PIN9
INTERRUPT_FLAG_PIN10
INTERRUPT_FLAG_PIN11

Functions

 enableInterruptFast - Enables fast interrupt on a selected Arduino pin.
 disableInterrupt - Disables interrupt on the selected Arduino pin.

Function Reference

enableInterruptFast()

 enableInterruptFast(uint8_t pinNumber, uint8_t mode);
 or
 enableInterruptFast(uint8_t interruptDesignator, uint8_t mode);

Enables interrupt on the selected pin. The arguments are:

  • pinNumber - The number of the Arduino pin, such as 3, or A0, or SCK. Note that these are not strings, so when you use A0 for example, do not use quotes.
  • interruptDesignator- very much like a pin. See below.
  • mode - What kind of signal you want the interrupt to interrupt on. For Pin Change Interrupt pins, the modes supported are RISING, FALLING, or CHANGE. For External Interrupt pins, the modes supported are the same, plus LOW. HiSpeed mode is not supported on the Due board because all of its pins are higher speed than on the ATmega chips. Again, the modes are not strings- just type them in verbatim, they are derived into a proper value by the compiler.
    • RISING - The signal went from "0", or zero volts, to "1", or 5 volts.
    • FALLING - The signal went from "1" to "0".
    • CHANGE - The signal either rose or fell.
    • HIGH - The signal is at a high level. Due only
    • LOW' - The signal is at a low level. Due and External Interrupt pins only
Each pin supports only 1 variable definition and 1 mode at a time. Of course, you can define as many interrupt pins as are supported on the chip. See the INTERRUPT_FLAG_PIN bestiary, above.

disableInterrupt()

 disableInterrupt(uint8_t pinNumber);
 or
 disableInterrupt(uint8_t interruptDesignator);

Disables interrupt on a selected Arduino pin. You can reenable the pin with the same or a different function and mode.

The arguments are:

  • pinNumber - The number of the Arduino pin, such as 3, or A0, or SCK. Note that these are not strings, so when you use A0 for example, do not use quotes.
  • interruptDesignator- very much like a pin. See the Usage page.

What is an InterruptDesignator?

See the Usage page.

External Interrupts

See the Usage page.

Pin Change Interrupts

See the Usage page.

Due Interrupts

HiSpeed mode does not apply to the Due. The Arduino Due with its ARM CPU is a wholly different beast than the ATmega series of chips. Not only is it a 32 bit processor (vs. 8 on the ATmega), and its clock runs at 84 MHz, but its interrupt system is superior to that on the ATmega chips, even compared to External interrupts. This is because the Due's CPU stores the CPU register state automatically via hardware. Thus, all interrupts are "HiSpeed".

PIN / PORT BESTIARY

See the Usage page.

LICENSE

Licensed under the Apache2.0 license. See the source files for the license boilerplate, the LICENSE file for the full text, and the NOTICE file which is required by the Apache2.0 license to be distributed with any code that you distribute that uses this library. The copyright holder for this code is Michael Schwager.