Baike.dev
All toolsOnline toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
O

onoff

> 编程语言
Open source

GPIO access and interrupt detection with Node.js

1.3K stars0 likes2 views
WebsiteGitHub

About

GPIO access and interrupt detection with Node.js

onoff

GPIO access and interrupt detection with Node.js on Linux boards like the Raspberry Pi or BeagleBone.

onoff supports Node.js versions 10, 12, 14, 15 and 16.

Contents

  • Installation
  • Usage
    • LEDs and Buttons
    • Debouncing Buttons
    • Blink an LED Using the Synchronous API
    • Blink an LED Using the Asynchronous API and Completion Callbacks
    • Blink an LED Using the Asynchronous API and Promises
  • API
  • How Does onoff Work?
  • Configuring Pullup and Pulldown Resistors
  • Benchmarks
  • Related Packages
  • Additional Information

Installation

bash
npm install onoff

Note that although it's possible to install onoff on non-Linux systems the functionality offered by onoff is only available on Linux systems.

Usage

LEDs and Buttons

Assume that there's an LED connected to GPIO17 and a momentary push button connected to GPIO4.

When the button is pressed the LED should turn on, when it's released the LED should turn off. This can be achieved with the following code:

javascript
const Gpio = require('onoff').Gpio;
const led = new Gpio(17, 'out');
const button = new Gpio(4, 'in', 'both');

button.watch((err, value) => led.writeSync(value));

Here two Gpio objects are being created. One called led for the LED connected to GPIO17 which is an output, and one called button for the momentary push button connected to GPIO4 which is an input. In addition to specifying that the button is an input, the constructors optional third argument is used to specify that 'both' rising and falling interrupt edges should be configured for the button GPIO as both button presses and releases should be handled.

After everything has been setup correctly, the buttons watch method is used to specify a callback function to execute every time the button is pressed or released. The value argument passed to the callback function represents the state of the button which will be 1 for pressed and 0 for released. This value is used by the callback to turn the LED on or off using its writeSync method.

When the above program is running it can be terminated with ctrl-c. However, it doesn't free its resources. It also ignores the err argument passed to the callback. Here's a slightly modified variant of the program that handles ctrl-c gracefully and bails out on error. The resources used by the led and button Gpio objects are released by invoking their unexport method.

javascript
const Gpio = require('onoff').Gpio;
const led = new Gpio(17, 'out');
const button = new Gpio(4, 'in', 'both');

button.watch((err, value) => {
  if (err) {
    throw err;
  }

  led.writeSync(value);
});

process.on('SIGINT', _ => {
  led.unexport();
  button.unexport();
});

Debouncing Buttons

When working with buttons there will often be button bounce issues which result in the hardware thinking that a button was pressed several times although it was only pressed once. onoff provides a software debouncing solution for resolving bounce issues.

Assume again that there's an LED connected to GPIO17 and a momentary push button connected to GPIO4.

When the button is pressed the LED should toggle its state. This is a typical example of a situation where there will be button bounce issues. The issue can be resolved by using the debounceTimeout option when creating the Gpio object for the button. In the below program the debounceTimeout is set to 10 milliseconds. This delays invoking the watch callback for the button while the button is bouncing. The watch callback will not be invoked until the button stops bouncing and has been in a stable state for 10 milliseconds.

javascript
const Gpio = require('onoff').Gpio;
const led = new Gpio(17, 'out');
const button = new Gpio(4, 'in', 'rising', {debounceTimeout: 10});

button.watch((err, value) => {
  if (err) {
    throw err;
  }

  led.writeSync(led.readSync() ^ 1);
});

process.on('SIGINT', _ => {
  led.unexport();
  button.unexport();
});

Blink an LED Using the Synchronous API

Blink an LED connected to GPIO17 for 5 seconds using the synchronous readSync and writeSync methods.

javascript
const Gpio = require('../onoff').Gpio; // Gpio class
const led = new Gpio(17, 'out');       // Export GPIO17 as an output

// Toggle the state of the LED connected to GPIO17 every 200ms
const iv = setInterval(_ => led.writeSync(led.readSync() ^ 1), 200);

// Stop blinking the LED after 5 seconds
setTimeout(_ => {
  clearInterval(iv); // Stop blinking
  led.unexport();    // Unexport GPIO and free resources
}, 5000);

Blink an LED Using the Asynchronous API and Completion Callbacks

Blink an LED connected to GPIO17 for 5 seconds using the asynchronous read and write methods and completion callbacks.

…

Blink an LED Using the Asynchronous API and Promises

Blink an LED connected to GPIO17 for 5 seconds using the asynchronous read and write methods and Promises.

javascript
const Gpio = require('../onoff').Gpio; // Gpio class
const led = new Gpio(17, 'out');       // Export GPIO17 as an output
let stopBlinking = false;

// Toggle the state of the LED connected to GPIO17 every 200ms
const blinkLed = _ => {
  if (stopBlinking) {
    return led.unexport();
  }

  led.read()
    .then(value => led.write(value ^ 1))
    .then(_ => setTimeout(blinkLed, 200))
    .catch(err => console.log(err));
};

blinkLed();

// Stop blinking the LED after 5 seconds
setTimeout(_ => stopBlinking = true, 5000);

Check accessibility

Sometimes it may be necessary to determine if the current system supports GPIOs programmatically and mock functionality if it doesn't. Gpio.accessible can be used to achieve this.

javascript
const Gpio = require('onoff').Gpio;

const useLed = (led, value) => led.writeSync(value);

let led;

if (Gpio.accessible) {
  led = new Gpio(17, 'out');
  // more real code here
} else {
  led = {
    writeSync: value => {
      console.log('virtual led now uses value: ' + value);
    }
  };
}

useLed(led, 1);

API

Class Gpio

  • Gpio(gpio, direction [, edge] [, options]) - Constructor
  • read([callback]) - Read GPIO value asynchronously
  • readSync() - Read GPIO value synchronously
  • write(value[, callback]) - Write GPIO value asynchronously
  • writeSync(value) - Write GPIO value synchronously
  • watch(callback) - Watch for hardware interrupts on the GPIO
  • unwatch([callback]) - Stop watching for hardware interrupts on the GPIO
  • unwatchAll() - Remove all watchers for the GPIO
  • direction() - Get GPIO direction
  • setDirection(direction) - Set GPIO direction
  • edge() - Get GPIO interrupt generating edge
  • setEdge(edge) - Set GPIO interrupt generating edge
  • activeLow() - Get GPIO activeLow setting
  • setActiveLow(invert) - Set GPIO activeLow setting
  • unexport() - Reverse the effect of exporting the GPIO to userspace
  • static accessible - Determine whether or not GPIO access is possible
  • HIGH / LOW - Constants used when reading or writing a GPIO value
Gpio(gpio, direction [, edge] [, options])
  • gpio - An unsigned integer specifying the GPIO number.
  • direction - A string specifying whether the GPIO should be configured as an input or output. The valid values are: 'in', 'out', 'high', and 'low'. If 'out' is specified the GPIO will be configured as an output and the value of the GPIO will be set to 0. 'high' and 'low' are variants of 'out' that configure the GPIO as an output with an initial level of 1 or 0 respectively.
  • [edge] - An optional string specifying the interrupt generating edge or edges for an input GPIO. The valid values are: 'none', 'rising', 'falling' or 'both'. The default value is 'none' indicating that the GPIO will not generate interrupts. Whether or not interrupts are supported by an input GPIO is GPIO specific. If interrupts are not supported by a GPIO the edge argument should not be specified. The edge argument is ignored for output GPIOs.
  • [options] - An optional options object.

Configures the GPIO based on the passed arguments and returns a new Gpio object that can be used to access the GPIO.

The following options are supported:

  • debounceTimeout - An unsigned integer specifying a millisecond delay. Delays invoking the watch callback for an interrupt generating input GPIO while the input is bouncing. The watch callback will not be invoked until the input stops bouncing and has been in a stable state for debounceTimeout milliseconds. Optional, if unspecified the input GPIO will not be debounced.
  • activeLow - A boolean value specifying whether the values read from or written to the GPIO should be inverted. The interrupt generating edge for the GPIO also follow this this setting. The valid values for activeLow are true and false. Setting activeLow to true inverts. Optional, the default value is false.
  • reconfigureDirection - A boolean value specifying whether the direction for the GPIO should be reconfigured even though the direction is already configured correctly. When an application starts, the direction of a GPIO used by that application may already be configured correctly, for example, from a previous run of the application. Reconfiguring the direction of that GPIO can result in unwanted side effects. For example, if a GPIO is already configured as an output and it is reconfigured as an output by passing 'out' to the constructor, the value of that output will be set to 0. In some applications this is not desirable and the value of the output should not be modified. The reconfigureDirection option can help here. If reconfigureDirection is set to false the direction of a GPIO that is already correctly configured will not be reconfigured. Optional, the default value is true.

GPIOs on Linux are identified by unsigned integers. These are the numbers that should be passed to the onoff Gpio constructor when exporting GPIOs to userspace. For example, pin 11 on the Raspberry Pi expansion header corresponds to GPIO17 in Raspbian Linux. 17 is therefore the number to pass to the onoff Gpio constructor when using pin 11 on the expansion header.

read([callback])
  • [callback] - An optional completion callback that gets two arguments (err, value), where err is reserved for an Error object and value is the number 0 or 1 and represents the state of the GPIO.

Read GPIO value asynchronously. If no completion callback is specified read returns a Promise which resolves to the value of the GPIO on success or rejects with an Error object on failure.

Note that most systems support readback of GPIOs configured as outputs. The read method can therefore be invoked for any GPIO, irrespective of whether it was configured as an input or an output. The Raspberry Pi and BeagleBone are examples of such systems.

readSync()

Read GPIO value synchronously. Returns the number 0 or 1 to represent the state of the GPIO.

Note that most systems support readback of GPIOs configured as outputs. The readSync method can therefore be invoked for any GPIO, irrespective of whether it was configured as an input or an output. The Raspberry Pi and BeagleBone are examples of such systems.

write(value[, callback])
  • value - The number 0 or 1.
  • [callback] - An optional completion callback that gets one argument (err), where err is reserved for an error object.

Write GPIO value asynchronously. If no completi

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

JavaScriptbeaglebonebeaglebone-blackgpiointerrupt

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言