Skip to content
Nick Yonge edited this page Oct 21, 2024 · 32 revisions

Table of Contents

Howto

Fast Start

Refer to the examples/Simple/Simple.ino sketch for an example of the library in use. Compare the instructions below to the code in that file. The file is designed to be used with the ATmega328 chip; there are other examples for the other chips.

To use the library:

To attach an interrupt to your Arduino (or 1284 or ATtiny) Pin, calling your function "userFunc", and acting on the "mode", which is a change in the pin's state; either RISING, FALLING, CHANGE, or (on External Interrupt pins ONLY), LOW:

At the top of your sketch, include:

       #include <EnableInterrupt.h>

Create a function that you want to run when your sketch is interrupted. Do not put any Serial.print() statements in your function. It also must not return any values and it cannot take any arguments (that is, its definition has to look like this):

       void userFunc() {
         ...your code here...
       }

In setup(), include:

       enableInterrupt(pin,userFunc,mode)

Pins that you can use follow. See the PIN / PORT BESTIARY below for the complete lists of pins for each CPU type:

  • ATmega328- All, except pins 0 and 1 are not recommended and not tested.
  • ATmega2560- 10 - 15, 18 - 21, A8 - A15, SS, SCK, MOSI, MISO
  • Leonardo- 0, 1, 2, 3, 7, 8, 9, 10, 11, MISO, SCK, MOSI, SS (on 3rd party boards)
  • Mighty1284- All, except pins 0 and 1 are not recommended. This chip has not been tested.
  • ATtiny44/84- All, except "pin 11" (PB3) is not defined in the support files (pins_arduino.h). The library should work to support that pin but you must modify the pins_arduino.h to support it.
  • ATtiny45/85- All (note that Gemma uses 3 pins for RESET, XTAL1, and XTAL2).
  • Due- All
  • Zero- All except pin 4.
That's it. For an example of this, see the aforementioned Simple.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.

Use With Objects

If you are a C++ programmer and enjoy working with objects, see the OOSimple.ino sketch in the examples folder.

Functions

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

Function Reference

enableInterrupt()

 enableInterrupt(uint8_t pinNumber, void (*userFunction)(void), uint8_t mode);
 or
 enableInterrupt(uint8_t interruptDesignator, void (*userFunction)(void), uint8_t mode);

Enables interrupt on the selected pin. Example: enableInterrupt(10, userFunction, RISING); 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 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. For the Due and Zero boards, the modes are the same as the External Interrupts, plus HIGH. Again, these 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 and Zero only
    • LOW' - The signal is at a low level. Due, Zero, and External Interrupt pins only
Each pin supports only 1 function and 1 mode at a time.

It is possible to change the user function after enabling the interrupt (if you want), by disabling the interrupt and enabling it with a different function.

disableInterrupt()

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

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

The arguments are:

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

Determine the Pin That Was Interrupted

You can assign a function to each of the pins upon which you want to enable interrupts, like this:

 enableInterrupt(9, myFunctionA, FALLING);
 enableInterrupt(10, myFunctionB, FALLING);
 enableInterrupt(11, myFunctionC, FALLING);

When any of the myFunctionX (where X is A, B, or C) gets called, you know exactly which pin triggered the interrupt. But what if you want the ISRs to share a single function? 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 test/example code in the examples/InterruptedPin[328|2560] directories. Here's a short example:

 volatile uint16_t interruptCountA=0; // The count will go back to 0 after hitting 65535.
 volatile uint16_t interruptCountB=0; // The count will go back to 0 after hitting 65535.
 
 void interruptFunctionA() {
   switch (arduinoInterruptedPin) {
     case 10:
       interruptCountA++;
       break;
     case 11:
       interruptCountB++;
       break;
   }
 }

Note that arduinoInterruptedPin is not marked volatile in the library, so the compiler is free to optimize it into a register. It may not be valid outside of an ISR.

Again, note (and I keep saying this): Because of the lag between the triggering of an interrupt and the actual running of an ISR, if you have multiple signals coming in on a port and a pin Y changes after pin X has triggered an interrupt, you may get false information. I imagine this would be rare, but it could happen- especially in high-speed circuits. If speed is of the essence (sub-millisecond, say), make sure you are using external interrupts.

Determine the Interrupted Pin's State

You can set the interrupt on a port to take place on rising, or falling, or both directions of signals (also low or high, depending on the type of chip). If you want to trigger on both directions, how do you know which way the signal changed that triggered the interrupt? The EnableInterrupt library provides a variable arduinoPinState which is updated early in the ISR code and should provide a fairly accurate indication.

This variable is provided when you use the #define EI_ARDUINO_INTERRUPTED_PIN functionality. As above, set the definition before including the EnableInterrupt.h file in your sketch.

The value of the variable is either 0 or some power of two (i.e., 2, 4, 8). 0 means that the pin changed from high to low signal. Other than 0 means the pin went from a low signal level to high.

What is an InterruptDesignator?

Essentially this is an Arduino pin, with a small bit of additional functionality, which is: You perform a bitwise "or" 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.

Example:

 enableInterrupt(2 | PINCHANGEINTERRUPT, myFunckyFunction, CHANGE);

...will set up a Pin Change interrupt on pin 2, and the ISR will call myFunckyFunction on any CHANGE of signal. This:

 enableInterrupt(2, myFunckyFunction, CHANGE);

will set up an External interrupt on pin 2. If you're troubled that there is a difference, my best piece of advice is this: Don't worry about it. If you use the Arduino long enough, you'll learn. But it's not significant enough at this stage in your development to worry about.

If you do simply use Arduino pin numbers, the Enable Interrupt library will choose whatever is appropriate for the pin, with a bias towards External interrupts. But make sure you use the proper mode- remember, LOW is not supported on Pin Change interrupts, and HIGH is only supported on the Due. These values are not error-checked for your platform/interrupt type, that would be too expensive software-wise.

Why the Interrupt Designator is Not a Big Deal

This complexity is all because of 2 pins 2 on the ATmega328-based Arduinos, and 3 pins on the ATmega-644 family of processors. Those are the only pins in the supported processors 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- or ATmega32U4-based Arduinos.

Saving Memory

You can define various preprocessor directives to save a few bytes (both static RAM and Flash). See SaveMemory.

Calling the Library from Other Libraries

It is possible to include this library in another library and thus make its functionality available to it. However, there is one caveat: without taking special percautions you will see linker errors about multiply-defined functions. You need to precede each one of the #include directives with #define LIBCALL_ENABLEINTERRUPT like this:

#define LIBCALL_ENABLEINTERRUPT
#include <EnableInterrupt.h>
...except one. In one and only one file in your project (meaning, all the files collected together to make your program), do not include that #define. That will allow the functions and variables to be compiled. Note that you must #include the library in your main sketch so that the Arduino system will add its path to the list of files to be compiled with your program, even if your main sketch doesn't set up any interrupts. See the FAQ for more information.

See the SimpleWithLibrary.ino sketch in the examples folder of the distribution for an example usage.

Conflicting ISRs with Other Libraries

You may find that you want to use another library that defines some of the same ISRs that the EnableInterrupt library defines. The compiler will throw an error because you are trying to define the same function twice. There are a couple of ways to handle this: You can either edit the other library or the EnableInterrupt library to remove the redundant ISRs, or you can eliminate some of the ISRs from the EnableInterrupt library by using some compiler directives to prevent them from being compiled. See SaveMemory for information about how to do that.

HiSpeed Mode

The EnableInterrupt library tries to be fast, but ultimately there is going to be some necessary overhead when calling a user-defined subroutine that is only known at compile time. 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 Usage-HiSpeed for details on how to use this mode, and HiSpeed for forther technical discussion and speed test results.

Important: Interrupt Types

After you've perhaps gotten the Simple.ino sketch working on your system, it's time to consider some of the nuances of the Arduino, especially of the Pin Change Interrupts.

ATmega Processor Interrupt Types

Note that the ATmega processors supported by this library have 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.

The Due and Zero only have a single type of interrupt, but it is superior to the ATmega chip's interrupt system in every significant way. This interrupt is somewhat analagous to the external interrupt type, but it carries less overhead, offers an additional interrupt on HIGH level, and includes other functionality such as interrupt priority. However, the only additional feature covered by this library is interrupt on HIGH.

External Interrupts

There are a varying number of external interrupt pins on the different ATmega processors. The Uno supports only 2 and they are mapped to Arduino pins 2 and 3. The 644/1284 support 3. The 2560 supports 6 usable, and the Leonardo supports 5. These interrupts can be set to trigger on RISING, or FALLING, or both ("CHANGE") signal levels, 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

Many of the interrupt pins on the ATmega processor used on all but the Arduino Due are "Pin Change Interrupt pins". This means that in the hardware, the pins only trigger on CHANGE, and a number of pins that share a "Port" share a single interrupt subroutine. For example, there are a total of 3 of these subroutines on the Arduino Uno. There is one subroutine for Port B, one for Port C, and one for Port D. There are 6 Port C pins (the A0 through A5 pins), and if Pin Change interrupts are enabled on those pins then if any of them change in any direction the single interrupt subroutine that serves those ports is called. It is not all bad, though, because you have to enable each pin that you wish to respond to Pin Change interrupts. So if you enable an interrupt on A0, the chip won't uselessly interrupt the other pins A1-A5. But the point is, if you enable an interrupt on A0 and any one or more of the other Analog pins, a single routine serves all of them.

But the EnableInterrupt library makes these interrupt types appear normal by creating the single interrupt routine to call a user-defined interrupt routine, so that each pin can individually support RISING or FALLING as well as CHANGE, and each pin can support its own user-defined interrupt subroutine- every usable pin on the processor can get its own interrupt subroutine (see AllPins328.ino in the examples directory). But 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 the library and hence 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.

For an utterly engrossing overview of this issue see https://github.com/GreyGnome/EnableInterrupt/blob/master/Interrupt%20Timing.pdf

On the Arduino Uno (and again, all 328p-based boards) and 644/1284-based systems, the pin change interrupts can be enabled on any or all of the pins. The two pins 2 and 3 support either pin change or external interrupts. On the 644/1284-based systems, pin change interrupts are supported on all pins and external interrupts are supported on pins 2, 10, and 11. 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.

Due and Zero Interrupts

The Arduino Due and Zero with their ARM CPUs are a different beast than the ATmega series of chips. Not only are they 32 bit processors (vs. 8 on the ATmega), and their clocks run at a much higher speed, but their interrupt systems are superior to that on the ATmega chips, even compared to External interrupts.

This means that the EnableInterrupt library's work on the Due and Zero is trivial: if called on those platforms, we simply create a macro that converts the form of enableInterrupt() and disableInterrupt() to attachInterrupt()/detachInterrupt().

Since that's all it does, the ONLY advantage the EnableInterrupt library offers is as a consistent API across the chip families. If you are not interested in this then don't use the EnableInterrupt library.

The EnableInterrupt library was designed to present a single API for interrupts to all the Arduino processors. Issues with interrupts have traditionally been caused by the varying and complicated pin interrupt schemes of the ATmega line of processors. The SAM processors on the Due and Zero present a more straightforward interrupt design. They already do what the EnableInterrupt library is trying to present: To enable an interrupt on any capable pin, simply set up that pin with the type of interrupt you want, no conversion to an "Interrupt Number" (see the attachInterrupt() docs).

Gemma Notes

The Arduino Gemma is based on the ATtiny85. For portability, I did not use the Gemma as the basis for ATtiny45/85 testing, rather, I used DA Mellis' work as mentioned elsewhere. However, the Gemma's pins_arduino.h is the same as a generic ATtiny45/85 so it should work without issue. Please open an Issue on the Github site if you find any bugs.

PIN / PORT BESTIARY

These are the pins that are supported on the different types of chips used in the Arduino.

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/ADK

 Interrupt Type | Pins
 -------------- | --------------
 External       | 2 3 and 18-21
 Pin Change     | 10-15 and A8-A15 and SS, SCK, MOSI, MISO
                  also, 'fake' pins 70-76 (see below under Details).

Arduino Leonardo

 Interrupt Type | Pins
 -------------- | --------------
 External       | 0-3 and 7
 Pin Change     | 8-11 and SCK, MOSI, MISO, SS (SS on 3rd party boards)

Mighty1284 / ATmega644/1284(P)

 Interrupt Type | Pins
 -------------- | --------------
 External       | 2 10 11
 Pin Change     | 2-23 and A0-A7

ATtiny44/84

 Interrupt Type | Pins
 -------------- | --------------
 External       | 8
 Pin Change     | 0 - 10 (and 11 if you modify pins_arduino.h from the ATtiny support files)

ATtiny45/85

 Interrupt Type | Pins
 -------------- | --------------
 External       | 2
 Pin Change     | 0-5

Arduino Due

All.

Arduino Zero

All except 4.

Details

Arduino Uno

ATmega168/328-based boards.

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

ATmega2560

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

* 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).

Fake Pins ---------------------------------------------------------- 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: fake 70 PJ2 this is Pin Change Interrupt PCINT11
pin: fake 71 PJ3 this is Pin Change Interrupt PCINT12
pin: fake 72 PJ4 this is Pin Change Interrupt PCINT13
pin: fake 73 PJ5 this is Pin Change Interrupt PCINT14
pin: fake 74 PJ6 this is Pin Change Interrupt PCINT15
pin: fake 75 PE6 this is External Interrupt INT6
pin: fake 76 PE7 this is External Interrupt INT7

Why support these pins? There are some non-Arduino boards that expose more pins, and even on the Arduino these may be useful for software interrupts. Software interrupts are used in my tests when I'm measuring the speed of the Arduino's interrupt system. You may find another use for them.

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
                                SS/17   PCINT0    PB0

                                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

Might1284 / ATmega644/1284(P)

See http://www.ot-hobbies.com/resource/ard-1284.htm for issues related to the ATmega644 family.

The following External Interrupts are available on the Mighty 1284:
Mighty           
  Pin*  PORT INT  ATmega644/1284 pin
   2    PB2   2      3
  10    PD2   0     16
  11    PD3   1     17

The following Pin Change Interrupts are available on the Mighty 1284:
Mighty                                 Mighty           
  Pin*  PORT PCINT ATmega644/1284 pin    Pin*  PORT PCINT ATmega644/1284 pin
   0     PB0   8         1                15    PD7  31        21
   1     PB1   9         2                16    PC0  16        22
   2     PB2   2         3                17    PC1  17        23
   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

// I use the mighty-1284p pinout from https://maniacbug.wordpress.com/2011/11/27/arduino-on-atmega1284p-4/
                    +---\/---+
          (D 0) PB0 |1     40| PA0 (AI 0 / D24)
          (D 1) PB1 |2     39| PA1 (AI 1 / D25)
     INT2 (D 2) PB2 |3     38| PA2 (AI 2 / D26)
      PWM (D 3) PB3 |4     37| PA3 (AI 3 / D27)
 PWM   SS (D 4) PB4 |5     36| PA4 (AI 4 / D28)
     MOSI (D 5) PB5 |6     35| PA5 (AI 5 / D29)
 PWM MISO (D 6) PB6 |7     34| PA6 (AI 6 / D30)
 PWM  SCK (D 7) PB7 |8     33| PA7 (AI 7 / D31)
                RST |9     32| AREF
                VCC |10    31| GND
                GND |11    30| AVCC
              XTAL2 |12    29| PC7 (D 23)
              XTAL1 |13    28| PC6 (D 22)
      RX0 (D 8) PD0 |14    27| PC5 (D 21) TDI
      TX0 (D 9) PD1 |15    26| PC4 (D 20) TDO
INT0 RX1 (D 10) PD2 |16    25| PC3 (D 19) TMS
INT1 TX1 (D 11) PD3 |17    24| PC2 (D 18) TCK
     PWM (D 12) PD4 |18    23| PC1 (D 17) SDA
     PWM (D 13) PD5 |19    22| PC0 (D 16) SDL
     PWM (D 14) PD6 |20    21| PD7 (D 15) PWM
                    +--------+

ATtiny44/84

See https://github.com/damellis/attiny for the ATtiny support files. The README contains a link to a tutorial. See the examples directory for a sample sketch and a Makefile. NOTE: The sketch has been compile tested ONLY! Bug reports welcome, but I do not have any ATtiny chips at this time.

The following External Interrupt is available on the ATtiny44/84:
ATtiny                  
  Pin*  PORT INT  ATtiny44/84 pin
   8    PB2   0      5  

The following Pin Change Interrupts are available on the ATtiny44/84:
Arduino                                 Arduino
  Pin*  PORT PCINT ATtiny44/84 pin        Pin*  PORT PCINT ATtiny44/84 pin
   0     PA0   0        13                 5    PA5    5         8
   1     PA1   1        12                 6    PA6    6         7
   2     PA2   2        11                 7    PA7    7         6
   3     PA3   3        10                 8    PB2   10         5
   4     PA4   4         9                 9    PB1    9         3
                                          10    PB0    8         2
                                          11    PB3   11         4

The following pin numbering scheme is assumed:

                          +-\/-+
                    VCC  1|    |14  GND
            (D 10)  PB0  2|    |13  PA0  (D  0) == AREF
            (D  9)  PB1  3|    |12  PA1  (D  1)
                    PB3  4|    |11  PA2  (D  2)
 PWM  INT0  (D  8)  PB2  5|    |10  PA3  (D  3)
 PWM        (D  7)  PA7  6|    |9   PA4  (D  4)
 PWM        (D  6)  PA6  7|    |8   PA5  (D  5)        PWM
                          +----+

ATtiny45/85

See https://github.com/damellis/attiny for the ATtiny support files. The README contains a link to a tutorial. See the examples directory for a sample sketch and a Makefile. NOTE: The sketch has been compile tested ONLY! Bug reports welcome, but I do not have any ATtiny chips at this time.

The following External Interrupt is available on the ATtiny45/85:
ATtiny                  
  Pin*  PORT INT  ATtiny45/85 pin
   2    PB2   0      7  

The following Pin Change Interrupts are available on the ATmega45/85:
Arduino(tiny)                          Arduino(tiny)
  Pin*  PORT PCINT ATmega45/85 pin    Pin*  PORT PCINT ATmega45/85 pin
   0     PB0   0        5                  3    PB3   3         2
   1     PB1   1        6                  4    PB4   4         3
   2     PB2   2        7                  5    PB5   5         1


The following pin numbering scheme is assumed:

             +-\/-+
 (D 5) PB5  1|    |8  Vcc
 (D 3) PB3  2|    |7  PB2 (D 2) (INT0)
 (D 4) PB4  3|    |6  PB1 (D 1)
       GND  4|    |5  PB0 (D 0)
             +----+

LICENSE

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