-
Notifications
You must be signed in to change notification settings - Fork 72
Usage HiSpeed
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.
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 NEEDFORSPEEDChoose 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.
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- All, except pins 0 and 1 are not recommended and not tested.
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
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
External interrupt pins:
INTERRUPT_FLAG_PIN0 INTERRUPT_FLAG_PIN1 INTERRUPT_FLAG_PIN2 INTERRUPT_FLAG_PIN3 INTERRUPT_FLAG_PIN7Pin 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
enableInterruptFast - Enables fast interrupt on a selected Arduino pin. disableInterrupt - Disables interrupt on the selected Arduino pin.
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
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.
See the Usage page.
See the Usage page.
See the Usage page.
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".
See the Usage page.
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.