Code Monkey home page Code Monkey logo

enableinterrupt's Introduction

EnableInterrupt

New Arduino interrupt library, designed for all versions of the Arduino.

Functions:

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

*What's New?

  • Wed Sep 4 19:30:45 CDT 2019
    • Version 1.1.0 of the library has been released. We add support for the ATmega2561 and 1281 chips, with pinouts defined from the MCUdude/MegaCore project. Code donations by Kizmit99. Plus, a documentation bugfix from Greg Bowler. Thanks, folks!

The EnableInterrupt library is an Arduino interrupt library, designed for 8-bit versions of the Arduino- at this writing, the Uno (and other ATmega328p-based boards, like the mini), Due, Zero, Leonardo (and other ATmega32u4-based boards, like the Micro), the Mega2560 (and other ATmega2560-based boards, like the MegaADK), and for non-Arduino chips: the 644/1284p (Mighty1284, Sodaq Mbili and EnviroDIY Mayfly) ATtiny 44/84, and ATtiny 45/85 (using DA Mellis' support files). The library enables you to assign an interrupt to pins on your chip that support them, and presents a common interface to all supported chips. This means that on the Arduino Uno and Mega you don't give it an interrupt number, as per http://arduino.cc/en/Reference/attachInterrupt. Rather, your first argument is a pin number of a pin that's supported on that chip (see https://github.com/GreyGnome/EnableInterrupt/wiki/Usage#pin--port-bestiary ).

32-bit support for Due comes only in the form of a macro that enables your code to be shared unchanged between 32- and 8-bit Arduinos. No further support for 32-bit Arduinos is planned.

Download

See the https://github.com/GreyGnome/EnableInterrupt/wiki/Download page to download the library.

More Information

See the Wiki at https://github.com/GreyGnome/EnableInterrupt/wiki/Home . For detailed usage information see https://github.com/GreyGnome/EnableInterrupt/wiki/Usage .

See the examples subdirectory in the distribution or in this Git site for code examples.

See the extras subdirectory in the distribution or in this Git site for License and Release Notes.

For a tutorial on interrupts, see http://www.engblaze.com/we-interrupt-this-program-to-bring-you-a-tutorial-on-arduino-interrupts/ The posting gets into low-level details on interrupts.

IMPORTANT NOTE: In 0.9.2 I discovered a rather pernicious bug, wherein the library was setting the global interrupt enable bit. This could cause a serious and difficult-to-debug race condition, as it is not the job of the library to manage that bit. The chips come with interrupts enabled so existing code should not be affected, but if you were relying on that behavior note that it has changed. My thanks to http://gammon.com.au/interrupts (the 'How are interrupts queued?' section).

ATmega Processor Interrupt Types

Note that the ATmega processor at the heart of the Arduino Uno/Mega2560/Leonardo/ATmega1284 has two different kinds of interrupts: “external”, and “pin change”. For the list of available interrupt pins and their interrupt types, see the PORT / PIN BESTIARY, below.

External Interrupts

There are a varying number of external interrupt pins on the different processors. The Uno supports only 2 and they are mapped to Arduino pins 2 and 3. The 2560 supports 6 usable, the Leonardo supports 5, and the ATmega1284p supports 3. These interrupts can be set to trigger on one of three signal values: RISING, FALLING, or CHANGE (for both), or on LOW level. The triggers are interpreted by hardware, so by the time your user function is running, you know exactly which pin interrupted at the time of the event, and how it changed. On the other hand, as mentioned there are a limited number of these pins.

Pin Change Interrupts

On the Arduino Uno (and again, all 328p-based boards) and 644/1284-based boards, the pin change interrupts can be enabled on any or all of the pins. The two pins 2 and 3 on 328p-based boards, or three pins (2, 10, and 11) on the 1284-based boards support either pin change or external interrupts. On 2560-based Arduinos, there are 18 pin change interrupt pins in addition to the 6 external interrupt pins. On the Leonardo there are 7 pin change interrupt pins in addition to the 5 external interrupt pins. See PIN BESTIARY below for the pin numbers and other details.

Pin Change interrupts trigger on all RISING and FALLING (ie, "CHANGE") signal edges. Furthermore, the processor's pins, and pin change interrupts, are grouped into “port”s, so for example on the Arduino Uno there are three ports and therefore only 3 interrupt vectors (subroutines) available for the entire body of 20 pin change interrupt pins.

The Library and Pin Change Interrupts

The foregoing means that not only do pin change interrupts trigger on all pin transitions, but a number of pins share a single interrupt subroutine. It's the library's function to make pin change interrupts appear that each pin can support RISING, FALLING, or CHANGE, and each pin can support its own user-defined interrupt subroutine.

When an event triggers an interrupt on any interrupt-enabled pin on a port, a library subroutine ("interrupt handler", "interrupt service routine", or "ISR") attached to that pin's port is triggered. It is up to the EnableInterrupt library to set the proper port to receive interrupts for a pin, to determine what happened when an interrupt is triggered (which pin? ...did the signal rise, or fall?), to handle it properly (Did we care if the signal fell? Did we care if it rose?), then to call the programmer's chosen subroutine (ISR). This makes the job of resolving the action on a single pin somewhat complicated. There is a definitive slowdown in the interrupt routine because of this complication. So there is a significant* time between when the interrupt triggers and when the pins are read to determine what actually happened (rising or falling) and which pin changed. So the signal could have changed by the time the pin's status is read, returning a false reading back to your sketch. Therefore, these pins are not suitable for fast changing signals, and under the right conditions such events as a bouncing switch may actually be missed. Caveat Programmer. If you're concerned about this, continue to read the following information and make sure to read the wiki pages; especially see https://github.com/GreyGnome/EnableInterrupt/wiki/Usage#atmega-processor-interrupt-types . For a further review of this issue see https://github.com/GreyGnome/EnableInterrupt/blob/master/Interrupt%20Timing.pdf

USAGE:

Basic Usage

enableInterrupt- Enables interrupt on a selected Arduino pin.

enableInterrupt(uint8_t pinNumber, void (*userFunction)(void), uint8_t mode);
or
enableInterrupt(uint8_t interruptDesignator, void (*userFunction)(void), uint8_t 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 below.
* userFunction - The name of the function you want the interrupt to run. Do not
use a pointer here, just give it the name of your function. See the example code
in the Examples directory.
* mode - What you want the interrupt to interrupt on. For Pin Change Interrupt
pins, the modes supported are RISING, FALLING, or CHANGE.
** 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.

For External Interrupts, the same modes are supported plus the additional mode
of LOW signal level.
** LOW - The signal is at a low level for some time.

Each pin supports only 1 function and 1 mode at a time.

disableInterrupt- Disables interrupt on a selected Arduino pin.

disableInterrupt(uint8_t pinNumber);
or
disableInterrupt(uint8_t interruptDesignator);
  • interruptDesignator: Essentially this is an Arduino pin, and if that's all you want to give the function, it will work just fine. Why is it called an "interruptDesignator", then? Because there's a twist: You can perform a bitwise "and" with the pin number and PINCHANGEINTERRUPT to specify that you want to use a Pin Change Interrupt type of interrupt on those pins that support both Pin Change and External Interrupts. Otherwise, the library will choose whatever interrupt type (External, or Pin Change) normally applies to that pin, with priority to External Interrupt.

  • The complexity is because of pins 2 and 3 on the ATmega328-based Arduinos, and pins 2, 10, and 11 on 1284-based boards. Those are the only pins on the processors supported by this library that can share External or Pin Change Interrupt types. Otherwise, each pin only supports a single type of interrupt and the PINCHANGEINTERRUPT scheme changes nothing. This means you can ignore this whole discussion for ATmega2560, ATmega32U4, or SAM3X8E (Due)-based Arduinos.

It is possible to change the user function assigned to an interrupt after enabling it (if you want). Later in your code simply disable the interrupt and enable it with a different function.

Determine the Pin That Was Interrupted

There is a facility in the library to identify the most recent pin that triggered an interrupt. Set the following definition '''before''' including the EnableInterrupt.h file in your sketch:

 #define EI_ARDUINO_INTERRUPTED_PIN

Then, the ATmega chip will set a variable with every interrupt, and you can query it to find which pin interrupted your sketch. The variable is arduinoInterruptedPin and it is of type uint8_t.

See the https://github.com/GreyGnome/EnableInterrupt/wiki/Usage wiki page for more information.

PIN / PORT BESTIARY

Theoretically pins 0 and 1 (RX and TX) are supported but as these pins have a special purpose on the Arduino, their use in this library has not been tested.

Summary

Arduino Uno/Duemilanove/etc.

Interrupt Type Pins
External 2 3
Pin Change 2-13 and A0-A5

Arduino Mega2560

Interrupt Type Pins
External 2 3 and 18-21
Pin Change 10-15 and A8-A15 and SS, SCK, MOSI, MISO

Arduino Leonardo

Interrupt Type Pins
External 0-3 and 7
Pin Change 8-11 and SCK, MOSI, MISO

Mighty 1284, Sodaq Mbili, EnviroDIY Mayfly

Interrupt Type Pins
External 2 10 11
Pin Change 0-31 (aka: 0-23 and A0-A7)

Details

Arduino Uno

Interrupt Pins:
Arduino	External                Arduino Pin Change      Arduino Pin Change
Pin     Interrupt               Pin     Interrupt       Pin     Interrupt
                Port                           Port                     Port
2       INT0    PD2             2       PCINT18 PD2     A0      PCINT8  PC0
3       INT1    PD3             3       PCINT19 PD3     A1      PCINT9  PC1
                                4       PCINT20 PD4     A2      PCINT10 PC2
                                5       PCINT21 PD5     A3      PCINT11 PC3
                                6       PCINT22 PD6     A4      PCINT12 PC4
                                7       PCINT23 PD7     A5      PCINT13 PC5
                                8       PCINT0  PB0
                                9       PCINT1  PB1
                                10      PCINT2  PB2
                                11      PCINT3  PB3
                                12      PCINT4  PB4
                                13      PCINT5  PB5

Leonardo Pins LEONARDO

Interrupt pins:
Arduino                         Arduino
Pin     External                Pin     Pin Change
        Interrupt                       Interrupt
               Port                               Port
 3      INT0   PD0              8       PCINT4    PB4
 2      INT1   PD1              9       PCINT5    PB5
 0      INT2   PD2              10      PCINT6    PB6
 1      INT3   PD3              11      PCINT7    PB7
 7      INT6   PE6              SCK/15  PCINT1    PB1
                                MOSI/16 PCINT2    PB2
                                MISO/14 PCINT3    PB3

                                on ICSP:
                                SCK/15:  PCINT1 (PB1)
                                MOSI/16: PCINT2 (PB2)
                                MISO/14: PCINT3 (PB3)

// Map SPI port to 'new' pins D14..D17
static const uint8_t SS   = 17;
static const uint8_t MOSI = 16;
static const uint8_t MISO = 14;
static const uint8_t SCK  = 15;
// A0 starts at 18

ATmega2560 Support

External Interrupts ------------------------------------------------------------
The following External Interrupts are available on the Arduino:
Arduino           
  Pin  PORT INT  ATmega2560 pin
  21     PD0  0     43
  20     PD1  1     44
  19     PD2  2     45
  18     PD3  3     46
   2     PE4  4      6
   3     PE5  5      7
 n/c     PE6  6      8  (fake pin 75) **
 n/c     PE7  7      9  (fake pin 76)


Pin Change Interrupts ----------------------------------------------------------

ATMEGA2560 Pin Change Interrupts
Arduino              Arduino              Arduino
  Pin  PORT PCINT     Pin   PORT PCINT     Pin   PORT PCINT
  A8     PK0  16       10     PB4   4       SS     PB0   0
  A9     PK1  17       11     PB5   5       SCK    PB1   1
 A10     PK2  18       12     PB6   6       MOSI   PB2   2
 A11     PK3  19       13     PB7   7       MISO   PB3   3
 A12     PK4  20       14     PJ1  10
 A13     PK5  21       15     PJ0   9
 A14     PK6  22        0     PE0   8 - this one is a little odd. *
 A15     PK7  23

The library supports all interrupt pins, even though not all pins to the ATmega-2560 processor are exposed on the Arduino board. These pins are supported as "fake pins", and begin with pin 70 (there are 70 pins on the ATmega 2560 board). The fake pins are as follows:

pin: fake70 PJ2 this is Pin Change Interrupt PCINT11
pin: fake71 PJ3 this is Pin Change Interrupt PCINT12
pin: fake72 PJ4 this is Pin Change Interrupt PCINT13
pin: fake73 PJ5 this is Pin Change Interrupt PCINT14
pin: fake74 PJ6 this is Pin Change Interrupt PCINT15
pin: fake75 PE6 this is External Interrupt INT6
pin: fake76 PE7 this is External Interrupt INT7
  • Note: Arduino Pin 0 is PE0 (PCINT8), which is RX0. Also, it is the only other pin on another port on PCI1. This would make it very costly to integrate with the library's code and thus is not supported by this library. It is the same pin the Arduino uses to upload sketches, and it is connected to the FT232RL USB-to-Serial chip (ATmega16U2 on the R3).

ATmega2561/1281 (MegaCore) Support

External Interrupts ------------------------------------------------------------
The following External Interrupts are available on the Arduino/MegaCore:
MegaCore           
  Pin  PORT INT  ATmega2561/1281 pin
  18     PD0  0     25
  19     PD1  1     26
  20     PD2  2     27
  21     PD3  3     28
   4     PE4  4      6
   5     PE5  5      7
   6     PE6  6      8
   7     PE7  7      9


Pin Change Interrupts ----------------------------------------------------------

ATMEGA2561/1281 (MegaCore) Pin Change Interrupts
MegaCore
 Pin      PORT   PCINT
  8/SS     PB0     0
  9/SCK    PB1     1
  10/MOSI  PB2     2
  11/MISO  PB3     3
  12       PB4     4
  13       PB5     5
  14       PB6     6
  15       PB7     7
   0       PE0     8 - this one is a little odd. *
  • Note: Arduino Pin 0 is PE0 (PCINT8), which is RX0. Also, it is the only other pin on another port on PCI1. This would make it very costly to integrate with the library's code and thus is not supported by this library. It is the same pin the Arduino uses to upload sketches, and it is connected to the FT232RL USB-to-Serial chip (ATmega16U2 on the R3).

Mighty 1284, Bobuino, EnviroDIY Mayfly, Sodaq Mbili Support

The ATmega 1284p shares pinout with the 644; the only difference is in memory size. We use the "Mighty 1284" platform as our model, because the needed files are mature and complete.

Interrupt Pins:
Mighty  External                Mighty                                 Mighty           
Pin     Interrupt               Pin*  PORT PCINT ATmega644/1284 pin    Pin*  PORT PCINT ATmega644/1284 pin
                Port            0     PB0   8         1                15    PD7  31        21
2       INT2    PB2             1     PB1   9         2                16    PC0  16        22
10      INT1    PD2             2     PB2   2         3                17    PC1  17        23
11      INT0    PD3             3     PB3  11         4                18    PC2  18        24
                                4     PB4  12         5                19    PC3  19        25
                                5     PB5  13         6                20    PC4  20        26
                                6     PB6  14         7                21    PC5  21        27
                                7     PB7  15         8                22    PC6  22        28
                                8     PD0  24        14                23    PC7  23        29
                                9     PD1  25        15             31/A7    PA7   7        33
                               10     PD2  26        16             30/A6    PA6   6        34
                               11     PD3  27        17             29/A5    PA5   5        35
                               12     PD4  28        18             28/A4    PA4   4        36
                               13     PD5  29        19             27/A3    PA3   3        37
                               14     PD6  30        20             26/A2    PA2   2        38
                                                                    25/A1    PA1   1        39
                                                                    24/A0    PA0   0        40

Bobuino External                Bobuino                                Bobuino           
Pin     Interrupt               Pin*  PORT PCINT ATmega644/1284 pin    Pin*  PORT PCINT ATmega644/1284 pin
                Port            4     PB0   8         1                31    PD7  31        21
2       INT2    PB2             5     PB1   9         2                22    PC0  16        22
10      INT1    PD2             6     PB2   2         3                23    PC1  17        23
11      INT0    PD3             7     PB3  11         4                24    PC2  18        24
                               10     PB4  12         5                25    PC3  19        25
                               11     PB5  13         6                26    PC4  20        26
                               12     PB6  14         7                27    PC5  21        27
                               13     PB7  15         8                28    PC6  22        28
                                0     PD0  24        14                29    PC7  23        29
                                1     PD1  25        15             14/A0    PA7   7        33
                                2     PD2  26        16             15/A1    PA6   6        34
                                3     PD3  27        17             16/A2    PA5   5        35
                               30     PD4  28        18             17/A3    PA4   4        36
                                8     PD5  29        19             18/A4    PA3   3        37
                                9     PD6  30        20             19/A5    PA2   2        38
                                                                    20/A6    PA1   1        39
                                                                    21/A7    PA0   0        40

Mayfly                          Mayfly                                 Mayfly
Mbili   External                Mbili                                  Mbili           
Pin     Interrupt               Pin*  PORT PCINT ATmega644/1284 pin    Pin*  PORT PCINT ATmega644/1284 pin
                Port            8     PB0   8         1                 7    PD7  31        21
2       INT2    PB2             9     PB1   9         2                16    PC0  16        22
10      INT1    PD2            10     PB2   2         3                17    PC1  17        23
11      INT0    PD3            11     PB3  11         4                18    PC2  18        24
                               12     PB4  12         5                19    PC3  19        25
                               13     PB5  13         6                20    PC4  20        26
                               14     PB6  14         7                21    PC5  21        27
                               15     PB7  15         8                22    PC6  22        28
                                0     PD0  24        14                23    PC7  23        29
                                1     PD1  25        15             31/A7    PA7   7        33
                                2     PD2  26        16             30/A6    PA6   6        34
                                3     PD3  27        17             29/A5    PA5   5        35
                                4     PD4  28        18             28/A4    PA4   4        36
                                5     PD5  29        19             27/A3    PA3   3        37
                                6     PD6  30        20             26/A2    PA2   2        38
                                                                    25/A1    PA1   1        39
                                                                    24/A0    PA0   0        40
# Thanks! Thank you for downloading and enjoying the EnableInterrupt library. I hope you find it useful. Heck, I wrote it for you- yeah, that's right- you. The Maker and/or Geek sitting before your project and trying to make little computers do fun stuff. It's not easy, and my hat goes off to you. I hope I've made stuff a little easier for you.

This software would not be nearly as useful as it is without the help of the following people:

Thanks to Loranzo Cafaro for his switch debounce example, to Jevon Wild for his changes to make the library more functional with PlatformIO (http://docs.platformio.org/en/latest/what-is-platformio.html), Ricardo JL Rufino for some PlatformIO fixes to the library.json file, and Sara Damiano for adding support for the Sodaq Mbili and EnviroDIY Mayfly.

And, from the past, this library's predecessor was the PinChangeInt library. I have done a complete rewrite and not used any of its code, but I learned a lot by doing the previous one and I feel like I still owe a debt of gratitude to all the geeks who created/contributed/helped/debugged. So without further ado, I present the "ACKNOWLEDGEMENTS" section from the previous library. Note that "this" library in the following refers to PinChangeInt:

This library was originally written by Chris J. Kiick, Robot builder and all around geek, who said of it, "Hi, Yeah, I wrote the original PCint library. It was a bit of a hack and the new one has better features. I intended the code to be freely usable. Didn't really think about a license. Feel free to use it in your code: I hereby grant you permission." Thanks, Chris! A hack? I dare say not, if I have taken this any further it's merely by standing on the shoulders of giants. This library was the best "tutorial" I found on Arduino Pin Change Interrupts and because of that I decided to continue to maintain and (hopefully) improve it. We, the Arduino community of robot builders and geeks, owe you a great debt of gratitude for your hack- a hack in the finest sense.

The library was then picked up by Lex Talionis, who created the Google Code website. We all owe a debt of thanks to Lex, too, for all his hard work! He is currently the other official maintainer of this code.

Many thanks to all the contributors who have contributed bug fixes, code, and suggestions to this project:

John Boiles and Baziki (who added fixes to PcInt), Maurice Beelen, nms277, Akesson Karlpetter, and Orly Andico for various fixes to this code, Rob Tillaart for some excellent code reviews and nice optimizations, Andre' Franken for a good bug report that kept me thinking, cserveny.tamas a special shout out for providing the MEGA code to PinChangeInt, and Pat O'Brien for testing and reporting on the Arduino Yun.- Thanks!

A HUGE thanks to JRHelbert for fixing the PJ0 and PJ1 interrupt PCMSK1 issue on the Mega... 06/2014

A HUGE thanks to Jan Baeyens ("jantje"), who has graciously DONATED an Arduino Mega ADK to the PinChangeInt project!!! Wow, thanks Jan! This makes the 2560-based Arduino Mega a first class supported platform- I will be able to test it and verify that it works.

  • In 2018, Alex Reinert contributed Bobuino support. Thanks, Alex!

  • In 4/2019 Kizmit99 contributed support for the ATmega2561 and 1281 chips, with pinouts defined from the MCUdude/MegaCore project. Thanks, Kizmit99!

  • In 8/2019 Greg Bowler helped suss out a documentation bug, and contributed a patch to make the README.md less confusing. Much appreciated.

Finally, a shout out to Leonard Bernstein. I was inspired by him (https://www.youtube.com/watch?feature=player_detailpage&v=R9g3Q-qvtss#t=1160) from a Ted talk by Itay Talgam. None of the contributors, myself included, has any interest in making money from this library and so I decided to free up the code as much as possible for any purpose. ...But! You must give credit where credit is due (it's not only a nice idea, it's the law- as in, the license terms)!

"If you love something, give it away."

I apologize if I have forgotten anyone here. Please let me know if so.

enableinterrupt's People

Contributors

alexreinert avatar dorkusprime avatar g105b avatar greygnome avatar ricardojlrufino avatar srgdamia1 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

enableinterrupt's Issues

FALLING function is never fired

Thank you for your work on this library!

I'm using ATMEGA328P chip. Here is my setup function:

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(9600);
  while(!Serial);
  Serial.setTimeout(1000);

  pinMode(PIN_COUNTER_1, INPUT_PULLUP);
  digitalWrite(LED_BUILTIN, HIGH);
  enableInterrupt(PIN_COUNTER_1, c1_fall, FALLING);
  enableInterrupt(PIN_COUNTER_1, c1_rise, RISING);
}

Within c1_rise function, the c1_rstatus variable is incremented successfully.

Within c1_fall function, the c1_fstatus variable is never incremented.

I can't figure out what I'm doing wrong with the library.

Here's my full ino script:

#include <EnableInterrupt.h>

#define PIN_COUNTER_1 9
#define DEBOUNCE 10
#define COOLOFF 1000
#define DELAY_PRINT 50

volatile unsigned long c1 = 0;
volatile unsigned long last_c1 = 0;
volatile unsigned long c1_ftime = 0;
volatile unsigned long c1_rtime = 0;

volatile unsigned long c1_fstatus = 0;
volatile unsigned long c1_rstatus = 0;

unsigned int t = 0;
unsigned int last_t = 0;

void output() {
  if(t - last_t < DELAY_PRINT) {
    return;
  }

  if(c1 == last_c1) {
    return;
  }
  
  Serial.print("C1\t");
  Serial.println(c1);
  Serial.print("ftime, rtime: ");
  Serial.print(c1_ftime);
  Serial.print(", ");
  Serial.println(c1_rtime);
  Serial.print(c1_fstatus);
  Serial.print(", ");
  Serial.println(c1_rstatus);
  last_c1 = c1;
  last_t = t;
}

// Only register a falling edge if it's long enough away from the previous rising edge (debounce)
void c1_fall() {
  unsigned long itime = millis();

  c1_fstatus = 1;

  // If a falling edge has been registered
  // and the time since last falling edge is less than debounce time,
  // ignore!
  if(c1_ftime > 0
  && itime - c1_ftime < DEBOUNCE) {
    return;
  }

  c1_fstatus = 2;

  // If a rising edge has been registered
  // and the time since last rising edge is less than cooloff time,
  // ignore!
  if(c1_rtime > 0
  && itime - c1_rtime < COOLOFF) {
    return;
  }

  c1_fstatus = 3;

  // Register a successful falling edge.
  c1_ftime = itime;
}

void c1_rise() {
  unsigned long itime = millis();

  c1_rstatus = 1;

  // If a rising edge has been registered
  // and the time since last rising edge is less than debounce time,
  // ignore!
  if(c1_rtime > 0
  && itime - c1_rtime < DEBOUNCE) {
    return;
  }

  c1_rstatus = 2;

  // If the time since last falling edge is less than colloff time,
  // ignore!
  if(itime - c1_ftime < COOLOFF) {
    return; // Too soon - cool off!
  }

  c1_rstatus = 3;

  c1_rtime = itime;
  c1++;
}

void c1_change() {
  unsigned long itime = millis();

  c1_rstatus = 1;

  // If a rising edge has been registered
  // and the time since last rising edge is less than debounce time,
  // ignore!
  if(c1_rtime > 0
  && itime - c1_rtime < DEBOUNCE) {
    return;
  }

  c1_rstatus = 2;

  // If the time since last falling edge is less than colloff time,
  // ignore!
  if(itime - c1_ftime < COOLOFF) {
    return; // Too soon - cool off!
  }

  c1_rstatus = 3;

  c1_rtime = itime;
  c1++;
}

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(9600);
  while(!Serial);
  Serial.setTimeout(1000);

  pinMode(PIN_COUNTER_1, INPUT_PULLUP);
  digitalWrite(LED_BUILTIN, HIGH);
  enableInterrupt(PIN_COUNTER_1, c1_fall, FALLING);
  enableInterrupt(PIN_COUNTER_1, c1_rise, RISING);
}

void loop() {
  t = millis();
  output();
  delay(10);
}

This library cannot be used in bigger projects.

If this library is used in projects spread over more than a single INO-file, i.e. if separate headers and code files are used, it breaks the linking process.

Because all code is simply put into a header file, the linker will produce a load of errors concerning multiple definitions. This cannot be catched by your include guards. For working in more than simple projects, this libray must be split into a separate code file (.cpp) and a header file containing solely declarations. I had the same problems already with the predecessor PinChangeInt.

Useless.h #include <EnableInterrupt.h> bug

Hi, I'm using EnableInterrupt as a submodule for one of my projects. I found a compiler bug regarding EnableInterrupt/examples/SimpleWithLibrary/Useless.h; the verbose output is as follows:

In file included from /var/folders/70/7_syjtnx1zb_t62jc3qwvk_w0000gn/T/buildb1edcb75b05118bd4250494061fe263d.tmp/sketch/EnableInterrupt/examples/SimpleWithLibrary/Useless.cpp:3:0:
/var/folders/70/7_syjtnx1zb_t62jc3qwvk_w0000gn/T/buildb1edcb75b05118bd4250494061fe263d.tmp/sketch/EnableInterrupt/examples/SimpleWithLibrary/Useless.h:15:29: fatal error: EnableInterrupt.h: No such file or directory
#include "EnableInterrupt.h"

And after a few minutes tinkering, I found a solution. Changing line 15 from #include <EnableInterrupt.h> to #include "../../EnableInterrupt.h". Not really sure why it gave me errors considering all the other .ino files in the examples directory seem to find the file just fine.

Using PORTB interrupts on ATtiny84

Pin change interrupts set on B0 and B1 were failing to trigger the appropriate functions.

Adding the following to the code directs mask to the right register and appears to solve the issue:

ifdef EI_ATTINY24

interruptMask = PCMSK1 & interruptMask;
...

ENDIF

WInterrupts.c.o (symbol from plugin): In function `attachInterrupt': (.text+0x0): multiple definition of `__vector_1'

Massive apologies in advance, first time I've posted a problem. Like the title says I get a compiling error due to attachInterrupt and multiple definition of vector 1 and 2. I've tried using different digital pins and including #define EI_NOTINT0 and #define EI_NOTINT1 in my sketch but I do not know what is going wrong. I've read that you are not meant to use serial.print but that surely can't be the problem? because serial print is a major function of Arduino prototyping.

I am using 3 pins to read 3 Hall effect sensors and migrated from using attachInterrupt to enableInterrupt as the prior does not accommodate more than 2 pins.

Below is the error message


Arduino: 1.8.3 (Linux), Board: "Arduino/Genuino Uno"

In file included from /local/XXXX/Arduino/flow_oct_v1/flow_oct_v1.ino:1:0:
/local/XXXX/Arduino/libraries/EnableInterrupt-master/EnableInterrupt.h:22:125: note: #pragma message: NOTICE: *** EnableInterrupt library version pre-0.9.6. This is not a problem. Keep calm, and carry on. ***
#pragma message("NOTICE: *** EnableInterrupt library version pre-0.9.6. This is not a problem. Keep calm, and carry on. ***")
^
WInterrupts.c.o (symbol from plugin): In function attachInterrupt': (.text+0x0): multiple definition of __vector_1'
sketch/flow_oct_v1.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here
WInterrupts.c.o (symbol from plugin): In function attachInterrupt': (.text+0x0): multiple definition of __vector_2'
sketch/flow_oct_v1.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
exit status 1
Error compiling for board Arduino/Genuino Uno.

-------------------------------------------------------------------------------------------------------------------------------------------And this is my sketch

#include <EnableInterrupt.h>

#define EI_NOTINT0
#define EI_NOTINT1

/*
Liquid flow rate sensor -DIYhacking.com Arvind Sanjeev

Measure the liquid/water flow rate using this code.
Connect Vcc and Gnd of sensor to arduino, and the
signal line to arduino digital pin 2.

*/

byte statusLed = 13;

// byte sensorInterrupt = 0; // 0 = digital pin 2
byte sensorPin1 = 5;

// The hall-effect flow sensor outputs approximately 4.5 pulses per second per
// litre/minute of flow.
float calibrationFactor = 4.5;

volatile byte pulseCount1;

float flowRate1;
unsigned int flowMilliLitres1;
unsigned long totalMilliLitres1;

unsigned long oldTime;

byte sensorPin2 = 4;
// The hall-effect flow sensor outputs approximately 4.5 pulses per second per
// litre/minute of flow.

volatile byte pulseCount2;

float flowRate2;
unsigned int flowMilliLitres2;
unsigned long totalMilliLitres2;

byte sensorPin3 = 7;

volatile byte pulseCount3;

float flowRate3;
unsigned int flowMilliLitres3;
unsigned long totalMilliLitres3;

void setup()
{

// Initialize a serial connection for reporting values to the host
Serial.begin(9600);

// Set up the status LED line as an output
pinMode(statusLed, OUTPUT);
digitalWrite(statusLed, HIGH); // We have an active-low LED attached

pinMode(sensorPin1, INPUT);
digitalWrite(sensorPin1, HIGH);

pinMode(sensorPin2, INPUT);
digitalWrite(sensorPin2, HIGH);

pinMode(sensorPin3, INPUT);
digitalWrite(sensorPin3, HIGH);

pulseCount1 = 0;
flowRate1 = 0.0;
flowMilliLitres1 = 0;
totalMilliLitres1 = 0;

pulseCount2 = 0;
flowRate2 = 0.0;
flowMilliLitres2 = 0;
totalMilliLitres2 = 0;

pulseCount3 = 0;
flowRate3 = 0.0;
flowMilliLitres3 = 0;
totalMilliLitres3 = 0;

oldTime = 0;

// The Hall-effect sensor is connected to pin 2 which uses interrupt 0.
// Configured to trigger on a FALLING state change (transition from HIGH
// state to LOW state)
// attachInterrupt(sensorInterrupt, pulseCounter, FALLING);

enableInterrupt(5, pulseCounter1, FALLING);

enableInterrupt(4, pulseCounter2, FALLING);

enableInterrupt(7, pulseCounter3, FALLING);

Serial.println("Qf,,Vf1,,Vf2,,Qr,,Vr1,,Vr2,,Qp,,Vp1,,Vp2,,");
}

/**

  • Main program loop
    */
    void loop()
    {

    if((millis() - oldTime) > 1000) // Only process counters once per second
    {
    // Disable the interrupt while calculating flow rate and sending the value to
    // the host
    //detachInterrupt(sensorInterrupt);
    disableInterrupt(5);
    disableInterrupt(4);
    detachInterrupt(7);

    // Because this loop may not complete in exactly 1 second intervals we calculate
    // the number of milliseconds that have passed since the last execution and use
    // that to scale the output. We also apply the calibrationFactor to scale the output
    // based on the number of pulses per second per units of measure (litres/minute in
    // this case) coming from the sensor.
    flowRate1 = ((1000.0 / (millis() - oldTime)) * pulseCount1) / calibrationFactor;
    flowRate2 = ((1000.0 / (millis() - oldTime)) * pulseCount2) / calibrationFactor;
    flowRate3 = ((1000.0 / (millis() - oldTime)) * pulseCount3) / calibrationFactor;

    // Note the time this processing pass was executed. Note that because we've
    // disabled interrupts the millis() function won't actually be incrementing right
    // at this point, but it will still return the value it was set to just before
    // interrupts went away.
    oldTime = millis();

    // Divide the flow rate in litres/minute by 60 to determine how many litres have
    // passed through the sensor in this 1 second interval, then multiply by 1000 to
    // convert to millilitres.
    flowMilliLitres1 = (flowRate1 / 60) * 1000;
    flowMilliLitres2 = (flowRate2 / 60) * 1000;
    flowMilliLitres3 = (flowRate3 / 60) * 1000;

    // Add the millilitres passed in this second to the cumulative total
    totalMilliLitres1 += flowMilliLitres1;
    totalMilliLitres2 += flowMilliLitres2;
    totalMilliLitres3 += flowMilliLitres3;

    unsigned int frac;

    // Print the flow rate for this second in litres / minute
    Serial.print(int(flowRate1)); // Print the integer part of the variable
    Serial.print(",");
    Serial.print("L/min");
    Serial.print(",");
    //Serial.print("\t"); // Print tab space

    // Print the cumulative total of litres flowed since starting;
    Serial.print(totalMilliLitres1);
    Serial.print(",");
    Serial.print("mL");
    Serial.print(",");
    //Serial.print("\t"); // Print tab space
    Serial.print(totalMilliLitres1/1000);
    Serial.print(",");
    Serial.print("L");
    Serial.print("\t");

    // this migh not work****************************************
    Serial.print(",");
    // Print the flow rate for this second in litres / minute
    Serial.print(int(flowRate2)); // Print the integer part of the variable
    Serial.print(",");
    Serial.print("L/min");
    Serial.print(",");
    //Serial.print("\t"); // Print tab space

    // Print the cumulative total of litres flowed since starting;
    Serial.print(totalMilliLitres2);
    Serial.print(",");
    Serial.print("mL");
    Serial.print(",");
    // Serial.print("\t"); // Print tab space
    Serial.print(totalMilliLitres2/1000);
    Serial.print(",");
    Serial.print("L");
    Serial.print(",");
    Serial.print("\t");

    // Print the flow rate for this second in litres / minute
    Serial.print(int(flowRate3)); // Print the integer part of the variable
    Serial.print(",");
    Serial.print("L/min");
    Serial.print(",");
    //Serial.print("\t"); // Print tab space

    // Print the cumulative total of litres flowed since starting;
    Serial.print(totalMilliLitres3);
    Serial.print(",");
    Serial.print("mL");
    Serial.print(",");
    //Serial.print("\t"); // Print tab space
    Serial.print(totalMilliLitres3/1000);
    Serial.print(",");
    Serial.println("L");
    //*************************************************************

    // Reset the pulse counter so we can start incrementing again
    pulseCount1 = 0;
    pulseCount2 = 0;
    pulseCount3 = 0;

    // Enable the interrupt again now that we've finished sending output
    //attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
    enableInterrupt(5, pulseCounter1, FALLING);

    enableInterrupt(4, pulseCounter2, FALLING);

    enableInterrupt(7, pulseCounter3, FALLING);
    }
    }

/*
Insterrupt Service Routine
*/
void pulseCounter1()
{
// Increment the pulse counter
pulseCount1++;
}
void pulseCounter2()
{
// Increment the pulse counter
pulseCount2++;
}
void pulseCounter3()
{
// Increment the pulse counter
pulseCount3++;
}

Apologies again as I can only presume there must be a painfully obvious solution to those that know.
And thanks.
Michael

Compile error with external interrupts

Thanks for this library,

Should I be able to use both this and external interrupts together?

just including this library with my code causes compile error.
I'm using a ProMicro (Leonardo) and IDE 1.8.1

#include <Keyboard.h>
#include <HID.h>
#include <Mouse.h>
//#include <EnableInterrupt.h>

#define pinA1 1 //Roller A
#define pinZ1 8 //Spinner

long cntX=0; //counter for mouse X-axis
long lastcntX=0;
float realX=0;
float incX= 0.5; // This gives approx correct speed on missile command default sensitivity 20
float incZ= 0.1; // high resolution spinner needs low value here.

void setup() {

// pinMode(pinZ1, INPUT_PULLUP);
// enableInterrupt(pinZ1,doZCount, CHANGE);

pinMode(pinA1, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(pinA1),doACountX,CHANGE);

Mouse.begin();
Keyboard.begin();
}

void loop() {
//send mouse update to usb
cntX = realX;
if(cntX!=lastcntX ){
Mouse.move((cntX-lastcntX),0);
lastcntX=cntX;
}
}

void doZCount() { // spinner is moving
realX = realX +incZ;
}

void doACountX() { // ball is moving
realX = realX +incX;
}

Build v1.0.0 and pragma message

Build please v1.0.0 and remove pragma notice there
EnableInterrupt library version 0.9.7. This is not a problem. Keep calm, and carry on

Conflict with SoftSerial

Including both Softserial and EnableInterrupt produces a compile conflict. Both libraries appear to be going after the same interrupt vector.

Sleep Modes

How Do I use Sleep modes with this library?

I am thinking of using lowpower library

This library does not coexist with other code using interrupts

I tried to use this library to add pinChange interrupt capability to an existing sketch. When I simply added #include <EnableInterrupt.h> into my main sketch, the build failed with multiple duplicate references.
After exploring a bit I discovered that all I had to do was use the 'Simple' example, #include a reference one of my other libraries (which supports hardware with its own interrupt handler) and that build failed. I then created a very simple extension to 'Simple' example in which there was a secondary file with its own interrupt handler and was not surprised that that failed as well. (I'd include the source files here but don't see how to do it)

Also, the EnableInterrupt.h file is peppered with references to actual Arduino boards, not to the underlying processor. Consequently any board that is NOT included in the set will not be built properly, these include new Arduino designs or designs using AVR processors that are not 'official' Arduino designs.

Use in library

My main sketch and a library I wrote are using EnableInterrupt. That means I have to include EnableInterrupt twice - in my main sketch and in my library.

The linker is giving me "multiple definition" errors. I've read about similar errors (https://forum.arduino.cc/index.php?topic=351281.15) and I believe it is caused by having the definitions inside the .h file instead of in a separate file.

Analog PIN - interrupt fired with minimal voltage change

Hi. I'm using Mega2560 and Analog pin A8 to A15.
I'm seeing strange behavior, using CHANGE, RISING or FALLING, any voltage change fire interrupt.
example, if it's on 0V and goes to 1V interrupt fire.
if it's 5V and goes to 4.9V interrupt fire.
Could you help me?

Sorry for my poor english!

Thanks a lot! This library save my life!

License?

I'd be very interested in using your library in a project. Would it be possible for you to add a license to this library? Also would you be able to do LGPL, or BSD, or something similar? My company may not allow me to use this library if it's Apache 2.0. I am planning on completely open-sourcing my entire project, but I won't be able to do that unless this library uses a license that my company's lawyers are comfortable with.

Thanks so much for your consideration.

Wake from Sleep Atmega2560 INT7 (PE7) - Gboard Pro

Hi, first of all i wanted to thank you for this wonderful job of yours.
I am using a Gboard Pro by Itead which is basically an Atmega2560 with Nrf24 IRQ pin attached to pin PE7 of the atmega. I can use your example code for generating the ISR on that pin but if i put the MCU i can't wake it up by that interrupt. Could you please explain how to achieve so? I suppose it is related to some flag that i read about in the datasheet but i am not that into technicalities.
Thanks in advance.

Multiple pins detected as 1 PCInt

I am using DS3231 RTC with my Arduino Yun, and connect DS3231's SQW pin (generates interrupt at preset alarm time) to arduino pin 10. EnableInterrupt detects the interrupt, but it also detects it when I connect the wire to pin 9. It also detects it occasionally when I connect it to pin 11 - though it seems to be more like random. I am concerned about this because pins 9, 11 are supposed to control different operations in the future of my project.
What could be done? Should I better use A0-A5 pins instead?

function name conflict with SD card library

In file included from recTest_Calculate.ino:16:0:
~\Documents\Arduino\libraries\EnableInterrupt-master/EnableInterrupt.h: In function 'void SerialPrint_P(const char*)':
~\Documents\Arduino\libraries\EnableInterrupt-master/EnableInterrupt.h:115:6: error: redefinition of 'void SerialPrint_P(const char*)'
 void SerialPrint_P(const char *str) {
      ^
In file included from C:\Program Files\Tools\arduino-1.7.3\libraries\SD\src/SD.h:21:0,
                 from recTest_Calculate.ino:5:
C:\Program Files\Tools\arduino-1.7.3\libraries\SD\src/utility/SdFatUtil.h:61:22: error: 'void SerialPrint_P(const char*)' previously defined here
 static NOINLINE void SerialPrint_P(PGM_P str) {
                      ^
Error compiling.

Identified Error -> multiple definition of `__vector_1'

I have been updating my libraries to use This new EnableInterrupt, but I was hitting a wall with this error message: multiple definition of `__vector_1', of course the compiler flags the error in code that has no relationship with the actual cause of the problem. So I just kept simplifying my code until i found what was left.

It turns out the if you use attachInterrupt(), (the Arduino Standard procedure) it produces this collision, now I am converting all of the old attachInterrupt() calls to enableInterrupt().

I think you should add this error message to your FAQ.

chuck.

edit: Solved this error only to create a new error.

I am using EnableInterrupt to add CTS/RTS handshaking to HardwareSerial. It works just fine, BUT, of course there is a but, If I want to use EnableInterrupt in my 'Application' level code, now I get
C:\Documents and Settings\user\My Documents\Arduino\libraries\EnableInterrupt/EnableInterrupt.h:783: multiple definition of `enableInterrupt(unsigned char, void (*)(), unsigned char)'

Here is the how I included EnableInterrupt in HardwareSerial.cpp:

#define EI_ARDUINO_INTERRUPTED_PIN // to support CTS handshaking 
#include "C:\Documents and Settings\user\My Documents\Arduino\libraries\EnableInterrupt\EnableInterrupt.h"
 //To support CTS handshaking 02AUG2015 Chuck Todd

Any Clues how to solve this collision?

Chuck.
Edit 27AUG15 19:41MDT

Here is a working solution, still testing, but so far it works. In the 'Application, or Application libraries' instead of #include <EnableInterrupt.h> use this:

extern void enableInterrupt(uint8_t interruptDesignator, void (*userFunction)(void), uint8_t mode);
extern void disableInterrupt(uint8_t interruptDesignator);

Chuck.

Fake Pin of atmega2560 conflicts with pins from datasheet

pin: fake70 PJ2 this is Pin Change Interrupt PCINT11
pin: fake71 PJ3 this is Pin Change Interrupt PCINT12
pin: fake72 PJ4 this is Pin Change Interrupt PCINT13
pin: fake73 PJ5 this is Pin Change Interrupt PCINT14
pin: fake74 PJ6 this is Pin Change Interrupt PCINT15
pin: fake75 PE6 this is External Interrupt INT6
pin: fake76 PE7 this is External Interrupt INT7

Must BE ||
pin: fake65 PJ2 this is Pin Change Interrupt PCINT11
pin: fake66 PJ3 this is Pin Change Interrupt PCINT12
pin: fake67 PJ4 this is Pin Change Interrupt PCINT13
pin: fake68 PJ5 this is Pin Change Interrupt PCINT14
pin: fake69 PJ6 this is Pin Change Interrupt PCINT15
pin: fake8 PE6 this is External Interrupt INT6
pin: fake76 PE7 this is External Interrupt INT7

http://www.atmel.com/Images/Atmel-2549-8-bit-AVR-Microcontroller-ATmega640-1280-1281-2560-2561_datasheet.pdf
https://www.arduino.cc/en/uploads/Hacking/PinMap2560sma_.png

#define EI_NOTINT0 does not produce compilable code

Please take this with a grain of salt, as I have like 12 total hours of Arduino time under my belt, but I believe that there are a number of spots (e.g. the first line of ei_external328.h) where you have:

#if ! defined(EI_NOTINT0) && !defined (EI_NOTINT1)

Where what you meant is

#if ! ( defined(EI_NOTINT0) && defined (EI_NOTINT1) )

(I'm working on something that uses the V-USB library with another library (the PS2 keyboard library) that also wants an interrupt. The comments in the v-usb library struck terror in my heart, so I was loathe to change that, and the PS2 keyboard library is in pretty rough shape, so I modified that to use your library, because I couldn't fathom how I could modify the system attachInterrupt, which is apparently incompatible with v-usb.)

Software Serial

Will softwareserial cause problem with this library?
We are building our hardware and trying to shift UART operations to software serial. But its also necessary for use to use your library. But I want make sure before I can go further. I think SoftwareSerial also use PCINT.

Interrupt and Pin Numbers with Mega2560 correct?!

In the pint-to-INT-List I see different things then in the official infos.

Official:
External Interrupts: 2 (interrupt 0), 3 (interrupt 1), 18 (interrupt 5), 19 (interrupt 4), 20 (interrupt 3), and 21 (interrupt 2). These pins can be configured to trigger an interrupt on a low value, a rising or falling edge, or a change in value. See the attachInterrupt() function for details.

this differs from your infos ... will it work on mega or not?

Extra comma in const array declaration

\EnableInterrupt/EnableInterrupt.h:193: warning: only initialized variables can be placed into program memory area

const uint8_t PROGMEM digital_pin_to_port_bit_number_PGM[] = {
  0, // 0 == port D, 0
  1,
  2,
.......
  4,
  5,
};

The comma after the last 5 should not be there.

Error Return for specifying Invalid pin?

I looked through the EnableInterrupt.h code, I did not see any error checking for invalid pins. I have used the current version 0.8.1 to implement RTS/CTS handshaking for HardwareSerial::begin(baud,config,CTS_pin,RTS_pin);. I am concerned about passing invalid pin values to EnableInterrupt. I use a FALLING mode interrupt for the CTS_pin.
Is there a possible error value I can check to validate the Arduino Pin I passed to your library is valid?
How does the library handle a invalid pin?
Chuck.

Support for Arduino Zero

I'm haven't this board so I can't see if this fantastic library is already compatible or not, but as anywhere is said it is, I'd like to know if this compatibility exists, and if it doesn't, ask for it.
Thanks!

in v 0.7, cannot disable port D for arduino UNO

my setup:

#define EI_NOTPORTB
// #define EI_NOTPORTC 
#define EI_NOTPORTD
#define EI_NOTEXTERNAL
#include <EnableInterrupt.h>

errors:

/Users/hwestbrook/Documents/Arduino/libraries/EnableInterrupt/EnableInterrupt.h: In function 'void __vector_5()':
/Users/hwestbrook/Documents/Arduino/libraries/EnableInterrupt/EnableInterrupt.h:1192:19: error: 'portSnapshotD' was not declared in this scope
   changedPins   = portSnapshotD ^ current;
                   ^
/Users/hwestbrook/Documents/Arduino/libraries/EnableInterrupt/EnableInterrupt.h:1193:19: error: 'risingPinsPORTD' was not declared in this scope
   tmp           = risingPinsPORTD & current;
                   ^
/Users/hwestbrook/Documents/Arduino/libraries/EnableInterrupt/EnableInterrupt.h:1194:19: error: 'fallingPinsPORTD' was not declared in this scope
   interruptMask = fallingPinsPORTD & ~current;
                   ^
/Users/hwestbrook/Documents/Arduino/libraries/EnableInterrupt/EnableInterrupt.h:1205:31: error: 'portDFunctions' was not declared in this scope
   if (interruptMask & _BV(0)) portDFunctions.pinZero();
                               ^
/Users/hwestbrook/Documents/Arduino/libraries/EnableInterrupt/EnableInterrupt.h:1206:31: error: 'portDFunctions' was not declared in this scope
   if (interruptMask & _BV(1)) portDFunctions.pinOne();
                               ^
/Users/hwestbrook/Documents/Arduino/libraries/EnableInterrupt/EnableInterrupt.h:1207:31: error: 'portDFunctions' was not declared in this scope
   if (interruptMask & _BV(2)) portDFunctions.pinTwo();
                               ^
/Users/hwestbrook/Documents/Arduino/libraries/EnableInterrupt/EnableInterrupt.h:1208:31: error: 'portDFunctions' was not declared in this scope
   if (interruptMask & _BV(3)) portDFunctions.pinThree();
                               ^
/Users/hwestbrook/Documents/Arduino/libraries/EnableInterrupt/EnableInterrupt.h:1209:31: error: 'portDFunctions' was not declared in this scope
   if (interruptMask & _BV(4)) portDFunctions.pinFour();
                               ^
/Users/hwestbrook/Documents/Arduino/libraries/EnableInterrupt/EnableInterrupt.h:1210:31: error: 'portDFunctions' was not declared in this scope
   if (interruptMask & _BV(5)) portDFunctions.pinFive();
                               ^
/Users/hwestbrook/Documents/Arduino/libraries/EnableInterrupt/EnableInterrupt.h:1211:31: error: 'portDFunctions' was not declared in this scope
   if (interruptMask & _BV(6)) portDFunctions.pinSix();
                               ^
/Users/hwestbrook/Documents/Arduino/libraries/EnableInterrupt/EnableInterrupt.h:1212:31: error: 'portDFunctions' was not declared in this scope
   if (interruptMask & _BV(7)) portDFunctions.pinSeven();
                               ^

It compiles just fine if port c is disabled too

ATmega328PB

Hi GreyGnome, is it possible to get the Lib work with an 328PB ?
Would be great Thx.

Examples won't compile

I have tried 3 examples, and none of them compiles. I am using Arduino 1.0.5 IDE. The following are just examples, there are many more errors.

EnableInterrupt OOSimple
OOSimple.ino: In function 'void* createSimple()':
OOSimple:10: error: previous declaration of 'void* createSimple()' with 'C++' linkage

EnableInterruptTest:183: error: 'ByteBuffer' does not name a type
EnableInterruptTest.ino: In function 'void quicfunc0()':
EnableInterruptTest:228: error: 'PCintPort' has not been declared

SimpleWithLibrary.cpp.o: In function UselessClass': /Useless.h:19: undefined reference toUselessClass::init(unsigned char, unsigned char)'

In my own code, when I include the header file in just my library cpp file, I get
C:...\mcHC_SR04.cpp:81: error: 'disableInterrupt' was not declared in this scope
To make the code work, I had to include the header in both the main sketch and the library file. The #define LIBCALL_ENABLEINTERRUPT worked in either file.

Assigning Class member as interrupt Function.

GreyGnome,
I'm in the process of adding CTS/RTS handshaking to the HardwareSerial object. I had previously used pinInterrupt with arduino 1.0. With the New 1.6.5 IDE they have totally changed Hardware Serial. The TX buffer is now a member of the class instead of a Global buffer.
The complier will not allow (interruptFunctionType)&this->_cts_clear_irq. It will allow (interruptFunctionType)&HardwareSerial::_cts_clear_irq. (the compiler did not force _cts_clear_irq to be a STATIC member, it used a uint16_t off the stack as the object pointer when I tried it.) But the instance pointer this was not set to the correct value.

I am at a loss on how to correctly access these internal buffers from a irq.

any suggestions?
Chuck.

Edit: add:
Can you make another enableInterrupt() that also accepts a this value? you would have to custom code the callback to push the this value on the stack before the class member callback.
Reading through the other open issues, it looks like the pinInterruptNumber variable would enable a workaround. Adding support to emulate a object member callback would increase the complexity of every callback too much.
Could you redefine the callback function with the pinNumber as a parameter? In your code these all would be constants in the if(interruptmask&_BV(x))portn.callback[x](pinNumber);

conflict please help.

I am using your library which performs great. But I wanted to use it with nrf24. For nrf Radio modules I am using radiohead's library and they both seem to have some conflict. I checked that it has to do with the driver RH_RF24.h because commenting it causes no error.
error is .
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
C:\Users\ASUS-PC\AppData\Local\Temp\build6046962854557047475.tmp/core.a(WInterrupts.c.o): In function __vector_1': C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/WInterrupts.c:309: multiple definition of__vector_1'
powerDownWakeExternalInterrupt_MY.cpp.o:C:\Program Files (x86)\Arduino\libraries\EnableInterrupt/EnableInterrupt.h:948: first defined here
C:\Users\ASUS-PC\AppData\Local\Temp\build6046962854557047475.tmp/core.a(WInterrupts.c.o): In function attachInterrupt': C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/WInterrupts.c:39: multiple definition of__vector_2'
powerDownWakeExternalInterrupt_MY.cpp.o:C:\Program Files (x86)\Arduino\libraries\EnableInterrupt/EnableInterrupt.h:473: first defined here
collect2.exe: error: ld returned 1 exit status
Error compiling.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
I would also try to contact radio head's author.
Any Idea How I resolve this.
I am attaching interrupts on 2,3,4,5,6 pin on Pro mini. Also using a LowPower.h but thats not causing this I have check.
Thanks in advance.

Passing some form of state to interrupt subroutines

Do you think it's feasible to change the callback function type to a void function that has a void pointer parameter? This would allow for passing state to the callback function, eliminating the need to declare multiple functions for each instance of a particular object (as your ooSimple example would require). I know that storing the void pointers may roughly double the library's memory usage and may complicate the #defines. Regardless, I believe this would be really useful.

Testing EnableInterrupt on ATmega1284p

Hi Mike,
I've been testing the Simple example on a LowPower labs Moteino Mega (ATMEGA1284p) .
I believe I may have encountered a defect in the EnableInterrupt library I downloaded on Nov 16 2015.

My tests using a single pushbutton were only partially successful. I was able to run the Simple example successfully on pins 0 to 7, A0 to A7, and 10 and 11 ... but was unable to activate pin change interrupts on pins 12 through 23. I have confirmed that the hardware and wiring is functioning correctly.

I'd be happy to work with you to confirm and resolve.

I've run your Mighty1284p example, but I'm afraid I don't understand the expected outcome.
I am happy to help if you give me a little guidance.

John
[email protected]

New release to make the removal of the pragma "official"

Any chance you could do another release to force the library registries to pick up the change to the pragma message? I think this library is wonderful and use it all the time so it would be nice to stop seeing the outdated pragma with every build.

Thanks!

Compatibility with Arduino IDE library manager

Nice Lib. I had to move around the folders and files a little before my sketch compiled.
The current version of the Arduino IDE (1.6.4) has a standardised method to include external libraries.
By default it places the files from a ZIP file into a directory under the MyDocuments/Arduino folder.

When included using the libarary manager, it expects the header file to be included in the top folder of the libary file, and that header file is then inserted in the source of the sketch. Thus it requires the "EnableInterrupt.h" to be moved to the top folder of the ZIP file. Only the file to be included in the sketch is needed since all .h files found in the top folder are inserted in the sketch source. The description is currently not visible in the list within the IDE.

A manual on how to organise external libraries is documented on http://www.arduino.cc/en/Guide/Libraries

struct functionPointersPortB

Hello, I get the following error when I try to compile the code. Can you please provide some guidance on this?

In file included from Interrupt.ino:1:
/Users/arjunmehta94/Documents/Arduino/libraries/EnableInterrupt-master/EnableInterrupt.h: In function 'void __vector_3()':
/Users/arjunmehta94/Documents/Arduino/libraries/EnableInterrupt-master/EnableInterrupt.h:976: error: 'struct functionPointersPortB' has no member named 'pinSix'
/Users/arjunmehta94/Documents/Arduino/libraries/EnableInterrupt-master/EnableInterrupt.h:977: error: 'struct functionPointersPortB' has no member named 'pinSeven'

Sleep mode issues

I realize this has been reported prior, however Im not getting how to resolve it.
I have a Rotary Encoder/Switch
I want the switch to enter and exit sleep mode.
I have the switch on pin4 of my uno.

void setup()
{
...
enableInterrupt(2, intrEncChange1, CHANGE); //encoder interrupts
enableInterrupt(3, intrEncChange2, CHANGE);
enableInterrupt(4, intrEncChangeS, CHANGE);
...
}

void intrEncChangeS()
{
if (sw)
delay(1);
if (digitalRead(SencPin) == encSW)
return;
encSW = !encSW;
if (encSW)
sleepNow();
sw = false;
}
void intrEncChange1() //Read on interrupt Right turn - Fast +5
{
if (moving)
delay(1);
if (digitalRead(encPin1) == enc1)
return;
enc1 = !enc1;
if (enc1 && !enc2)
encVal += 5;
moving = false;
update();
}
void intrEncChange2() //Read on interrupt Left turn - Slow -1
{
if (moving)
delay(1);
if (digitalRead(encPin2) == enc2)
return;
enc2 = !enc2;
if (enc2 && !enc1)
encVal -= 1;
moving = false;
update();
}
void sleepNow()
{
disableInterrupt(4);
enableInterrupt(4, wakeUpNow, LOW);
set_sleep_mode(SLEEP_MODE_STANDBY);// Choose our preferred sleep mode
sleep_enable();// Set sleep enable (SE) bit
sleep_mode();// Put the device to sleep
sleep_disable();// Upon waking up, sketch continues from this point.
disableInterrupt(4);
enableInterrupt(4, intrEncChangeS, CHANGE);
}

How do I code this so that the switch works the way I need it to in order to resume from sleep mode?

Compiling error conflict with RFM69.h

When I try to include EnableInterrupt with HFM69.h I get multiple definition of:
__vector_1
__vector_2

Are these ISR that I should modify in the RFM69 library ?

Sid

multiple definition of `__vector_1' when compiling with MySensors

I am getting this errors:

C:\Users\marco\AppData\Local\Temp\buildca530f920e52af2e7c8f67a769a556af.tmp/core\core.a(WInterrupts.c.o): In function `__vector_1':
C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/WInterrupts.c:309: multiple definition of `__vector_1'
sketch\MySensor_Keypad.ino.cpp.o:C:\Users\marco\Documents\MySensors\libraries\EnableInterrupt/EnableInterrupt.h:1284: first defined here

C:\Users\marco\AppData\Local\Temp\buildca530f920e52af2e7c8f67a769a556af.tmp/core\core.a(WInterrupts.c.o): In function `nothing':
C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/WInterrupts.c:35: multiple definition of `__vector_2'
sketch\MySensor_Keypad.ino.cpp.o:C:\Users\marco\Documents\MySensors\libraries\EnableInterrupt/EnableInterrupt.h:1011: first defined here

I did not figure out easily how __vector_1 and __vector_2 are defined/used since there are preprocessor macros involved.

  • The EnableInterrupt examples compile correctly in my environment.
  • I am compiling for board Arduino Pro or Pro Mini (ATmega328 3.3V 8MHz).
  • I am using the MySensors library. It seems to be conflicting with this.

Any idea on how to solve?
Thank you!

Hi-Speed examples not compiling

Hi, I'm not sure where to ask this but here's my problem:

I'm unable to compile any sketches when hi speed mode is enabled, including the examples.

Here's the compiler error:

In file included from /home/engwan/sketchbook/libraries/EnableInterrupt/EnableInterrupt.h:829:0,
                 from HiSpeedTest.ino:52:
/home/engwan/sketchbook/libraries/EnableInterrupt/utility/ei_PinChange328.h: In function ‘void enableInterrupt(uint8_t, interruptFunctionType, uint8_t)’:
/home/engwan/sketchbook/libraries/EnableInterrupt/utility/ei_PinChange328.h:4:3: error: ‘risingPinsPORTB’ was not declared in this scope
/home/engwan/sketchbook/libraries/EnableInterrupt/utility/ei_PinChange328.h:9:3: error: ‘risingPinsPORTC’ was not declared in this scope
/home/engwan/sketchbook/libraries/EnableInterrupt/utility/ei_PinChange328.h:14:3: error: ‘risingPinsPORTD’ was not declared in this scope
In file included from /home/engwan/sketchbook/libraries/EnableInterrupt/EnableInterrupt.h:843:0,
                 from HiSpeedTest.ino:52:
/home/engwan/sketchbook/libraries/EnableInterrupt/utility/ei_PinChange328.h:22:3: error: ‘fallingPinsPORTB’ was not declared in this scope
/home/engwan/sketchbook/libraries/EnableInterrupt/utility/ei_PinChange328.h:27:3: error: ‘fallingPinsPORTC’ was not declared in this scope
/home/engwan/sketchbook/libraries/EnableInterrupt/utility/ei_PinChange328.h:32:3: error: ‘fallingPinsPORTD’ was not declared in this scope
In file included from /home/engwan/sketchbook/libraries/EnableInterrupt/EnableInterrupt.h:866:0,
                 from HiSpeedTest.ino:52:
/home/engwan/sketchbook/libraries/EnableInterrupt/utility/ei_PinChange328.h:44:3: error: ‘portSnapshotB’ was not declared in this scope
/home/engwan/sketchbook/libraries/EnableInterrupt/utility/ei_PinChange328.h:55:3: error: ‘portSnapshotC’ was not declared in this scope
/home/engwan/sketchbook/libraries/EnableInterrupt/utility/ei_PinChange328.h:66:3: error: ‘portSnapshotD’ was not declared in this scope
In file included from /home/engwan/sketchbook/libraries/EnableInterrupt/EnableInterrupt.h:957:0,
                 from HiSpeedTest.ino:52:
/home/engwan/sketchbook/libraries/EnableInterrupt/utility/ei_PinChange328.h: In function ‘void disableInterrupt(uint8_t)’:
/home/engwan/sketchbook/libraries/EnableInterrupt/utility/ei_PinChange328.h:78:3: error: ‘risingPinsPORTB’ was not declared in this scope
/home/engwan/sketchbook/libraries/EnableInterrupt/utility/ei_PinChange328.h:79:3: error: ‘fallingPinsPORTB’ was not declared in this scope
/home/engwan/sketchbook/libraries/EnableInterrupt/utility/ei_PinChange328.h:86:3: error: ‘risingPinsPORTC’ was not declared in this scope
/home/engwan/sketchbook/libraries/EnableInterrupt/utility/ei_PinChange328.h:87:3: error: ‘fallingPinsPORTC’ was not declared in this scope
/home/engwan/sketchbook/libraries/EnableInterrupt/utility/ei_PinChange328.h:94:3: error: ‘risingPinsPORTD’ was not declared in this scope
/home/engwan/sketchbook/libraries/EnableInterrupt/utility/ei_PinChange328.h:95:3: error: ‘fallingPinsPORTD’ was not declared in this scope
In file included from HiSpeedTest.ino:52:0:
/home/engwan/sketchbook/libraries/EnableInterrupt/EnableInterrupt.h: In function ‘void __vector_3()’:
/home/engwan/sketchbook/libraries/EnableInterrupt/EnableInterrupt.h:1269:19: error: ‘portSnapshotB’ was not declared in this scope
/home/engwan/sketchbook/libraries/EnableInterrupt/EnableInterrupt.h:1270:19: error: ‘risingPinsPORTB’ was not declared in this scope
/home/engwan/sketchbook/libraries/EnableInterrupt/EnableInterrupt.h:1271:19: error: ‘fallingPinsPORTB’ was not declared in this scope
In file included from HiSpeedTest.ino:52:0:
/home/engwan/sketchbook/libraries/EnableInterrupt/EnableInterrupt.h: In function ‘void __vector_4()’:
/home/engwan/sketchbook/libraries/EnableInterrupt/EnableInterrupt.h:1328:19: error: ‘portSnapshotC’ was not declared in this scope
/home/engwan/sketchbook/libraries/EnableInterrupt/EnableInterrupt.h:1329:19: error: ‘risingPinsPORTC’ was not declared in this scope
/home/engwan/sketchbook/libraries/EnableInterrupt/EnableInterrupt.h:1330:19: error: ‘fallingPinsPORTC’ was not declared in this scope
In file included from HiSpeedTest.ino:52:0:
/home/engwan/sketchbook/libraries/EnableInterrupt/EnableInterrupt.h: In function ‘void __vector_5()’:
/home/engwan/sketchbook/libraries/EnableInterrupt/EnableInterrupt.h:1380:19: error: ‘portSnapshotD’ was not declared in this scope
/home/engwan/sketchbook/libraries/EnableInterrupt/EnableInterrupt.h:1381:19: error: ‘risingPinsPORTD’ was not declared in this scope
/home/engwan/sketchbook/libraries/EnableInterrupt/EnableInterrupt.h:1382:19: error: ‘fallingPinsPORTD’ was not declared in this scope

EDIT: I tried using older versions and I got 0.6.3 to compile. Versions after that give the same error above.

Pin port number in called routine

Hello,

I'm using your excellent library to implement RC Pwm timing on an arduino uno. The interrupt routine I use is identical between pins, but needs to store separate data for separate pins. is there anyway for my interrupt routine to easily access which pin generated the interrupt request so I can use the same code for both pin interrupts with an array?

thanks very much!

How I can use enableInterrupt in class

// Test.h

ifndef _TEST_h

define _TEST_h

if defined(ARDUINO) && ARDUINO >= 100

#include "arduino.h"

else

#include "WProgram.h"

endif

define ADC_EXTERNAL_PIN 2

include <EnableInterrupt.h>

class TestClass
{
protected:
interruptFunctionType pInt;

public:
TestClass();
void init();
void start();
void stop();
static void _interruptFunction();
};

endif

// Test.cpp

include "Test.h"

void TestClass::init()
{

pInt = static_cast( TestClass::_interruptFunction);
}

void TestClass::start()
{
enableInterrupt (ADC_EXTERNAL_PIN, pInt , FALLING);
}
void TestClass::stop()
{
disableInterrupt (ADC_EXTERNAL_PIN);
}

this code not compiled

arduinoInterruptedPin variable not available in my library files

When debugging code I placed in a library, the arduinoInterruptedPin variable would have been a big help, but was not available. The reason is that variables can not be defined in header files that are included in multiple source files. When they are, a multiple definition error is generated. The EnableInterrupt library is implemented as a header file with 2 sections,

  • One that is included in all the files that use the library - the header section, and
  • One that must be included in only the top level sketch (source file) - the implementation section

My suggested solution is to

  • Move the variable definition to the implementation section
  • Add a function prototype to the header section
  • Implement the function in the implementation section

In the Arduino C implementation, function prototypes can be included via a header file in multiple source files without any problem. The function should simply return the value of the variable. This modification should allow all existing code that uses the variable to continue operating without any changes, and will allow libraries to also access the interrupting pin numbers.

The following is code that I have tested. You may use it if you like, or change what ever makes sense. I am not trying to tell you what to do, just making a suggestion.

#ifdef EI_ARDUINO_INTERRUPTED_PIN
uint8_t arduinoInterruptedLastPin();      // function prototype
#endif


#ifndef LIBCALL_ENABLEINTERRUPT           // This is the magic dividing line
                                          // between prototypes and implementation
#ifdef EI_ARDUINO_INTERRUPTED_PIN
volatile uint8_t arduinoInterruptedPin=0; // This was moved from above the line

uint8_t arduinoInterruptedLastPin(){      // function implementation
  return arduinoInterruptedPin;
}
#endif

I also defined the variable as volatile because it is set via an interrupt routine.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.