{"id":13410668,"url":"https://github.com/fivdi/onoff","last_synced_at":"2025-05-14T21:06:08.877Z","repository":{"id":5202482,"uuid":"6377918","full_name":"fivdi/onoff","owner":"fivdi","description":"GPIO access and interrupt detection with Node.js","archived":false,"fork":false,"pushed_at":"2024-06-27T02:45:26.000Z","size":937,"stargazers_count":1247,"open_issues_count":8,"forks_count":124,"subscribers_count":39,"default_branch":"master","last_synced_at":"2025-04-18T10:22:17.266Z","etag":null,"topics":["beaglebone","beaglebone-black","gpio","interrupt","iot","javascript","linux","nodejs","raspberry-pi"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"devbridge/BetterCMS","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fivdi.png","metadata":{"files":{"readme":"README.md","changelog":"History.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2012-10-24T21:32:07.000Z","updated_at":"2025-03-26T07:22:36.000Z","dependencies_parsed_at":"2024-10-08T14:45:59.077Z","dependency_job_id":"747baa6c-f363-4908-9a8e-fef0438baf00","html_url":"https://github.com/fivdi/onoff","commit_stats":{"total_commits":368,"total_committers":16,"mean_commits":23.0,"dds":"0.46739130434782605","last_synced_commit":"813da60dd1f3a842a29a8c630243d4f5b7523cc0"},"previous_names":[],"tags_count":59,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fivdi%2Fonoff","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fivdi%2Fonoff/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fivdi%2Fonoff/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fivdi%2Fonoff/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fivdi","download_url":"https://codeload.github.com/fivdi/onoff/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250452293,"owners_count":21432984,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["beaglebone","beaglebone-black","gpio","interrupt","iot","javascript","linux","nodejs","raspberry-pi"],"created_at":"2024-07-30T20:01:08.305Z","updated_at":"2025-05-14T21:06:08.848Z","avatar_url":"https://github.com/fivdi.png","language":"JavaScript","readme":"[![Build Status](https://app.travis-ci.com/fivdi/onoff.svg?branch=master)](https://app.travis-ci.com/github/fivdi/onoff)\n[![codecov](https://codecov.io/gh/fivdi/onoff/branch/master/graph/badge.svg)](https://codecov.io/gh/fivdi/onoff)\n[![npm Version](http://img.shields.io/npm/v/onoff.svg)](https://www.npmjs.com/package/onoff)\n[![Downloads Per Month](http://img.shields.io/npm/dm/onoff.svg)](https://www.npmjs.com/package/onoff)\n[![Mentioned in Awesome Node.js](https://awesome.re/mentioned-badge.svg)](https://github.com/sindresorhus/awesome-nodejs#hardware)\n\n# onoff\n\nGPIO access and interrupt detection with **Node.js** on Linux boards like the\nRaspberry Pi or BeagleBone.\n\nonoff supports Node.js versions 10, 12, 14, 15 and 16.\n\n## Contents\n\n * [Installation](#installation)\n * [Usage](#usage)\n   * [LEDs and Buttons](#leds-and-buttons)\n   * [Debouncing Buttons](#debouncing-buttons)\n   * [Blink an LED Using the Synchronous API](#blink-an-led-using-the-synchronous-api)\n   * [Blink an LED Using the Asynchronous API and Completion Callbacks](#blink-an-led-using-the-asynchronous-api-and-completion-callbacks)\n   * [Blink an LED Using the Asynchronous API and Promises](#blink-an-led-using-the-asynchronous-api-and-promises)\n * [API](#api)\n * [How Does onoff Work?](#how-does-onoff-work)\n * [Configuring Pullup and Pulldown Resistors](#configuring-pullup-and-pulldown-resistors)\n * [Benchmarks](#benchmarks)\n * [Related Packages](#related-packages)\n * [Additional Information](#additional-information)\n\n## Installation\n\n```\nnpm install onoff\n```\n\nNote that although it's possible to install onoff on non-Linux systems the\nfunctionality offered by onoff is only available on Linux systems.\n\n## Usage\n\n#### LEDs and Buttons\nAssume that there's an LED connected to GPIO17 and a momentary push button\nconnected to GPIO4.\n\n\u003cimg src=\"https://raw.githubusercontent.com/fivdi/onoff/master/examples/light-switch.png\"\u003e\n\nWhen the button is pressed the LED should turn on, when it's released the LED\nshould turn off. This can be achieved with the following code:\n\n```js\nconst Gpio = require('onoff').Gpio;\nconst led = new Gpio(17, 'out');\nconst button = new Gpio(4, 'in', 'both');\n\nbutton.watch((err, value) =\u003e led.writeSync(value));\n```\n\nHere two Gpio objects are being created. One called led for the LED connected\nto GPIO17 which is an output, and one called button for the momentary push\nbutton connected to GPIO4 which is an input. In addition to specifying that\nthe button is an input, the constructors optional third argument is used to\nspecify that 'both' rising and falling interrupt edges should be configured\nfor the button GPIO as both button presses and releases should be handled.\n\nAfter everything has been setup correctly, the buttons watch method is used to\nspecify a callback function to execute every time the button is pressed or\nreleased. The value argument passed to the callback function represents the\nstate of the button which will be 1 for pressed and 0 for released. This value\nis used by the callback to turn the LED on or off using its writeSync method.\n\nWhen the above program is running it can be terminated with ctrl-c. However,\nit doesn't free its resources. It also ignores the err argument passed to\nthe callback. Here's a slightly modified variant of the program that handles\nctrl-c gracefully and bails out on error. The resources used by the led and\nbutton Gpio objects are released by invoking their unexport method.\n\n```js\nconst Gpio = require('onoff').Gpio;\nconst led = new Gpio(17, 'out');\nconst button = new Gpio(4, 'in', 'both');\n\nbutton.watch((err, value) =\u003e {\n  if (err) {\n    throw err;\n  }\n\n  led.writeSync(value);\n});\n\nprocess.on('SIGINT', _ =\u003e {\n  led.unexport();\n  button.unexport();\n});\n```\n\n#### Debouncing Buttons\nWhen working with buttons there will often be button bounce issues which\nresult in the hardware thinking that a button was pressed several times\nalthough it was only pressed once. onoff provides a software debouncing\nsolution for resolving bounce issues.\n\nAssume again that there's an LED connected to GPIO17 and a momentary push\nbutton connected to GPIO4.\n\nWhen the button is pressed the LED should toggle its state. This is a typical\nexample of a situation where there will be button bounce issues. The issue can\nbe resolved by using the debounceTimeout option when creating the Gpio object\nfor the button. In the below program the debounceTimeout is set to 10\nmilliseconds. This delays invoking the watch callback for the button while the\nbutton is bouncing. The watch callback will not be invoked until the button\nstops bouncing and has been in a stable state for 10 milliseconds.\n\n```js\nconst Gpio = require('onoff').Gpio;\nconst led = new Gpio(17, 'out');\nconst button = new Gpio(4, 'in', 'rising', {debounceTimeout: 10});\n\nbutton.watch((err, value) =\u003e {\n  if (err) {\n    throw err;\n  }\n\n  led.writeSync(led.readSync() ^ 1);\n});\n\nprocess.on('SIGINT', _ =\u003e {\n  led.unexport();\n  button.unexport();\n});\n```\n\n#### Blink an LED Using the Synchronous API\n\nBlink an LED connected to GPIO17 for 5 seconds using the synchronous readSync\nand writeSync methods.\n\n```js\nconst Gpio = require('../onoff').Gpio; // Gpio class\nconst led = new Gpio(17, 'out');       // Export GPIO17 as an output\n\n// Toggle the state of the LED connected to GPIO17 every 200ms\nconst iv = setInterval(_ =\u003e led.writeSync(led.readSync() ^ 1), 200);\n\n// Stop blinking the LED after 5 seconds\nsetTimeout(_ =\u003e {\n  clearInterval(iv); // Stop blinking\n  led.unexport();    // Unexport GPIO and free resources\n}, 5000);\n```\n\n#### Blink an LED Using the Asynchronous API and Completion Callbacks\n\nBlink an LED connected to GPIO17 for 5 seconds using the asynchronous read and\nwrite methods and completion callbacks.\n\n```js\nconst Gpio = require('../onoff').Gpio; // Gpio class\nconst led = new Gpio(17, 'out');       // Export GPIO17 as an output\nlet stopBlinking = false;\n\n// Toggle the state of the LED connected to GPIO17 every 200ms\nconst blinkLed = _ =\u003e {\n  if (stopBlinking) {\n    return led.unexport();\n  }\n\n  led.read((err, value) =\u003e { // Asynchronous read\n    if (err) {\n      throw err;\n    }\n\n    led.write(value ^ 1, err =\u003e { // Asynchronous write\n      if (err) {\n        throw err;\n      }\n    });\n  });\n\n  setTimeout(blinkLed, 200);\n};\n\nblinkLed();\n\n// Stop blinking the LED after 5 seconds\nsetTimeout(_ =\u003e stopBlinking = true, 5000);\n```\n\n#### Blink an LED Using the Asynchronous API and Promises\n\nBlink an LED connected to GPIO17 for 5 seconds using the asynchronous read and\nwrite methods and Promises.\n\n```js\nconst Gpio = require('../onoff').Gpio; // Gpio class\nconst led = new Gpio(17, 'out');       // Export GPIO17 as an output\nlet stopBlinking = false;\n\n// Toggle the state of the LED connected to GPIO17 every 200ms\nconst blinkLed = _ =\u003e {\n  if (stopBlinking) {\n    return led.unexport();\n  }\n\n  led.read()\n    .then(value =\u003e led.write(value ^ 1))\n    .then(_ =\u003e setTimeout(blinkLed, 200))\n    .catch(err =\u003e console.log(err));\n};\n\nblinkLed();\n\n// Stop blinking the LED after 5 seconds\nsetTimeout(_ =\u003e stopBlinking = true, 5000);\n```\n\n#### Check accessibility\n\nSometimes it may be necessary to determine if the current system supports\nGPIOs programmatically and mock functionality if it doesn't. `Gpio.accessible`\ncan be used to achieve this.\n\n```js\nconst Gpio = require('onoff').Gpio;\n\nconst useLed = (led, value) =\u003e led.writeSync(value);\n\nlet led;\n\nif (Gpio.accessible) {\n  led = new Gpio(17, 'out');\n  // more real code here\n} else {\n  led = {\n    writeSync: value =\u003e {\n      console.log('virtual led now uses value: ' + value);\n    }\n  };\n}\n\nuseLed(led, 1);\n```\n\n## API\n\n### Class Gpio\n\n  * [Gpio(gpio, direction [, edge] [, options]) - Constructor](#gpiogpio-direction--edge--options)\n  * [read([callback]) - Read GPIO value asynchronously](#readcallback)\n  * [readSync() - Read GPIO value synchronously](#readsync)\n  * [write(value[, callback]) - Write GPIO value asynchronously](#writevalue-callback)\n  * [writeSync(value) - Write GPIO value synchronously](#writesyncvalue)\n  * [watch(callback) - Watch for hardware interrupts on the GPIO](#watchcallback)\n  * [unwatch([callback]) - Stop watching for hardware interrupts on the GPIO](#unwatchcallback)\n  * [unwatchAll() - Remove all watchers for the GPIO](#unwatchall)\n  * [direction() - Get GPIO direction](#direction)\n  * [setDirection(direction) - Set GPIO direction](#setdirectiondirection)\n  * [edge() - Get GPIO interrupt generating edge](#edge)\n  * [setEdge(edge) - Set GPIO interrupt generating edge](#setedgeedge)\n  * [activeLow() - Get GPIO activeLow setting](#activelow)\n  * [setActiveLow(invert) - Set GPIO activeLow setting](#setactivelowinvert)\n  * [unexport() - Reverse the effect of exporting the GPIO to userspace](#unexport)\n  * [static accessible - Determine whether or not GPIO access is possible](#static-accessible)\n  * [HIGH / LOW - Constants used when reading or writing a GPIO value](#static-high--low)\n\n##### Gpio(gpio, direction [, edge] [, options])\n- gpio - An unsigned integer specifying the GPIO number.\n- direction - A string specifying whether the GPIO should be configured as an\ninput or output. The valid values are: 'in', 'out', 'high', and 'low'. If 'out'\nis specified the GPIO will be configured as an output and the value of the GPIO\nwill be set to 0. 'high' and 'low' are variants of 'out' that configure the\nGPIO as an output with an initial level of 1 or 0 respectively.\n- [edge] - An optional string specifying the interrupt generating edge or\nedges for an input GPIO. The valid values are: 'none', 'rising', 'falling' or\n'both'. The default value is 'none' indicating that the GPIO will not generate\ninterrupts. Whether or not interrupts are supported by an input GPIO is GPIO\nspecific. If interrupts are not supported by a GPIO the edge argument should\nnot be specified. The edge argument is ignored for output GPIOs.\n- [options] - An optional options object.\n\nConfigures the GPIO based on the passed arguments and returns a new Gpio\nobject that can be used to access the GPIO.\n\nThe following options are supported:\n- debounceTimeout - An unsigned integer specifying a millisecond delay. Delays\ninvoking the watch callback for an interrupt generating input GPIO while the\ninput is bouncing. The watch callback will not be invoked until the input\nstops bouncing and has been in a stable state for debounceTimeout\nmilliseconds. Optional, if unspecified the input GPIO will not be debounced.\n- activeLow - A boolean value specifying whether the values read from or\nwritten to the GPIO should be inverted. The interrupt generating edge for the\nGPIO also follow this this setting. The valid values for activeLow are true\nand false. Setting activeLow to true inverts. Optional, the default value is\nfalse.\n- reconfigureDirection - A boolean value specifying whether the direction for\nthe GPIO should be reconfigured even though the direction is already\nconfigured correctly. When an application starts, the direction of a GPIO used\nby that application may already be configured correctly, for example, from a\nprevious run of the application. Reconfiguring the direction of that GPIO can\nresult in unwanted side effects. For example, if a GPIO is already configured\nas an output and it is reconfigured as an output by passing 'out' to the\nconstructor, the value of that output will be set to 0. In some applications\nthis is not desirable and the value of the output should not be modified. The\nreconfigureDirection option can help here. If reconfigureDirection is set to\nfalse the direction of a GPIO that is already correctly configured will not be\nreconfigured. Optional, the default value is true.\n\nGPIOs on Linux are identified by unsigned integers. These are the numbers that\nshould be passed to the onoff Gpio constructor when exporting GPIOs to\nuserspace. For example, pin 11 on the Raspberry Pi expansion header\ncorresponds to GPIO17 in Raspbian Linux. 17 is therefore the number to pass\nto the onoff Gpio constructor when using pin 11 on the expansion header.\n\n##### read([callback])\n- [callback] - An optional completion callback that gets two arguments (err,\nvalue), where err is reserved for an Error object and value is the number 0\nor 1 and represents the state of the GPIO.\n\nRead GPIO value asynchronously. If no completion callback is specified read\nreturns a Promise which resolves to the value of the GPIO on success or rejects\nwith an Error object on failure.\n\nNote that most systems support readback of GPIOs configured as outputs. The\nread method can therefore be invoked for any GPIO, irrespective of whether it\nwas configured as an input or an output. The Raspberry Pi and BeagleBone are\nexamples of such systems.\n\n##### readSync()\nRead GPIO value synchronously. Returns the number 0 or 1 to represent the\nstate of the GPIO.\n\nNote that most systems support readback of GPIOs configured as outputs. The\nreadSync method can therefore be invoked for any GPIO, irrespective of whether\nit was configured as an input or an output. The Raspberry Pi and BeagleBone\nare examples of such systems.\n\n##### write(value[, callback])\n- value - The number 0 or 1.\n- [callback] - An optional completion callback that gets one argument (err),\nwhere err is reserved for an error object.\n\nWrite GPIO value asynchronously. If no completion callback is specified write\nreturns a Promise that resolves with no value on success or rejects with an\nError object on failure.\n\nNote that on most systems invoking write for a GPIO configured as an input\nwill result in an EPERM error indicating that the operation is not permitted.\nThe Raspberry Pi and BeagleBone are examples of such systems.\n\n##### writeSync(value)\n- value - The number 0 or 1.\n\nWrite GPIO value synchronously.\n\nNote that on most systems invoking writeSync for a GPIO configured as an input\nwill result in an EPERM error indicating that the operation is not permitted.\nThe Raspberry Pi and BeagleBone are examples of such systems.\n\n##### watch(callback)\n- callback - A callback that gets two arguments (err, value), where err is\nreserved for an error object and value is the number 0 or 1 and represents the\nstate of the GPIO. The value can also be used to determine whether the\ninterrupt occurred on a rising or falling edge. A value of 0 implies a falling\nedge interrupt and a value of 1 implies a rising edge interrupt.\n\nWatch for hardware interrupts on the GPIO. The edge argument that was passed\nto the constructor determines which hardware interrupts to watch for.\n\n##### unwatch([callback])\n- [callback] - The callback to remove.\n\nStop watching for hardware interrupts on the GPIO. If callback is specified,\nonly that particular callback is removed. Otherwise all callbacks are removed.\n\n##### unwatchAll()\nRemove all hardware interrupt watchers for the GPIO.\n\n##### direction()\nReturns the string 'in' or 'out' indicating whether the GPIO is an input or\noutput.\n\n##### setDirection(direction)\n- direction - A string specifying whether the GPIO should be configured as an\ninput or output. The valid values are 'in', 'out', 'high', and 'low'. If 'out'\nis specified the GPIO will be configured as an output and the value of the GPIO\nwill be set to 0. 'high' and 'low' are variants of 'out' that configure the\nGPIO as an output with an initial level of 1 or 0 respectively.\n\nSet GPIO direction.\n\n##### edge()\nReturns the string 'none', 'falling', 'rising', or 'both' indicating the\ninterrupt generating edge or edges for the GPIO. Whether or not interrupts are\nsupported by an input GPIO is GPIO specific. If interrupts are not supported\nthe edge method should not be used. Interrupts are not supported by output\nGPIOs.\n\n##### setEdge(edge)\n- edge - A string specifying the interrupt generating edge or edges for an\ninput GPIO. The valid values are: 'none', 'rising', 'falling' or 'both'.\nWhether or not interrupts are supported by an input GPIO is GPIO specific. If\ninterrupts are not supported the setEdge method should not be used. Interrupts\nare not supported by output GPIOs.\n\nSet GPIO interrupt generating edge.\n\n##### activeLow()\nReturns true or false indicating whether or not the values read from or written\nto the GPIO are inverted.\n\n##### setActiveLow(invert)\n- invert - A boolean value specifying whether the values read from or written\nto the GPIO should be inverted. The interrupt generating edge for the GPIO also\nfollow this this setting. The valid values for invert are true and false.\nSetting activeLow to true inverts.\n\nSet GPIO activeLow setting.\n\n##### unexport()\nReverse the effect of exporting the GPIO to userspace. A Gpio object should not\nbe used after invoking its unexport method.\n\n##### static accessible\nDetermine whether or not GPIO access is possible. true if the current process\nhas the permissions required to export GPIOs to userspace. false otherwise.\nLoosely speaking, if this property is true it should be possible for the\ncurrent process to create Gpio objects.\n\nIt is notable that while this property may be false indicating that the\ncurrent process does not have the permissions required to export GPIOs to\nuserspace, existing exported GPIOs may still be accessible.\n\nThis property is useful for mocking functionality on computers used for\ndevelopment that do not provide access to GPIOs.\n\nThis is a static property and should be accessed as `Gpio.accessible`.\n\n##### static HIGH / LOW\nConstants used when reading or writing a GPIO value. Gpio.HIGH and Gpio.LOW\ncan be used in place of the numeric constants 1 and 0.\n\n\n## How Does onoff Work?\n\nInternally onoff uses sysfs files located at /sys/class/gpio to access GPIOs\nand the [epoll package](https://github.com/fivdi/epoll) to detect hardware\ninterrupts. The Linux GPIO sysfs interface for userspace is documented\n[here](https://www.kernel.org/doc/Documentation/gpio/sysfs.txt).\nIt's a relatively simple interface which can be used to ask the Linux kernel\nto export control of a GPIO to userspace. After control of a GPIO has been\nexported to userspace, the GPIO can be configured as an input or output.\nThereafter, the state of an input can be read, and the state of an output can\nbe written. Some systems will also allow the state of a output to be read.\nThe GPIO sysfs interface can also be used for interrupt detection. onoff can\ndetect several thousand interrupts per second on both the BeagleBone and the\nRaspberry Pi.\n\n\n## Configuring Pullup and Pulldown Resistors\n\nAs mentioned in section [How Does onoff Work](#how-does-onoff-work) the sysfs\ninterface is used to access GPIOs. The sysfs interface doesn't offer support\nfor configuring pullup and pulldown resistors on GPIOs.\n\nThere are however many platform specific mechanisms for configuring pullup and\npulldown resistors that are compatible with onoff. onoff itself doesn't use\nthese mechanisms as one of the goals of onoff is to be platform independent.\n\nHere we'll take a look at two mechanisms available on the Raspberry Pi for\nconfiguring pullup and pulldown resistors.\n\nThe first point to be aware of is that most GPIOs on a Raspberry Pi have\neither their pullup or pulldown resistor activated by default. The defaults\ncan be seen in Table 6-31 on pages 102 and 103 of the\n[BCM2835 ARM Peripherals](http://www.farnell.com/datasheets/1521578.pdf)\ndocumentation.\n\n#### Using the gpio Command in /boot/config.txt \n\nOn Raspbian 2018-04-18 or later the `gpio` configuration command can be used\nin `/boot/config.txt` to configure pullup and pulldown resistors. Further\ninformation is available at\n[New \"gpio\" config command](https://www.raspberrypi.org/forums/viewtopic.php?f=117\u0026t=208748).\n\n#### Using Device Tree Overlays\n\nDevice tree overlays can also be used to configure pullup and pulldown\nresistors. The Wiki page\n[Enabling Pullup and Pulldown Resistors on The Raspberry Pi](https://github.com/fivdi/onoff/wiki/Enabling-Pullup-and-Pulldown-Resistors-on-The-Raspberry-Pi)\ndescribes this mechanism in more detail.\n\n## Benchmarks\n\nThree of the onoff tests are used to monitor performance.\n\n  * performance-async.js - determine max. no. of write ops per seconds\n  * performance-sync.js - determine max. no. of writeSync ops per second\n  * performance-interrupt.js - determine max. no. of interrupts per second\n\nThe results of these tests are shown in the following tables.\n\n**Raspberry Pi 4 B, 1.5GHz, Raspberry Pi OS (March 4th 2021, Buster 10.8)**\n\nnode | onoff | kernel | write / sec | writeSync / sec | interrupts / sec\n:---: | :---: | :---: | ---: | ---: | ---:\nv16.0.0 | v6.0.3 | 5.10.17-v7l+ | 25124 | 280417 | 20240\nv15.14.0 | v6.0.3 | 5.10.17-v7l+ | 24055 | 271149 | 20488\nv14.16.1 | v6.0.3 | 5.10.17-v7l+ | 21669 | 254705 | 19703\nv12.22.1 | v6.0.3 | 5.10.17-v7l+ | 22618 | 318417 | 21122\nv10.24.1 | v6.0.3 | 5.10.17-v7l+ | 22405 | 329927 | 19583\n\n**Raspberry Pi 3 B, 1.2GHz, Raspbian Buster 10.1**\n\nnode | onoff | kernel | write / sec | writeSync / sec | interrupts / sec\n:---: | :---: | :---: | ---: | ---: | ---:\nv12.14.0 | v5.0.0 | 4.19.75-v7l+ | 21670 | 207222 | 18328\nv10.18.0 | v5.0.0 | 4.19.75-v7l+ | 23661 | 225758 | 20741\n\n**Raspberry Pi 2 B, 900MHz, Raspbian Buster 10.1**\n\nnode | onoff | kernel | write / sec | writeSync / sec | interrupts / sec\n:---: | :---: | :---: | ---: | ---: | ---:\nv12.14.0 | v5.0.0 | 4.19.75-v7l+ | 10769 | 113107 | 10373\nv10.18.0 | v5.0.0 | 4.19.75-v7l+ | 11843 | 129086 | 10536\n\n**Raspberry Pi 1 B, 700MHz, Raspbian Buster 10.1**\n\nnode | onoff | kernel | write / sec | writeSync / sec | interrupts / sec\n:---: | :---: | :---: | ---: | ---: | ---:\nv12.14.0 | v5.0.0 | 4.19.75+ | 2316 | 26696 | 2112\nv10.18.0 | v5.0.0 | 4.19.75+ | 2613 | 33129 | 2225\n\n**BeagleBone Black, 1GHz, Debian Buster 10.2**\n\nnode | onoff | kernel | write / sec | writeSync / sec | interrupts / sec\n:---: | :---: | :---: | ---: | ---: | ---:\nv12.14.0 | v5.0.0 | 4.19.79-ti-r30 | 6855 | 70535 | 5911\nv10.18.0 | v5.0.0 | 4.19.79-ti-r30 | 7564 | 79133 | 5920\n\n**BeagleBone, 720MHz, Debian Buster 10.2**\n\nnode | onoff | kernel | write / sec | writeSync / sec | interrupts / sec\n:---: | :---: | :---: | ---: | ---: | ---:\nv12.14.0 | v5.0.0 | 4.19.79-ti-r30 | 5013 | 49741 | 4297\nv10.18.0 | v5.0.0 | 4.19.79-ti-r30 | 5400 | 57157 | 4371\n\n## Related Packages\n\nHere are a few links to other hardware specific Node.js packages that may be\nof interest.\n\n  * [pigpio](https://github.com/fivdi/pigpio) - Fast GPIO, PWM, servo control, state change notification and interrupt handling on the Raspberry Pi\n  * [i2c-bus](https://github.com/fivdi/i2c-bus) - I2C serial bus access\n  * [spi-device](https://github.com/fivdi/spi-device) - SPI serial bus access\n  * [mcp-spi-adc](https://github.com/fivdi/mcp-spi-adc) - Analog to digital conversion with the MCP3002/4/8, MCP3202/4/8 and MCP3304\n\n## Additional Information\n\nonoff was tested on the following platforms:\n\n- Raspberry Pi 1, 2, 3 and 4\n  - Raspbian or Raspberry Pi OS\n- BeagleBone, BeagleBone Black and PocketBeagle\n  - Debian\n\nThe suitability of onoff for a particular Linux board is highly dependent on\nhow GPIO interfaces are made available on that board. The\n[GPIO interfaces](https://www.kernel.org/doc/Documentation/gpio/)\ndocumentation describes GPIO access conventions rather than standards that must\nbe followed so GPIO can vary from platform to platform. For example, onoff\nrelies on sysfs files located at /sys/class/gpio being available. However,\nthese sysfs files for userspace GPIO are optional and may not be available on a\nparticular platform.\n\n","funding_links":[],"categories":["Packages","Repository","包","目录","JavaScript","Hardware"],"sub_categories":["Hardware","硬件"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffivdi%2Fonoff","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffivdi%2Fonoff","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffivdi%2Fonoff/lists"}