/fastgpio-arduino

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.

Primary LanguageC++MIT LicenseMIT

FastGPIO library for Arduino

www.pololu.com

Summary

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.

Supported platforms

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

Getting started

Software

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:

  1. In the Arduino IDE, open the "Sketch" menu, select "Include Library", then "Manage Libraries...".
  2. Search for "FastGPIO".
  3. Click the FastGPIO entry in the list.
  4. Click "Install".

If this does not work, you can manually install the library:

  1. Download the latest release archive from GitHub and decompress it.
  2. Rename the folder "fastgpio-arduino-xxxx" to "FastGPIO".
  3. 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.
  4. After installing the library, restart the Arduino IDE.

Specifying a pin

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 as A2 and MOSI.
  • By the special IO_NONE macro. Commands operating on the IO_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.

Digital outputs

This example shows how to set pin 13 as an output and drive it high:

FastGPIO::Pin<13>::setOutput(HIGH);

Digital inputs

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();

Pin number reference

Pins for ATmega328PB boards

NumberAVR pin macroAlternative name
0IO_D0
1IO_D1
2IO_D2
3IO_D3
4IO_D4
5IO_D5
6IO_D6
7IO_D7
8IO_B0
9IO_B1
10IO_B2SS
11IO_B3MOSI
12IO_B4MISO
13IO_B5SCK
14IO_C0A0
15IO_C1A1
16IO_C2A2
17IO_C3A3
18IO_C4A4, SDA, SDA0
19IO_C5A5, SCL, SCL0
20IO_E2A6
21IO_E3A7
22IO_E0SDA1
23IO_E1SCL1
24IO_C6

Pins for ATmega328P boards

NumberAVR pin macroAlternative name
0IO_D0
1IO_D1
2IO_D2
3IO_D3
4IO_D4
5IO_D5
6IO_D6
7IO_D7
8IO_B0
9IO_B1
10IO_B2SS
11IO_B3MOSI
12IO_B4MISO
13IO_B5SCK
14IO_C0A0
15IO_C1A1
16IO_C2A2
17IO_C3A3
18IO_C4A4, SDA
19IO_C5A5, SCL
20IO_C6

Pins for ATmega32U4 boards

NumberAVR pin macroAlternative name
0IO_D2
1IO_D3
2IO_D1SDA
3IO_D0SCL
4, 24IO_D4A6
5IO_C6
6, 25IO_D7A7
7IO_E6
8, 26IO_B4A8
9, 27IO_B5A9
10, 28IO_B6A10
11IO_B7
12, 29IO_D6A11
13IO_C7
14IO_B3MISO
15IO_B1SCK
16IO_B2MOSI
17IO_B0SS
18IO_F7A0
19IO_F6A1
20IO_F5A2
21IO_F4A3
22IO_F1A4
23IO_F0A5
30IO_D5
31IO_E2

Speed test

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.

Error messages

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.

Classes

The classes provided by this library are listed below:

  • FastGPIO::Pin
  • FastGPIO::PinLoan

Documentation

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.

Version history

  • 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.