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.2 to 0.3.3

example/query-pin.js

5

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

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

"dependencies": {
"async": "~0.8.0"
"async": "~0.8.0",
"debug": "~0.8.1"
}
}

308

rpi-gpio.js

@@ -1,17 +0,10 @@

var fs = require('fs');
var util = require('util');
var fs = require('fs');
var util = require('util');
var EventEmitter = require('events').EventEmitter;
var async = require('async');
var async = require('async');
var debug = require('debug')('rpi-gpio');
var PATH = '/sys/class/gpio';
// Constructor
function Gpio() {
EventEmitter.call(this);
this.reset();
}
util.inherits(Gpio, EventEmitter);
var pins = {
current: undefined,
v1: {

@@ -75,144 +68,165 @@ '1': null,

// Constants
Gpio.prototype.DIR_IN = 'in';
Gpio.prototype.DIR_OUT = 'out';
Gpio.prototype.MODE_RPI = 'mode_rpi';
Gpio.prototype.MODE_BCM = 'mode_bcm';
function Gpio() {
var currentPins;
var exportedPins = {};
var getPinForCurrentMode = getPinRpi;
/**
* Set pin reference mode. Defaults to 'mode_rpi'.
*
* @param {string} mode Pin reference mode, 'mode_rpi' or 'mode_bcm'
*/
Gpio.prototype.setMode = function(mode) {
if (mode === this.MODE_RPI) {
getPinForCurrentMode = getPinRpi;
} else if (mode === this.MODE_BCM) {
getPinForCurrentMode = getPinBcm;
} else {
throw new Error('Cannot set invalid mode');
}
this.DIR_IN = 'in';
this.DIR_OUT = 'out';
this.MODE_RPI = 'mode_rpi';
this.MODE_BCM = 'mode_bcm';
this.emit('modeChange', mode);
};
/**
* Set pin reference mode. Defaults to 'mode_rpi'.
*
* @param {string} mode Pin reference mode, 'mode_rpi' or 'mode_bcm'
*/
this.setMode = function(mode) {
if (mode === this.MODE_RPI) {
getPinForCurrentMode = getPinRpi;
} else if (mode === this.MODE_BCM) {
getPinForCurrentMode = getPinBcm;
} else {
throw new Error('Cannot set invalid mode');
}
/**
* Setup a channel for use as an input or output
*
* @param {number} channel Reference to the pin in the current mode's schema
* @param {string} direction The pin direction, either 'in' or 'out'
* @param {function} cb Optional callback
*/
Gpio.prototype.setup = function(channel, direction, cb /*err*/) {
if (!channel) {
return cb(new Error('Channel not specified'));
}
this.emit('modeChange', mode);
};
direction = direction || this.DIR_OUT;
/**
* Setup a channel for use as an input or output
*
* @param {number} channel Reference to the pin in the current mode's schema
* @param {string} direction The pin direction, either 'in' or 'out'
* @param {function} cb Optional callback
*/
this.setup = function(channel, direction, cb /*err*/) {
if (!channel) {
return process.nextTick(function() {
cb(new Error('Channel not specified'));
});
}
if (typeof direction === 'function') {
cb = direction;
direction = this.DIR_OUT;
}
direction = direction || this.DIR_OUT;
if (direction !== this.DIR_IN && direction !== this.DIR_OUT) {
return cb(new Error('Cannot set invalid direction'));
}
if (typeof direction === 'function') {
cb = direction;
direction = this.DIR_OUT;
}
var pin;
async.waterfall([
function(next) {
setRaspberryVersion(next);
},
function(next) {
pin = getPinForCurrentMode(channel);
isExported(pin, next);
},
function(isExported, next) {
if (isExported) {
return unexportPin(pin, next);
}
return next(null);
},
function(next) {
exportPin(pin, next);
},
function(next) {
this.exportedPins[pin] = true;
this.emit('export', channel);
createListener.call(this, channel, pin);
setDirection(pin, direction, next);
}.bind(this)
], cb);
};
if (direction !== this.DIR_IN && direction !== this.DIR_OUT) {
return process.nextTick(function() {
cb(new Error('Cannot set invalid direction'));
});
}
/**
* Write a value to a channel
*
* @param {number} channel The channel to write to
* @param {boolean} value If true, turns the channel on, else turns off
* @param {function} cb Optional callback
*/
Gpio.prototype.write = function(channel, value, cb /*err*/ ) {
var pin = getPinForCurrentMode(channel);
if (!this.exportedPins[pin]) {
return cb(new Error('Pin has not been exported'));
}
var pin;
async.waterfall([
function(next) {
setRaspberryVersion(currentPins, function(err, pinSchema) {
if (err) next(err);
currentPins = pinSchema;
next();
});
},
function(next) {
pin = getPinForCurrentMode(currentPins, channel);
debug('set up pin %d', pin);
isExported(pin, next);
},
function(isExported, next) {
if (isExported) {
return unexportPin(pin, next);
}
return next(null);
},
function(next) {
exportPin(pin, next);
},
function(next) {
exportedPins[pin] = true;
this.emit('export', channel);
createListener.call(this, channel, pin);
setDirection(pin, direction, next);
}.bind(this)
], cb);
};
value = (!!value && value !== '0') ? '1' : '0';
fs.writeFile(PATH + '/gpio' + pin + '/value', value, cb || function () {});
};
Gpio.prototype.output = Gpio.prototype.write;
/**
* Write a value to a channel
*
* @param {number} channel The channel to write to
* @param {boolean} value If true, turns the channel on, else turns off
* @param {function} cb Optional callback
*/
this.write = this.output = function(channel, value, cb /*err*/ ) {
var pin = getPinForCurrentMode(currentPins, channel);
/**
* Read a value from a channel
*
* @param {number} channel The channel to read from
* @param {function} cb Callback which receives the channel's boolean value
*/
Gpio.prototype.read = function(channel, cb /*err,value*/) {
var pin = getPinForCurrentMode(channel);
if (!exportedPins[pin]) {
return process.nextTick(function() {
cb(new Error('Pin has not been exported'));
});
}
if (!this.exportedPins[pin]) {
return cb(new Error('Pin has not been exported'));
}
value = (!!value && value !== '0') ? '1' : '0';
fs.writeFile(PATH + '/gpio' + pin + '/value', value, cb || function () {});
};
fs.readFile(PATH + '/gpio' + pin + '/value', 'utf-8', function(err, data) {
data = (data + '').trim() || '0';
return cb(err, data === '1');
});
};
Gpio.prototype.input = Gpio.prototype.read;
/**
* Read a value from a channel
*
* @param {number} channel The channel to read from
* @param {function} cb Callback which receives the channel's boolean value
*/
this.read = this.input = function(channel, cb /*err,value*/) {
var pin = getPinForCurrentMode(currentPins, channel);
/**
* Unexport any pins setup by this module
*
* @param {function} cb Optional callback
*/
Gpio.prototype.destroy = function(cb) {
var tasks = Object.keys(this.exportedPins).map(function(pin) {
return function(done) {
unexportPin(pin, done);
if (!exportedPins[pin]) {
return process.nextTick(function() {
cb(new Error('Pin has not been exported'));
});
}
});
async.parallel(tasks, cb);
};
/**
* Reset the state of the module
*/
Gpio.prototype.reset = function() {
this.exportedPins = {};
this.removeAllListeners();
fs.readFile(PATH + '/gpio' + pin + '/value', 'utf-8', function(err, data) {
data = (data + '').trim() || '0';
return cb(err, data === '1');
});
};
pins.current = undefined;
getPinForCurrentMode = getPinRpi;
};
/**
* Unexport any pins setup by this module
*
* @param {function} cb Optional callback
*/
this.destroy = function(cb) {
var tasks = Object.keys(exportedPins).map(function(pin) {
return function(done) {
unexportPin(pin, done);
}
});
async.parallel(tasks, cb);
};
/**
* Sets the version of the model
*/
function setRaspberryVersion(cb) {
if (pins.current) {
/**
* Reset the state of the module
*/
this.reset = function() {
exportedPins = {};
this.removeAllListeners();
currentPins = undefined;
exportedPins = {};
getPinForCurrentMode = getPinRpi;
};
// Init
EventEmitter.call(this);
this.reset();
}
util.inherits(Gpio, EventEmitter);
function setRaspberryVersion(currentPins, cb) {
if (currentPins) {
return cb(null);

@@ -227,19 +241,19 @@ }

var revisionNumber = parseInt(match[1], 16);
var pinVersion = (revisionNumber < 4) ? 'v1' : 'v2';
if (revisionNumber < 3) {
pins.current = pins.v1;
} else {
pins.current = pins.v2;
}
debug(
'seen hardware revision %d; using pin mode %s',
revisionNumber,
pinVersion
);
return cb(null);
return cb(null, pins[pinVersion]);
});
};
var getPinForCurrentMode = getPinRpi;
function getPinRpi(channel) {
return pins.current[channel] + '';
function getPinRpi(currentPins, channel) {
return currentPins[channel] + '';
};
function getPinBcm(channel) {
function getPinBcm(currentPins, channel) {
return channel + '';

@@ -249,2 +263,3 @@ };

function createListener(channel, pin) {
debug('listen for pin %d', pin);
var self = this;

@@ -260,2 +275,3 @@ fs.watchFile(PATH + '/gpio' + pin + '/value', function() {

function setDirection(pin, direction, cb) {
debug('set direction %s on pin %d', direction.toUpperCase(), pin);
fs.writeFile(PATH + '/gpio' + pin + '/direction', direction, function(err) {

@@ -267,2 +283,3 @@ if (cb) return cb(err);

function exportPin(pin, cb) {
debug('export pin %d', pin);
fs.writeFile(PATH + '/export', pin, function(err) {

@@ -274,2 +291,3 @@ if (cb) return cb(err);

function unexportPin(pin, cb) {
debug('unexport pin %d', pin);
fs.unwatchFile(PATH + '/gpio' + pin + '/value');

@@ -276,0 +294,0 @@ fs.writeFile(PATH + '/unexport', pin, function(err) {

@@ -10,6 +10,7 @@ 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 : 0002\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 : 100000002\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 : 000e\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 : 10000003\nSerial : 000000009a5d9c22'
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'
}

@@ -563,2 +564,44 @@

context('using Raspberry Pi latest revision 2 hardware', function() {
beforeEach(function() {
fs.readFile.withArgs('/proc/cpuinfo').yieldsAsync(null, cpuinfo.v2latest);
});
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);
});
});
});
});
context('using Raspberry Pi revision 1 hardware overvolted', function() {

@@ -565,0 +608,0 @@ beforeEach(function() {

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