-
Notifications
You must be signed in to change notification settings - Fork 72
SaveMemory
In order to make the Enable Interrupt library work as it does and easy to use, some compromises were necessary regarding code size. For example, on the ATmega328 an array of function pointers is defined for each port:
functionPointersPortB portBFunctions = { NULL, NULL, NULL, NULL, NULL, NULL, };
This sets up a block of memory 6 * 2-bytes long- 12 bytes total. Similarly for port C (12 bytes), port D (16 bytes), and an array of 4 bytes (2 function pointers) for the two External interrupts: 44 bytes total.
If you need a single interrupt on a Port B pin, that's only 2 bytes (a single function pointer) required, and 42 bytes wasted, or 2% of your available static RAM. So the library has included some features to allow you to shut off unneeded variables and functions.
Additionally you may find that this library conficts with other libraries (the SoftSerial library is a case in point). You may find that disabling one or more ISRs in this library enables you to use it with a conflicting library.
- Refer to the Usage#PIN / PORT BESTIARY section for the relationships between Arduino pins and the ATmega ports.
- Inventory your interrupt pins, and decide which ports you are able to shut off.
- In your main sketch, precede the
#include <EnableInterrupt.h>
with#define
statements that will prevent the variables and functions associated with the chosen ports from compiling, by inserting#define EI_NOTPORTx
wherex
refers to the port letter you wish to eliminate. - For external interrupts,
#define EI_INTx
to prevent code from compiling for your chosen External interrupt pins, where x refers to the External interrupt number. - You can also
#define EI_NOTEXTERNAL
if you are not using any External interrupts. - You can
#define EI_NOTPINCHANGE
if you are not using any Pin Change interrupts.
I have pin 7 and pin 8 each connected to a pushbutton switch on an Arduino Uno. Referring to the Bestiary, I see that these pins are on 2 ports:
Arduino Pin Port 7 PD7 8 PB0
This means I don't need to compile any code for Port C. Nor am I using External Interrupts. Therefore, my sketch can begin as follows:
#define EI_NOTPORTC #define EI_NOTEXTERNAL #include <EnableInterrupt.h>
Note that I am using only 1 interrupt pin on each port. If possible, it would be better to put the 2 pins on a single port. For example, move pin 8 to use pin 6 instead. Thus we would only be using port D, and we could define EI_NOTPORTB
as well, and save another few bytes.
These are the compiler directives available to you for the various processors. Check the Usage page to see which pins correspond to the
INTxand
PORTxdesignations:
Arduino Uno, etc.
EI_NOTEXTERNAL EI_NOTINT0 EI_NOTINT1 EI_NOTPINCHANGE EI_NOTPORTB EI_NOTPORTC EI_NOTPORTD
Arduino Mega, etc.
EI_NOTEXTERNAL EI_NOTINT0 EI_NOTINT1 EI_NOTINT2 EI_NOTINT3 EI_NOTINT4 EI_NOTINT5 EI_NOTINT6 EI_NOTINT7 EI_NOTPINCHANGE EI_NOTPORTB EI_NOTPORTJ EI_NOTPORTK
Arduino Leonardo, etc.
EI_NOTEXTERNAL EI_NOTINT0 EI_NOTINT1 EI_NOTINT2 EI_NOTINT3 EI_NOTINT6 EI_NOTPINCHANGE EI_NOTPORTB
EI_NOTEXTERNAL EI_NOTINT0 EI_NOTINT1 EI_NOTINT2 EI_NOTPINCHANGE EI_NOTPORTA EI_NOTPORTB EI_NOTPORTC EI_NOTPORTD
EI_NOTEXTERNAL EI_NOTINT0 EI_NOTPINCHANGE EI_NOTPORTA EI_NOTPORTB
EI_NOTEXTERNAL EI_NOTINT0 EI_NOTPINCHANGE EI_NOTPORTB
Not Applicable.
Here are some tests to demonstrate the amount of space saved by these optimizations. The Simple.ino example sketch was used with ARDUINOPIN
defined as pin 10, and the code was compiled for the ATmega2560. Note that pin 10 is on Port B:
Compile Simple.ino, no memory saving features enabled: Program: 6402 bytes (2.4% Full) (.text + .data + .bootloader) Data: 859 bytes (10.5% Full) (.data + .bss + .noinit) Compile Simple.ino, using pin 10, define EI_NOTEXTERNAL: Program: 5328 bytes (2.0% Full) (.text + .data + .bootloader) Data: 843 bytes (10.3% Full) (.data + .bss + .noinit) Compile Simple.ino, using pin 10, define EI_NOTPORTJ: Program: 5006 bytes (1.9% Full) (.text + .data + .bootloader) Data: 825 bytes (10.1% Full) (.data + .bss + .noinit) Compile Simple.ino, using pin 10, define EI_NOTPORTJ EI_NOTPORTK: Program: 4686 bytes (1.8% Full) (.text + .data + .bootloader) Data: 806 bytes (9.8% Full) (.data + .bss + .noinit) Compile Simple.ino, using pin 10, define EI_NOTPORTJ EI_NOTPORTK EI_NOTEXTERNAL: Program: 4674 bytes (1.8% Full) (.text + .data + .bootloader) Data: 806 bytes (9.8% Full) (.data + .bss + .noinit)