UNPKG

rpio2

Version:

Control Raspberry Pi GPIO pins with node.js. Fast and easy to use.

226 lines (202 loc) 5.17 kB
'use strict'; const rpio = require('rpio'), util = require('util'), EventEmitter = require('events').EventEmitter; function updateEdge(gpio, type){ var changes = gpio.listeners('change').length, risings = gpio.listeners('rising').length, fallings = gpio.listeners('falling').length; var edge = gpio.edge; function triggerEvent(pin){ gpio.emit('change', gpio, pin); if(gpio.value) gpio.emit('rising', gpio, pin); else gpio.emit('falling', gpio, pin); } if(type === 'change'){ changes ++; }else if(type === 'rising'){ risings ++; }else if(type === 'falling'){ fallings ++; } if(changes > 0 || risings > 0 && fallings > 0){ if(edge !== rpio.POLL_BOTH){ gpio.edge = rpio.POLL_BOTH; if(edge !== rpio.POLL_NONE){ rpio.poll(gpio.pin, null); } rpio.poll(gpio.pin, triggerEvent, rpio.POLL_BOTH); } }else if(risings > 0){ if(edge !== rpio.POLL_HIGH){ gpio.edge = rpio.POLL_HIGH; if(edge !== rpio.POLL_NONE){ rpio.poll(gpio.pin, null); } rpio.poll(gpio.pin, triggerEvent, rpio.POLL_HIGH); } }else if(fallings > 0){ if(edge !== rpio.POLL_LOW){ gpio.edge = rpio.POLL_LOW; if(edge !== rpio.POLL_NONE){ rpio.poll(gpio.pin, null); } rpio.poll(gpio.pin, triggerEvent, rpio.POLL_LOW); } }else{ if(edge !== rpio.POLL_NONE){ rpio.poll(gpio.pin, null); } gpio.edge = rpio.POLL_NONE; } } function Gpio(pin, activeLow){ this.pin = pin; this.edge = rpio.POLL_NONE; this.activeLow = !!activeLow; this.on('removeListener', function(type){ updateEdge(this); }); this.on('newListener', function(type){ updateEdge(this, type); }); //private properties var mode = -1; Object.defineProperty(this, '_mode', { get: function(){ return mode; }, set: function(value){ mode = value; }, enumerable: false }); //input state POLL_HIGH POLL_ROW resistors var state = -1; Object.defineProperty(this, '_state', { get: function(){ return state; }, set: function(value){ state = value; }, enumerable: false }); } util.inherits(Gpio, EventEmitter); Gpio.init = rpio.init; require('./gpio_util.js').defineStaticProperties(Gpio); Object.assign(Gpio.prototype, { open: function(mode, value){ this._mode = mode; if(mode === rpio.INPUT && value !== undefined){ this._state = value; } if(mode === rpio.OUTPUT){ return rpio.open(this.pin, mode, this.activeLow ^ value); }else{ return rpio.open(this.pin, mode, value); } }, close: function(){ this.removeAllListeners(); this._mode = this._state = -1; return rpio.close(this.pin); }, read: function(length){ if(length === undefined){ return this.value; }else{ var buf = new Buffer(length); rpio.readbuf(this.pin, buf, length); if(this.activeLow){ for(var i = 0; i < buf.length; i++){ buf[i] ^= 1; } } return buf; } }, write: function(buf, length){ var self = this; function writeData(){ if(self.activeLow){ var newBuf = new Buffer(length || buf.length); for(var i = 0; i < newBuf.length; i++){ newBuf[i] = 1 ^ buf[i]; } return rpio.writebuf(self.pin, newBuf, length); }else{ return rpio.writebuf(self.pin, buf, length); } } if(length === undefined && buf === 0 || buf === 1){ //gpio.write(1) this.value = buf; return; }else if(typeof buf === 'string'){ //gpio.write('1010101') buf = new Buffer(buf.trim().split('').map(function(i){return 0|i})); return writeData(); }else if(typeof buf === 'number'){ //gpio.write(0b10101010); return this.write(buf.toString(2), length); }else if(buf instanceof Buffer){ if(buf[0] !== 0 && buf[0] !== 1){ //Buffer<'0','1','0','1'...> return this.write(buf.toString(), length); }else{ //Buffer<00,01,00,01...> return writeData(); } } }, sleep: function(ms, async){ if(!async){ return rpio.msleep(ms); } return new Promise(function(resolve){ setTimeout(resolve, ms); }); }, toggle: function(){ this.value ^= 1; return this.value; } }); Object.defineProperty(Gpio.prototype, 'value', { get: function(){ return this.activeLow ^ rpio.read(this.pin); }, set: function(value){ rpio.write(this.pin, this.activeLow ^ value); } }); Object.defineProperty(Gpio.prototype, 'mode', { get: function(){ return this._mode; }, set: function(mode){ this._mode = mode; rpio.mode(this.pin, mode); } }); Object.defineProperty(Gpio.prototype, 'state', { get: function(){ if(this.mode === Gpio.INPUT){ return this._state; }else{ return this.value; } }, set: function(state){ if(this.mode === Gpio.INPUT){ this._state = state; rpio.pud(this.pin, state); }else{ this.value = state; } } }); module.exports = Gpio;