running rpi3 applications that use gpio without being root

When I last wrote about using the Raspberry Pi 3’s GPIO pins, it was with my simple and silly cylon.js application (see “retesting gpio with node.js and onoff with the raspberry pi 3“). Every time I ran that application, or any other application that used the GPIO pins, I had to run as root or use sudo (to run as temporary root):

sudo node cylon.js

That kicked off the application and allowed me to flash those LEDs back and forth.

Turns out that there’s a straightforward way to do all this without root or rootly powers, using the granularity built into Linux. These are the straightforward steps to run GPIO applications as a regular user. Note that I’m using Arch Linux and the account is ‘alarm’. The following changes are made as root (su to root).

  1. As root create a new group called gpio (groupadd -f -r gpio)
  2. As root add the group to the alarm account (usermod -G gpio alarm)
  3. As root create a udev rules file at /dev/gpiomem in /etc/udev/rules.d/99-gpio.rules

The rules to be placed into the 99-gpio.rules file are:

SUBSYSTEM=="bcm2835-gpiomem", KERNEL=="gpiomem", GROUP="gpio", MODE="0660"SUBSYSTEM=="gpio", KERNEL=="gpiochip*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:gpio /sys/class/gpio/export /sys/class/gpio/unexport ; chmod 220 /sys/class/gpio/export /sys/class/gpio/unexport'"SUBSYSTEM=="gpio", KERNEL=="gpio*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:gpio /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/value ; chmod 660 /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/value'"

Once all the group and account changes have been made and the rules have been added, reboot the Raspberry Pi.

The two key features to making this work are (1) the new group, gpio, and (2) the udev rules that allow anyone who is a member of the gpio group to access /dev/gpiomem, where the GPIO pins are individually accessed. With these changes in place I no longer have to run as root or type ‘sudo’ before any application that accesses the pins because the alarm account is now a member of the gpio group.

There may very well be an Arch Linux package that does all this for you automatically, but I haven’t found it yet.

retesting gpio with node.js and onoff with the raspberry pi 3

This is the Cylon test I created for my original personal Raspberry Pi work over two years ago (see testing gpio with node.js and onoff, February 2014) except this time I executed it on the Raspberry Pi 3, not the original Raspberry Pi. In order to make clear what I did to run this from the RPi3 side, here’s what I installed on Arch Linux via pacman:

  • gcc
  • make
  • nodejs
  • npm

I was happy to see that the Arch Linux ARM repositories carried the latest node.js and npm, versions 5.8.0 and 3.8.1 respectively. I used npm to install a local copy of onoff. I needed gcc and make because npm builds part of onoff locally during installation.

This test actually uses the code I posted (and am reposting) back in March 2014. I’m going to use the i2c and port expanders for key input. But for testing the output I use the following simple code:

// cylon.js - JavaScript application to flash four LEDs in// a 'cylon' like fashion from side to side.// Requires node.js and onoffvar Gpio = require('onoff').Gpio,   // Instantiate the onoff.Gpio instance.led1 = new Gpio(17, 'out'), // Export GPIO pin #17 as output.led2 = new Gpio(18, 'out'), // Export GPIO pin #18 as output.led3 = new Gpio(27, 'out'), // Export GPIO pin #27 as output.led4 = new Gpio(22, 'out'), // Export GPIO pin #22 as output.iv1,// Function to be called periodically.shifter = 1,// Bit to shift back and forth.multiplier = 2; // Determines shift direction.// This sets up the periodically called function.// Function is called every 50 milliseconds (see end of setInterval(...)// A single bit is shifted low to high, then high to low, and used via// and AND mask, to either turn the LED on (bit is '1') or turn the LED// off (bit is '0'). This single bit, moving back and forth across four// bits, is used to turn on a single LED, giving the illusion of the LED// moving back and forth, like the Cylon head visor in the original// Battlestar Galactica series (which I personally found more enjoyable// than the reboot).iv1 = setInterval(function() {led1.writeSync(shifter & 1 ? 1 : 0); // 1 = on, 0 = offled2.writeSync(shifter & 2 ? 1 : 0);led3.writeSync(shifter & 4 ? 1 : 0);led4.writeSync(shifter & 8 ? 1 : 0);shifter *= multiplier;if (shifter > 4) multiplier = .5;if (shifter < 2) multiplier = 2;}, 50);// Stop blinking the LEDs and turn them off after 10 seconds.setTimeout(function() {clearInterval(iv1); // Stop blinkingled1.writeSync(0);  // Turn LED off.led1.unexport();// Unexport GPIO and free resourcesled2.writeSync(0);  // Turn LED off.led2.unexport();// Unexport GPIO and free resourcesled3.writeSync(0);  // Turn LED off.led3.unexport();// Unexport GPIO and free resourcesled4.writeSync(0);  // Turn LED off.led4.unexport();// Unexport GPIO and free resources}, 10000);

With node.js and onoff installed type ‘sudo node cylon.js‘ at the prompt to execute.

The reason I’ve gone back to node.js is because the split that occurred nearly two years ago has been healed between the Node group and io.js, the fork. Things are back to a better state.

The video at the top was created using an Olympus E-M5 Elite and an M.Zuiko 12-40mm PRO zoom in manual focus mode, zoomed out to 40mm. The manual focus eliminates the constant and annoying in-and-out automatic refocusing of the first video I took of the Cylon lighting effect. The output was edited with iMovie on my iPad Air 2. Get used to the trippy little background music, as I’ll be using it on other similar technical videos in the future.

This post concludes my breaking-in of the new Raspberry Pi 3. It also is the start of a small break in RPi3 related work as I start heading back to my regular job. The next posts will be a bit more sophisticated and unique from any prior work.