This is a C++ library for the Arduino IDE that allows you to manipulate general-purpose I/O (GPIO) pins on your Arduino or Arduino-compatible board with minimal overhead. Many function calls to this library will be inlined and compiled down to just one or two assembly instructions.
This library is intended to be a replacement for the default Arduino I/O functions (pinMode
, digitalWrite
, and digitalRead
) and has several advantages over them:
- The compiled code runs faster.
- Operates only on the specific bits used by the pin instead of doing read-write-modify operations on entire registers.
- Never disables interrupts.
- Supports reading and restoring the state of a pin, which is useful if the pin is used for multiple purposes.
- Pins can be specified either by their AVR pin name or their Arduino pin name.
To use this library, you will need a basic understanding of microcontroller I/O pins. General information on this topic can be found in the Arduino Digital Pins tutorial.
Currently, this library requires that the pin number you specify must be known at compile time. This means the pin number cannot come from a variable that might change and it cannot be the result of a complicated calculation. This allows the compiler to generate optimal code for manipulating that pin.
The Arduino GPIO functions automatically turn off a pin's PWM function when accessing it with digitalRead
or digitalWrite
. This library does not have that feature.
This library is designed to work with the Arduino IDE versions 1.0.x, 1.5.x, 1.6.x, and later, and will probably not work with earlier versions.
This library currently supports any board based on these AVRs:
- ATmega48PB, ATmega88PB, ATmega168PB, ATmega328PB
- ATmega48, ATmega48P, ATmega88, ATmega88P, ATmega168, ATmega168P, ATmega328, ATmega328P
- ATmega16U4, ATmega32U4
If you are using version 1.6.2 or later of the Arduino software (IDE), you can use the Library Manager to install this library:
- In the Arduino IDE, open the "Sketch" menu, select "Include Library", then "Manage Libraries...".
- Search for "FastGPIO".
- Click the FastGPIO entry in the list.
- Click "Install".
If this does not work, you can manually install the library:
- Download the latest release archive from GitHub and decompress it.
- Rename the folder "fastgpio-arduino-xxxx" to "FastGPIO".
- Drag the "FastGPIO" folder into the "libraries" directory inside your Arduino sketchbook directory. You can view your sketchbook location by opening the "File" menu and selecting "Preferences" in the Arduino IDE. If there is not already a "libraries" folder in that location, you should make the folder yourself.
- After installing the library, restart the Arduino IDE.
There are three ways to specify a pin:
- By its pin number
- By its AVR pin name, using the
IO_*
macros that this library provides. For example,IO_D3
refers to pin PD3. - By alternative names defined in the Arduino IDE's
pins_arduino.h
header, such asA2
andMOSI
. - By the special
IO_NONE
macro. Commands operating on theIO_NONE
pin will have no effect.
Any pin number that works with the standard Arduino I/O functions will work with the FastGPIO library.
For a full list of all the supported pins, see the "Pin number reference" section below.
This example shows how to set pin 13 as an output and drive it high:
FastGPIO::Pin<13>::setOutput(HIGH);
To configure a pin as a digital input with the internal pull-up resistor disabled, run:
FastGPIO::Pin<12>::setInput();
To configure a pin as a digital input with the internal pull-up resistor enabled, run:
FastGPIO::Pin<12>::setInputPulledUp();
Then, to read the value of the input, you can use:
bool inputHigh = FastGPIO::Pin<12>::isInputHigh();
Number | AVR pin macro | Alternative name |
---|---|---|
0 | IO_D0 | |
1 | IO_D1 | |
2 | IO_D2 | |
3 | IO_D3 | |
4 | IO_D4 | |
5 | IO_D5 | |
6 | IO_D6 | |
7 | IO_D7 | |
8 | IO_B0 | |
9 | IO_B1 | |
10 | IO_B2 | SS |
11 | IO_B3 | MOSI |
12 | IO_B4 | MISO |
13 | IO_B5 | SCK |
14 | IO_C0 | A0 |
15 | IO_C1 | A1 |
16 | IO_C2 | A2 |
17 | IO_C3 | A3 |
18 | IO_C4 | A4, SDA, SDA0 |
19 | IO_C5 | A5, SCL, SCL0 |
20 | IO_E2 | A6 |
21 | IO_E3 | A7 |
22 | IO_E0 | SDA1 |
23 | IO_E1 | SCL1 |
24 | IO_C6 |
Number | AVR pin macro | Alternative name |
---|---|---|
0 | IO_D0 | |
1 | IO_D1 | |
2 | IO_D2 | |
3 | IO_D3 | |
4 | IO_D4 | |
5 | IO_D5 | |
6 | IO_D6 | |
7 | IO_D7 | |
8 | IO_B0 | |
9 | IO_B1 | |
10 | IO_B2 | SS |
11 | IO_B3 | MOSI |
12 | IO_B4 | MISO |
13 | IO_B5 | SCK |
14 | IO_C0 | A0 |
15 | IO_C1 | A1 |
16 | IO_C2 | A2 |
17 | IO_C3 | A3 |
18 | IO_C4 | A4, SDA |
19 | IO_C5 | A5, SCL |
20 | IO_C6 |
Number | AVR pin macro | Alternative name |
---|---|---|
0 | IO_D2 | |
1 | IO_D3 | |
2 | IO_D1 | SDA |
3 | IO_D0 | SCL |
4, 24 | IO_D4 | A6 |
5 | IO_C6 | |
6, 25 | IO_D7 | A7 |
7 | IO_E6 | |
8, 26 | IO_B4 | A8 |
9, 27 | IO_B5 | A9 |
10, 28 | IO_B6 | A10 |
11 | IO_B7 | |
12, 29 | IO_D6 | A11 |
13 | IO_C7 | |
14 | IO_B3 | MISO |
15 | IO_B1 | SCK |
16 | IO_B2 | MOSI |
17 | IO_B0 | SS |
18 | IO_F7 | A0 |
19 | IO_F6 | A1 |
20 | IO_F5 | A2 |
21 | IO_F4 | A3 |
22 | IO_F1 | A4 |
23 | IO_F0 | A5 |
30 | IO_D5 | |
31 | IO_E2 |
We compiled the following code with the Arduino IDE 1.5.8 and ran it on an ATmega32U4 running at 16 MHz:
#include <FastGPIO.h>
#include <util/delay.h>
void setup() {
FastGPIO::Pin<A1>::setOutputLow();
}
void loop() {
FastGPIO::Pin<A1>::setOutputValueHigh();
FastGPIO::Pin<A1>::setOutputValueLow();
_delay_us(10);
digitalWrite(A1, HIGH);
digitalWrite(A1, LOW);
_delay_us(10);
}
The pulses generated by the FastGPIO calls were 0.125 μs long because each call was compiled to just a single assembly instruction, while the pulses generated by digitalWrite
were 5.1 μs long.
If you specify an invalid pin number, GCC will produce error messages like this:
warning: array subscript is above array bounds
warning: asm operand 0 probably doesn't match constraints
error: impossible constraint in 'asm'
This is because the pin number is checked at compile time and must be valid.
The classes provided by this library are listed below:
- FastGPIO::Pin
- FastGPIO::PinLoan
For complete documentation, see https://pololu.github.io/fastgpio-arduino. If you are already on that page, then click on the links in the "Classes" section above.
- 2.2.0 (2023-08-28): Added support for some chips with the same pinout as already-supported chips: ATmega48PB, ATmega88PB, ATmega168PB, ATmega48, ATmega48P, ATmega88, ATmega88P, ATmega16U4.
- 2.1.0 (2018-02-27): Added support for the ATmega328PB.
- 2.0.0 (2016-08-19): Updated library to work with the Arduino Library Manager.
- 1.0.2 (2015-03-16): Improved the speed of toggling a pin's output value.
- 1.0.1 (2015-01-06): Introduced some casts to fix compiler warnings.
- 1.0.0 (2014-12-11): Original release.