Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@jperkin
Last active October 13, 2023 16:56
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save jperkin/e1f0ce996c83ccf2bca9 to your computer and use it in GitHub Desktop.
Save jperkin/e1f0ce996c83ccf2bca9 to your computer and use it in GitHub Desktop.
Raspberry Pi GPIO Comparison

Comparing node.js GPIO implementations

Here are two simple programs testing the performance of my rpio library against popular alternatives which use the /sys interface (with the number of npm stars indicated for a rough idea of popularity).

rpi-gpio (9 stars)

This test is based on an example on the rpi-gpio page.

As modules which uses /sys depend upon asynchronous behaviour they require callbacks to ensure that the next operation starts only when the previous one has completed.

var gpio = require('rpi-gpio');

var count = 1000000;

gpio.setup(9, gpio.DIR_OUT, on);

function on() {
	if (count-- == 0) {
		gpio.destroy();
		return;
	}
	gpio.write(9, 1, off);
}

function off() {
	gpio.write(9, 0, on);
}

onoff (12 stars)

onoff provides a nice and simple synchronous interface as well as async, with the synchronous interface being faster for simple tests like this.

var Gpio = require('onoff').Gpio,
    led = new Gpio(9, 'out'),
    count = 1000000;

while (count-- != 0) {
        led.writeSync(1);
        led.writeSync(0);
}

wiring-pi (5 stars)

wiring-pi is quite similar to rpio, but uses Gordon Henderson's wiring-pi library for access rather than bcm2835. As such it has comparable simplicity and speed to rpio.

var wpi = require('wiring-pi');

var count = 1000000;

wpi.wiringPiSetupGpio();
wpi.pinMode(9, wpi.OUTPUT);

while (count-- != 0) {
        wpi.digitalWrite(9, 1);
        wpi.digitalWrite(9, 0);
}

rpio

rpio directly calls the underlying hardware thanks to the bcm2835 library, so there is no need for asynchronous handling and callbacks, we can just write directly as fast as possible and ordering is guaranteed to be preserved.

var rpio = require('rpio');

/*
 * Use GPIOxx numbering to match the rpi-gpio example.  rpio defaults to the physical
 * mapping, i.e. P01-P40, as it is simpler and portable across different models.
 *
 * Alternatively, remove the rpio.init() call completely and replace '9' with '21'.
 */
rpio.init({mapping: 'gpio'});
rpio.open(9, rpio.OUTPUT);

for (var i = 0; i < 1000000; i++) {
	rpio.write(9, 1);
	rpio.write(9, 0);
}

In 0.9.0 I added the .writebuf() API call which makes this even faster, by writing the values from a Buffer directly to a pin:

var rpio = require('../lib/rpio');

var buf = new Buffer(1000000);

rpio.init({mapping: 'gpio'});
rpio.open(9, rpio.OUTPUT);

for (var i = 0; i < buf.length; i+=2) {
        buf[i] = 1;
        buf[i+1] = 0;
}

rpio.writebuf(9, buf);

Results

I ran each multiple times and took the fastest run.

  • rpi-gpio
$ time sudo node rpi-gpio.js

real    11m41.023s
user    6m45.430s
sys     6m29.480s
  • onoff
$ time sudo node onoff.js

real    0m11.136s
user    0m5.040s
sys     0m6.090s
  • wiring-pi
$ time sudo node wiring-pi.js

real    0m2.022s
user    0m1.930s
sys     0m0.050s
  • rpio (.write())
$ time sudo node rpio.js

real    0m2.907s
user    0m2.850s
sys     0m0.040s
  • rpio (.writebuf())
$ time sudo node rpio-writebuf.js

real    0m0.684s
user    0m0.660s
sys     0m0.020s
@jonathanscottjames
Copy link

jonathanscottjames commented Mar 23, 2018

hi thanks for doing that test..
i'm not sure what i'm seeing.
i made a simple tester program and the script is easily editable.
i will now try to test to see the difference between rpio and rpi,gpio..
but i wish you would look at my script revise to test rpio and rpi,gpio even thought i still am not done testing.. i wouldn't be uninspired if try to edit used my script
https://github.com/jonathanscottjames/jsj_python-rpi.gpio-cps-speed-test-max-min-avr-16bit-sync-serial-with-sync-pin-for-scope.git
and beat me to it. thanks

@gcurtis79
Copy link

I know this is a tad old, but can you run this on pigpio? It's what I've been using (for the whole week since I've started using python) and I'm wondering how it compares.

@StefansArya
Copy link

Still missing some benchmark like pi-gpio library

@oisteink
Copy link

oisteink commented May 5, 2020

I did pi-gpio comparison using this script on Pi3b+:

const Gpio = require('pigpio').Gpio;

var count = 1000000;
var pin9 = new Gpio(9, Gpio.OUTPUT);

while (count-- != 0) {
        pin9.digitalWrite(1);
        pin9.digitalWrite(0);
}

Result:

real    0m2.212s
user    0m2.116s
sys     0m0.355s

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment