Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

rpi-gpio

Package Overview
Dependencies
Maintainers
1
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

rpi-gpio - npm Package Compare versions

Comparing version 0.3.4 to 0.4.0

2

package.json
{
"name": "rpi-gpio",
"version": "0.3.4",
"version": "0.4.0",
"description": "Control Raspberry Pi GPIO pins with node.js",

@@ -5,0 +5,0 @@ "main": "rpi-gpio.js",

rpi-gpio.js
==========
Control Raspberry Pi GPIO pins with node.js

@@ -11,5 +10,5 @@

## Setup
See this guide on how to get [node.js running on Raspberry Pi](http://elsmorian.com/post/23474168753/node-js-on-raspberry-pi).
See this guide on how to get [node.js running on Raspberry Pi](http://joshondesign.com/2013/10/23/noderpi).
This module can be installed with npm:
This module can then be installed with npm:
```js

@@ -20,8 +19,48 @@ npm install rpi-gpio

## Usage
Please see the examples below. Make make sure you are running as root or with sudo, else the Raspberry Pi will not let you output to the GPIO. All of the functions relating to the pins within this module are asynchronous, so where necessary - for example in reading the value of a pin - a callback must be provided.
Firstly, make make sure you are running your application as root or with sudo, else the Raspberry Pi will not let you output to the GPIO.
Please note that there are two different ways to reference a channel; either using the Raspberry Pi or the BCM/SoC naming schema (sadly, neither of which match the physical pins!). This module supports both schemas, with Raspberry Pi being the default. Please see [this page](http://elinux.org/RPi_Low-level_peripherals) for more details.
Before you can read or write, you must use setup() to open a channel, and must specify whether it will be used for input or output. Having done this, you can then read in the state of the channel or write a value to it using read() or write().
All of the functions relating to the pin state within this module are asynchronous, so where necessary - for example in reading the value of a channel - a callback must be provided. This module inherits the standard [EventEmitter](http://nodejs.org/api/events.html), so you may use its functions to listen to events.
### Query the value of a pin
Please note that there are two different and confusing ways to reference a channel; either using the Raspberry Pi or the BCM/SoC naming schema (sadly, neither of which match the physical pins!). This module supports both schemas, with Raspberry Pi being the default. Please see [this page](http://elinux.org/RPi_Low-level_peripherals) for more details.
## API
### setup(channel [, direction], callback)
Sets up a channel for read or write. Must be done before the channel can be used.
* channel: Reference to the pin in the current mode's schema.
* direction: The pin direction, pass either DIR_IN for read mode or DIR_OUT for write mode. Defaults to DIR_OUT.
* callback: Provides Error as the first argument if an error occured.
### read(channel, callback)
Reads the value of a channel.
* channel: Reference to the pin in the current mode's schema.
* callback: Provides Error as the first argument if an error occured, otherwise the pin value boolean as the second argument.
### write(channel, value [, callback])
Writes the value of a channel.
* channel: Reference to the pin in the current mode's schema.
* value: Boolean value to specify whether the channel will turn on or off.
* callback: Provides Error as the first argument if an error occured.
### setMode(mode)
Sets the channel addressing schema.
* mode: Specify either Raspberry Pi or SoC/BCM pin schemas, by passing MODE_RPI or MODE_BCM. Defaults to MODE_RPI.
### input()
Alias of read().
### output()
Alias of write().
### destroy()
Tears down any previously set up channels.
### reset()
Tears down the module state - used for testing.
## Examples
### Setup and read the value of a pin
```js

@@ -39,17 +78,6 @@ var gpio = require('rpi-gpio');

### Listen for changes on a pin
The GPIO module inherits from `EventEmitter` so any of the [EventEmitter functions](http://nodejs.org/api/events.html) can be used. The example below shows how to listen for a change in value to a channel.
### Setup and write to a pin
```js
var gpio = require('rpi-gpio');
gpio.on('change', function(channel, value) {
console.log('Channel ' + channel + ' value is now ' + value);
});
gpio.setup(7, gpio.DIR_IN);
```
### Write to a pin
```js
var gpio = require('rpi-gpio');
gpio.setup(7, gpio.DIR_OUT, write);

@@ -65,5 +93,14 @@

### Unexport pins when finished
This will close any pins that were opened by the module.
### Listen for changes on a pin
```js
var gpio = require('rpi-gpio');
gpio.on('change', function(channel, value) {
console.log('Channel ' + channel + ' value is now ' + value);
});
gpio.setup(7, gpio.DIR_IN);
```
### Unexport pins opened by the module when finished
```js
var gpio = require('../rpi-gpio');

@@ -97,6 +134,6 @@

var pin = 7,
delay = 2000,
count = 0,
max = 3;
var pin = 7;
var delay = 2000;
var count = 0;
var max = 3;

@@ -103,0 +140,0 @@ gpio.on('change', function(channel, value) {

@@ -69,3 +69,4 @@ var fs = require('fs');

var currentPins;
var exportedPins = {};
var exportedInputPins = {};
var exportedOutputPins = {};
var getPinForCurrentMode = getPinRpi;

@@ -149,5 +150,11 @@

function(next) {
exportedPins[pinForSetup] = true;
this.emit('export', channel);
createListener.call(this, channel, pinForSetup);
if (direction === this.DIR_IN) {
exportedInputPins[pinForSetup] = true;
} else {
exportedOutputPins[pinForSetup] = true;
}
setDirection(pinForSetup, direction, next);

@@ -168,5 +175,12 @@ }.bind(this)

if (!exportedPins[pin]) {
if (!exportedOutputPins[pin]) {
var message;
if (exportedInputPins[pin]) {
message = 'Pin has been exported for input so cannot be written to';
} else {
message = 'Pin has not been exported';
}
return process.nextTick(function() {
cb(new Error('Pin has not been exported'));
cb(new Error(message));
});

@@ -188,3 +202,3 @@ }

if (!exportedPins[pin]) {
if (!exportedInputPins[pin]) {
return process.nextTick(function() {

@@ -207,7 +221,10 @@ cb(new Error('Pin has not been exported'));

this.destroy = function(cb) {
var tasks = Object.keys(exportedPins).map(function(pin) {
return function(done) {
unexportPin(pin, done);
}
});
var tasks = Object.keys(exportedOutputPins)
.concat(Object.keys(exportedInputPins))
.map(function(pin) {
return function(done) {
unexportPin(pin, done);
}
});
async.parallel(tasks, cb);

@@ -220,7 +237,7 @@ };

this.reset = function() {
exportedPins = {};
exportedOutputPins = {};
exportedInputPins = {};
this.removeAllListeners();
currentPins = undefined;
exportedPins = {};
getPinForCurrentMode = getPinRpi;

@@ -271,3 +288,3 @@ };

Gpio.read(channel, function(err, value) {
if (err) return cb(err);
// @todo how should error be handled here?
Gpio.emit('change', channel, value);

@@ -274,0 +291,0 @@ });

@@ -9,8 +9,5 @@ var assert = require('assert');

var cpuinfo = {
v1: 'Processor : ARMv6-compatible processor rev 7 (v6l)\nBogoMIPS : 697.95\nFeatures : swp half thumb fastmult vfp edsp java tls\nCPU implementer : 0x41\nCPU architecture: 7\nCPU variant : 0x0\nCPU part : 0xb76\nCPU revision : 7\n\n\nHardware : BCM2708\nRevision : 0003\nSerial : 000000009a5d9c22',
v1Overvolted: 'Processor : ARMv6-compatible processor rev 7 (v6l)\nBogoMIPS : 697.95\nFeatures : swp half thumb fastmult vfp edsp java tls\nCPU implementer : 0x41\nCPU architecture: 7\nCPU variant : 0x0\nCPU part : 0xb76\nCPU revision : 7\n\n\nHardware : BCM2708\nRevision : 100000003\nSerial : 000000009a5d9c22',
v2: 'Processor : ARMv6-compatible processor rev 7 (v6l)\nBogoMIPS : 697.95\nFeatures : swp half thumb fastmult vfp edsp java tls\nCPU implementer : 0x41\nCPU architecture: 7\nCPU variant : 0x0\nCPU part : 0xb76\nCPU revision : 7\n\n\nHardware : BCM2708\nRevision : 0004\nSerial : 000000009a5d9c22',
v2Overvolted: 'Processor : ARMv6-compatible processor rev 7 (v6l)\nBogoMIPS : 697.95\nFeatures : swp half thumb fastmult vfp edsp java tls\nCPU implementer : 0x41\nCPU architecture: 7\nCPU variant : 0x0\nCPU part : 0xb76\nCPU revision : 7\n\n\nHardware : BCM2708\nRevision : 10000004\nSerial : 000000009a5d9c22',
v2latest: 'Processor : ARMv6-compatible processor rev 7 (v6l)\nBogoMIPS : 697.95\nFeatures : swp half thumb fastmult vfp edsp java tls\nCPU implementer : 0x41\nCPU architecture: 7\nCPU variant : 0x0\nCPU part : 0xb76\nCPU revision : 7\n\n\nHardware : BCM2708\nRevision : 000f\nSerial : 000000009a5d9c22'
function getCpuInfo(revision) {
revision = revision || '0002';
return 'Processor : ARMv6-compatible processor rev 7 (v6l)\nBogoMIPS : 697.95\nFeatures : swp half thumb fastmult vfp edsp java tls\nCPU implementer : 0x41\nCPU architecture: 7\nCPU variant : 0x0\nCPU part : 0xb76\nCPU revision : 7\n\n\nHardware : BCM2708\nRevision : ' + revision + '\nSerial : 000000009a5d9c22';
}

@@ -25,3 +22,3 @@

sinon.stub(fs, 'readFile')
.withArgs('/proc/cpuinfo').yieldsAsync(null, cpuinfo.v1);
.withArgs('/proc/cpuinfo').yieldsAsync(null, getCpuInfo());
sinon.spy(fs, 'unwatchFile');

@@ -332,2 +329,27 @@ });

context('when pin 1 has been setup for input', function() {
var onSetup;
var onWrite;
beforeEach(function(done) {
onSetup = sinon.spy(done);
gpio.setup(1, gpio.DIR_IN, onSetup);
});
context('and pin 1 is written to with boolean true', function() {
beforeEach(function(done) {
var callback = function() {
done();
}
onWrite = sinon.spy(callback);
gpio.write(1, true, onWrite);
});
it('should run the callback with an error', function() {
sinon.assert.calledOnce(onWrite);
assert.ok(onWrite.getCall(0).args[0]);
});
});
});
});

@@ -337,3 +359,3 @@

context('when pin 1 is setup', function() {
context('when pin 1 is setup for input', function() {
beforeEach(function(done) {

@@ -478,3 +500,3 @@ gpio.setup(1, gpio.DIR_IN, done);

describe('pin translation', function() {
describe('handles pin translation', function() {

@@ -486,8 +508,22 @@ context('when in RPI mode', function() {

context('using Raspberry Pi revision 1 hardware', function() {
beforeEach(function() {
fs.readFile.withArgs('/proc/cpuinfo').yieldsAsync(null, cpuinfo.v1);
});
var revisionMap = {
'0002': 'v1',
'0003': 'v1',
'0004': 'v2',
'0005': 'v2',
'0006': 'v2',
'0007': 'v2',
'0008': 'v2',
'0009': 'v2',
'000d': 'v2',
'000e': 'v2',
'000f': 'v2',
// Over-volted hardware
'10000003': 'v1',
'10000004': 'v2',
'1000000f': 'v2'
};
var map = {
var map = {
v1: {
// RPI to BCM

@@ -511,25 +547,4 @@ '3': '0',

'26': '7'
}
Object.keys(map).forEach(function(rpiPin) {
var bcmPin = map[rpiPin];
context('writing to RPI pin ' + rpiPin, function() {
beforeEach(function(done) {
gpio.setup(rpiPin, gpio.DIR_IN, done);
});
it('should write to pin ' + bcmPin + ' (BCM)', function() {
assert.equal(fs.writeFile.getCall(0).args[1], bcmPin);
});
});
});
});
context('using Raspberry Pi revision 2 hardware', function() {
beforeEach(function() {
fs.readFile.withArgs('/proc/cpuinfo').yieldsAsync(null, cpuinfo.v2);
});
var map = {
},
v2: {
// RPI to BCM

@@ -554,142 +569,30 @@ '3': '2',

}
};
Object.keys(map).forEach(function(rpiPin) {
var bcmPin = map[rpiPin];
Object.keys(revisionMap).forEach(function(revision) {
var revisionSchema = revisionMap[revision];
var pinMap = map[revisionSchema];
context('writing to RPI pin ' + rpiPin, function() {
beforeEach(function(done) {
gpio.setup(rpiPin, gpio.DIR_IN, done);
});
it('should write to pin ' + bcmPin + ' (BCM)', function() {
assert.equal(fs.writeFile.getCall(0).args[1], bcmPin);
});
context('and hardware revision is: ' + revision, function() {
beforeEach(function() {
fs.readFile.withArgs('/proc/cpuinfo').yieldsAsync(null, getCpuInfo(revision));
});
});
});
context('using Raspberry Pi latest revision 2 hardware', function() {
beforeEach(function() {
fs.readFile.withArgs('/proc/cpuinfo').yieldsAsync(null, cpuinfo.v2latest);
});
Object.keys(pinMap).forEach(function(rpiPin) {
var bcmPin = pinMap[rpiPin];
var map = {
// RPI to BCM
'3': '2',
'5': '3',
'7': '4',
'8': '14',
'10': '15',
'11': '17',
'12': '18',
'13': '27',
'15': '22',
'16': '23',
'18': '24',
'19': '10',
'21': '9',
'22': '25',
'23': '11',
'24': '8',
'26': '7'
}
context('writing to RPI pin ' + rpiPin, function() {
beforeEach(function(done) {
gpio.setup(rpiPin, gpio.DIR_IN, done);
});
Object.keys(map).forEach(function(rpiPin) {
var bcmPin = map[rpiPin];
context('writing to RPI pin ' + rpiPin, function() {
beforeEach(function(done) {
gpio.setup(rpiPin, gpio.DIR_IN, done);
it('should write to pin ' + bcmPin + ' (BCM)', function() {
assert.equal(fs.writeFile.getCall(0).args[1], bcmPin);
});
});
it('should write to pin ' + bcmPin + ' (BCM)', function() {
assert.equal(fs.writeFile.getCall(0).args[1], bcmPin);
});
});
});
});
context('using Raspberry Pi revision 1 hardware overvolted', function() {
beforeEach(function() {
fs.readFile.withArgs('/proc/cpuinfo').yieldsAsync(null, cpuinfo.v1Overvolted);
});
var map = {
// RPI to BCM
'3': '0',
'5': '1',
'7': '4',
'8': '14',
'10': '15',
'11': '17',
'12': '18',
'13': '21',
'15': '22',
'16': '23',
'18': '24',
'19': '10',
'21': '9',
'22': '25',
'23': '11',
'24': '8',
'26': '7'
}
Object.keys(map).forEach(function(rpiPin) {
var bcmPin = map[rpiPin];
context('writing to RPI pin ' + rpiPin, function() {
beforeEach(function(done) {
gpio.setup(rpiPin, gpio.DIR_IN, done);
});
it('should write to pin ' + bcmPin + ' (BCM)', function() {
assert.equal(fs.writeFile.getCall(0).args[1], bcmPin);
});
});
});
});
context('using Raspberry Pi revision 2 hardware overvolted', function() {
beforeEach(function() {
fs.readFile.withArgs('/proc/cpuinfo').yieldsAsync(null, cpuinfo.v2Overvolted);
});
var map = {
// RPI to BCM
'3': '2',
'5': '3',
'7': '4',
'8': '14',
'10': '15',
'11': '17',
'12': '18',
'13': '27',
'15': '22',
'16': '23',
'18': '24',
'19': '10',
'21': '9',
'22': '25',
'23': '11',
'24': '8',
'26': '7'
}
Object.keys(map).forEach(function(rpiPin) {
var bcmPin = map[rpiPin];
context('writing to RPI pin ' + rpiPin, function() {
beforeEach(function(done) {
gpio.setup(rpiPin, gpio.DIR_IN, done);
});
it('should write to pin ' + bcmPin + ' (BCM)', function() {
assert.equal(fs.writeFile.getCall(0).args[1], bcmPin);
});
});
});
});
});

@@ -696,0 +599,0 @@

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc