Skip to content
per1234 edited this page Oct 27, 2018 · 13 revisions

Table of Contents

The EnableInterrupt library does not work with *Insert name of other library here*

True, the library specifies the ISR's for all the Pin Change and External interrupt vectors. Other libraries need some of these interrupts and define all of them as well. To handle this, you can disable some of the ISRs in the Enable Interrupt library by turning off the conflicting ISRs. See the SaveMemory wiki page. You may actually need to modify the code in the other library to remove ISRs that you need to use with the EnableInterrupt library.

No really, the EnableInterrupt library does not work with the Software Serial library.

Don't use that library. Use Paul Stoffregen's AltSoftSerial library at https://github.com/PaulStoffregen/AltSoftSerial. The Software Serial library (including the NewSoftwareSerial library), for one thing, ties up your processor with delays; furthermore, those delays are within its ISR. The ISR reads in the bits off the line, reading an entire byte (including delays) before returning! This is a horrible practice for an interrupt routine. The AltSoftSerial uses the ATmega's timer circuitry. It is much, much friendlier to the CPU and allows your main program to run at the time between serial signal transitions, which is most of the time during a serial data transmission.

Yeah but what is the downside of the AltSoftSerial library?

It uses one of the ATmega's timers. Other than that, I think its design is far superior... Far superior.

I cannot include the EnableInterrupt library in my own library.

I cannot use the EnableInterrupt library with other code that uses the library.

Yes, yes you can. First some background: As you know, the C/C++ compiler allows you to separate your code into multiple files (which includes libraries). For example, your main sketch calls setup() and loop(), right? There is code in the Arduino software system (that is, the IDE that you use to write and upload your sketch) that tells your Arduino processor that it needs to call setup and loop, which you will define in your sketch. But the calling code is in a different place than your sketch, obviously (on my computer it's in the file /usr/share/arduino/hardware/arduino/cores/arduino/main.cpp). Since the multiple files are coded separately, they will be compiled separately. Before the Arduino IDE sends your program to the Arduino it then links all the needed files together.

Now, by default if you use the EnableInterrupt library in multiple files, then when the Arduino software gets to linking them, it discovers that certain functions (specifically the ISRs) have already been created. It complains because it would be an error to create another one; how is it to choose which function to really run?

It seems counterintuitive to compile the library's code twice; it makes no sense to us. Indeed, I have tried the --read-my-mind switch on the compiler. It says,

gcc: error: unrecognized command line option ‘--read-my-mind’
Drat; it doesn't work :-) . The compiler doesn't know that it makes no sense to compile code twice - it simply does what it's told. So, we have to be careful to tell the compiler *exactly* what to do. Therefore, you must insert
#define LIBCALL_ENABLEINTERRUPT
in front of every #include <EnableInterrupt.h> in every one of the files in which you want to use EnableInterrupt library functionality - *except one*. In that file (often but not necessarily your sketch), just place the #include directive; don't define the LIBCALL_ENABLEINTERRUPT. Then, for that one file only, the compiler will create the Arduino code and it will then link all references to its functions as necessary. The compiler is no longer confused since there is only one set of compiled code for the library.

I want to use the EnableInterrupt library to interrupt on Analog signals.

Sorry, that's not supported by the Arduino's interrupt system. Obviously, then, the library cannot do this. What you can do, however, is trigger an Analog-to-Digital conversion and the system will interrupt your sketch when it's done. Doing that is beyond the scope of this library. Don't get confused, however! The analogRead function is just another feature available on certain pins. Just as you can use a pin for input OR output, or some have UARTs attached to them, some are used for I2C, some for SPI, etc.... the beauty of the state of the art in MCUs is that not only are they cheap, they're incredibly adaptable. Don't let the fact that some pins are called "analog pins" confuse you... if you use them in their default digital mode, they act just like every other digital pin on the ATmega, because they are digital pins too.

I want to attach multiple function to a single pin.

Sorry, only 1 function per pin. If you need to call multiple functions then just have your function call other functions. Remember, however, not to spend too much time in the ISR. You should usually just set some flags and get out. This enables the CPU to respond to new interrupts as necessary.

If I #include the EnableInterrupt Library in My Library File, Why Do I Have to #include the EnableInterrupt Library in My Sketch?

With Arduino IDE 1.6.6 and newer, you don't. Older IDE versions are less good at resolving dependencies of libraries. With those versions it was necessary to add #include directives for dependencies of libraries in the sketch so that their path would be added to the list of included compile directories.

Can I use this library with the ESP8266?

No it will not work, but never fear - it's not necessary. On the ESP8266, pin interrupts are supported through the attachInterrupt and detachInterrupt functions. Interrupts may be attached to any GPIO pin, except GPIO16. Standard Arduino interrupt types are supported: CHANGE, RISING, FALLING. See https://arduino-esp8266.readthedocs.io/en/latest/reference.html#digital-io

The purpose of this library is to enable the ATmega-series, with their peculiar grouping of pins, to work seamlessly like attachInterrupt. "Seamlessly" meaning: If pin 1 interrupts, your sketch's pin 1 interrupt handler will be called.