Sign Up for Free

RunKit +

Try any Node.js package right in your browser

This is a playground to test code. It runs a full Node.js environment and already has all of npm’s 400,000 packages pre-installed, including array-gpio with all npm packages installed. Try it out:

var arrayGpio = require("array-gpio")

This service is provided by RunKit and is not affiliated with npm, Inc or the package authors.

array-gpio v1.1.34

A node.js GPIO control for rapid prototyping and development using a simple modern API.

array-gpio

A node.js GPIO control for rapid prototyping and development using a simple modern API.

Compatibility

  • Raspberry Pi Models: A, B (revisions 1.0 and 2.0), A+, B+, 2, 3, Zero.
  • Node.js Versions: 5.x, 6.x, 7.x

Installation

$ npm install array-gpio

Quick Start

Creating an individual input/output object

circuit setup: Two momentary switch buttons connected to pin 11 and 13 and one led connected to pin 33.

Using a shared common main function for pin event detection.

const GPIO = require('array-gpio');

let sw1 = GPIO.setInput(11); 
let sw2 = GPIO.setInput(13);
let led = GPIO.setOutput(33);

/*
* By default, the main event function 
* will listen to all input pin events.
*/
GPIO.main = () => {
  /* turn ON led */    
  if(sw1.isOn){
    led.on();
  }
  /* turn OFF led */ 
  else if(sw2.isOn){
    led.off();
  }
};

Using local event for each input pin.

const GPIO = require('array-gpio');

let sw1 = GPIO.Input(11); 
let sw2 = GPIO.Input(13);
let led = GPIO.Output(33);

/* turn ON led */  
sw1.event(1, () => led.on());

/* turn OFF led */ 
sw2.event(1, () => led.off());

Creating an input/output array object

circuit setup: Two momentary switch buttons connected to pin 11 and 13 and six led's connected to pin 33, 35, 37, 36, 38 and 40.

/* r for raspberry */
const r = require('array-gpio');

let input = r.input(11,13);
let output = r.output(33,35,37,36,38,40);

/* turn ON led's sequentially */
function LedOn(){
  let t = 50;
  for (let x in output){
    t += 50;
    output[x].on(t); 
  }
}
/* turn OFF led's sequentially */
function LedOff(){
  let t = 50;
  for (let x in output){
    t += 50;
    output[x].off(t);
  }
}

r.main = function (){
  if(input[0].isOn){
    LedOn();
  }
  else if(input[1].isOn){
    LedOff();
  }
};

API

setInput(pin1, pin2, ... , pinN [,event, edge, intR])

input object constructor

Set a GPIO pin or group of GPIO pins as input object.

Choose your pin based on the physical pin number (P01-P40).

Returns an input object or an array object if more than one pin is used.

For array object, each pin will be assigned or indexed consecutively as element of the returned array object.

You can set as many input pins as you can. You are only limited by how much GPIO pins are available on your Raspberry Pi.

This is a synchronous function.

Aside from setInput() method syntax, below are also valid syntax for input object setup.

###Input (...)

###input (...)

###in (...)

All of the above will have the same result as setInput().


Using drop-in options

setInput(pin1, pin2, ... , pinN [,event][,edge][,intR])

event

true - All input objects will use main as event listener (default setup).

The main event function is a common callback function shared by all input objects.

It must be defined using the following pattern.

const GPIO = require('array-gpio');

let inputObject = GPIO.Input( ...);
let outputObject = GPIO.Output( ... );

/* main event function */
GPIO.main = function (){
  /* I/O expression or any JavaScript expression */ 
}; 

If event option is not provided, implicitly it is the same as true.

GPIO.setInput(11, 13, 15, 19, true);
// same as above   
GPIO.setInput(11, 13, 15, 19);

false - All inputs will not listen to main event function.

Your application will exit immediately. This is handy for testing some I/O logical expressions. Or you need to define a local event function for each input object ( see event() section ).

// application will exit immediately
GPIO.setInput(11, 13, 15, 19, false);

edge

're' - Enable rising edge (high transition) event detection.

GPIO.setInput(11, 13, 15, 19, 're');

'fe' - Enable falling edge (low transition) event detection.

GPIO.setInput(11, 13, 15, 19, 'fe');

If edge option is not provided, both rising and falling edge detection will be used.

GPIO.setInput(11, 13, 15, 19);

intR

'pu' - Enable PULL UP resistor for all input objects.

GPIO.setInput(11, 13, 15, 19, false, 'pu');

'pd' - Enable PULL DOWN resistor for all input objects.

GPIO.setInput(11, 13, 15, 19, 'pd');

If intR option is not provided, no internal resistor will be used.

GPIO.setInput(11, 13, 15, 19);

There is no order of precedence for drop-in options.

// below all will have the same effect
// using main event, rising edge detection and using pull-up for all inputs

GPIO.setInput(11, 13, 15, 19, true, 're', 'pu');
// or 
GPIO.setInput(11, 13, 15, 19, 're', 'pu', true);
// or
GPIO.setInput(11, 13, 15, 19, 'pu', true, 're');
// or
GPIO.setInput(11, 13, 15, 19, 'pu', 're');

Using object literal as option

setInput(pin1, pin2, ... , pinN [, option])

var option = {event:value, edge:value, intR:value};

event : true or false

edge : 're'||'fe' or 1||0

intR : 'pu'||'pd' or 1||0

Example

var options = {event: true, edge: 're', intR: 'pu'};
// or
var options = {event: true, edge: 1, intR: 1};

var input = GPIO.setInput(11, 13, 15, options );

// dropping the event property is the same as true
var input = GPIO.setInput(11, 13, 15, {edge: 're', intR: 'pu'});

// dropping the edge property, both rising and falling edge will be used
var input = GPIO.setInput(11, 13, 15, {intR: 'pu'});

// dropping the intR property, no internal resistor will be used
var input = GPIO.setInput(11, 13, 15, {edge: 're'});

/* no options provided */ 
// will use main event
// both rising and falling edge will be used
// no internal resistor will be used
var input = GPIO.setInput(11, 13, 15);

Using object literal as a single argument

setInput(arg)

This is similar to using object literal option but with the additional pin array property as container for input pins.

Example

var arg = {pin: [11, 13, 15], event: true, edge: 'fe', intR: 'pd'};
// or 
var arg = {pin: [11, 13, 15], event: true, edge: 0, intR: 0};

var input = GPIO.setInput(arg);

state

input/output property

Get or read the current logical condition of any input/output object at any given point in your application during runtime.

Returns true if the object is in high or ON state condition.

Otherwise returns false for low or OFF state condition.

Example

if(input[0].state && led[1].state === false){

  console.log(input[0].state); // true
  console.log(led[1].state); // false

  led[1].on();

  console.log(input[0].state); // true
  console.log(led[1].state); // true
}

isOn and isOff

input/output property

Similar to state property but with explicit context.

isOn returns true if state is true, otherwise it returns false.

isOff returns true if state is false, otherwise it returns false.

isOff is the negative logic of isOn.

isOff becomes handy when using falling edge input detection or negative logic expression.

Instead of using the conditional statement if(sensor.state === false), you can just use if(sensor.isOff).

Using assert module, we can better understand its behavior.

const assert = require ('assert');
const GPIO = require('array-gpio');

let input = GPIO.Input(11);
let output = GPIO.Output(33);

// whatever is the state condition of input and output object
// the following will always apply 

assert.strictEqual(input.state, input.isOn); // ok
assert.strictEqual(output.state, output.isOn); // ok

assert.notStrictEqual(input.isOn, input.isOff); // ok
assert.notStrictEqual(output.isOn, output.isOff); // ok

assert.notStrictEqual(input.state, input.isOff); // ok
assert.notStrictEqual(output.state, output.isOff); // ok

Example

const GPIO = require('array-gpio');
 
let sw = GPIO.Input(11, 13, 15, 're');
let led = GPIO.Output(33);
 
GPIO.main = () => {
  // turns on led if sw[0] is ON and if led is OFF 
  if(sw[0].isOn && led.isOff){ 
    led.on();
  }
  // turns off led if sw[1] is ON and if led is ON 
  if(sw[1].isOn && led.isOn){
    led.off();
  }
};

read([callback])

or

rd( ... )

input/output method

The traditional way of getting the current state of any input/output object.

Returns 1 for ON or high state and 0 for OFF or low state.

callback function will be executed asynchronously if provided.

/* r for raspberry */
const r = require('array-gpio');

let sw = r.input(11);
let solenoid = r.output(35);

sw.event(function(){
  let status = sw.read(() => {
    if(status === 1)
      solenoid.on(50);
    else
      solenoid.off();  
  }); 
});

event(edge, callback)

input method

Enable an input object to use a local event listener for its pin event detection.

Similar to main event, you can enable rising or falling edge detection or both.

edge

're' or 1 - Enable rising edge (high transition) event detection.

'fe' or 0 - Enable falling edge (low transition) event detection.

// enable rising edge detection
input[0].event('re', callback);
// or
input[0].event(1, callback);

// Enable falling edge detection
input[0].event('fe', callback);
// or
input[0].event(0, callback);

If edge parameter is not provided, both rising and falling edge detection will be used.

// enable both rising and falling edge detection
input[0].event(callback);

callback function will be executed asynchronously when input events are detected.

Example 1

const GPIO = require('array-gpio');

let sw = GPIO.Input(11, 13);
let led = GPIO.Output(33, 35);

// sw[0] will use a local event for pin event detection 
sw[0].event(function(){
  if(sw[0].state){
    console.log('sw[0] is listening to a local event');
    if(led[0].isOff){
      led[0].on();
    }
    if(led[1].isOn){
      led[1].off();
    }
  }
});

// sw[1] will still use the main event for event detection 
GPIO.main = function () {
  if(sw[1].state){
    console.log('sw[1] is listening to main event');
    if(led[0].isOn){
      led[0].off();
    }
    if(led[1].isOff){
      led[1].on();
    }
  }
};

Example 2

const GPIO = require('array-gpio');

let sw = GPIO.Input(11, 13, false);
let led = GPIO.Output(33, 35);

// this time, both sw[0] and sw[1] will use its own local event
// there is no need to define a main event function

sw[0].event(function(){
  // detects only high state and ignores low state
  if(sw[0].state){
    console.log('sw[0] is listening to a local event using anynomous function');
    if(led[0].isOff){
      led[0].on();
    }
    if(led[1].isOn){
      led[1].off();
    }
  }
});

function sw1Event(){
    console.log('sw[1] is listening to a local event using sw1Event callback');
    if(led[0].isOn){
      led[0].off();
    }
    if(led[1].isOff){
      led[1].on();
    }
}

sw[1].event(1, sw1Event);

clearEvent()

input method

Input stops listening to any input events (local or main event).

const r = require('array-gpio');

/* using one button switch */
let sw = r.input(11);

sw.event(1, function(){
  console.log("I'm only a one-time event");
  sw.clearEvent();
});

Using clearEvent() to debounce a switch.

const r = require('array-gpio');

let sw1 = r.input(11);
let sw2 = r.input(13);
let led = r.output(33);

/* debouncing sw1 only */

function OnEvent(){
  console.log('led is ON'); 
  led.on();
  sw1.clearEvent();
}

/* ON switch */
sw1.event(1, OnEvent);

/* OFF switch */
sw2.event(1, function(){
  led.off()
  sw1.event(1, OnEvent);
});

main

input object callback function definition

It will run in the background as the default input event listener for all input objects when you run your application. All input objects created will use it for event detection.

You must define it inside your application if you decide to use it ( see setInput() section ).

If you want to create your own common event function instead of using the main event, you can follow the example below.

const GPIO = require('array-gpio');

let sw = GPIO.Input(11, 13, 15, false);
let led = GPIO.Output(33, 35);

/* common input event handler for all inputs */
let swEventHandler = () => {
  /* I/O logical expressions */ 
};

/*
*  assign the swEventHandler 
*  as local event for each sw object
*/
for(let x in sw){
  sw[x].event(swEventHandler);
}

setOutput(pin1, pin2, pin3 ... pinN)

output object constructor

Set a GPIO pin or group of GPIO pins as output object.

Choose your pin based on the physical pin number (P01-P40).

Returns an output object using a single pin or an array object for more than one pin.

For array object, each pin will be assigned or indexed consecutively as element of the returned array object.
Similar to setInput(), you can set as many output pins as you can.

This is a synchronous function.

Using object as a single argument

setOutput(arg)

var arg = {pin:[pin1, pin2, pin3 ... pinN]};

const GPIO = require ('array-gpio');

let arg = {pin:[33,35,37,36,38,40]};

let actuator = GPIO.setOutput(arg);

Similar to setInput(), you can also use the following syntax for output object setup.

###Output (...)

###output (...)

###out (...)

All of the above will have the same result as setOutput().

on([t]) and off([t])

output method

Turn ON and OFF an output object.

t is an optional time delay in milliseconds. Output object will turn ON or OFF after the expiration of time delay.

Example

const GPIO = require('array-gpio');

let sw = GPIO.input(11,13);
let actuator = GPIO.output(33,35);

GPIO.main = () => {
  if(sw[0].isOn && actuator[0].isOff){
    actuator[0].on(200); // turns ON after 200 ms delay
    actuator[1].on(); // turns ON immediately
  }
  else if(sw[1].isOn && actuator[1].isOn){
    actuator[0].off(50); // turns OFF after 50 ms delay
    actuator[1].off(); // turns OFF immediately
  }
};

write(value[,callback])

or

w( ... )

output method

The traditional way of turning ON and OFF an output object.

value - control bit number.

1 - ON or high state

0 - OFF or low state

callback function will be executed asynchronously if provided.

Example

const GPIO = require('array-gpio');

const sw = GPIO.input(11,13);
const actuator = GPIO.output(33,35);

let sw1 = sw[0];
let sw2 = sw[1];

let motorA = actuator[0];
let motorB = actuator[1];

GPIO.main = () => {
  if(sw1.read() === 1){
    motorA.write(1, function(){
      if(motorB.read() === 0)
      motorB.write(1);
    });
  }
  if(sw2.read() === 1){
    motorA.write(0, function(){
      if(motorB.read() === 1)
      motorB.write(0);
    });
  }
};

delayON(t [,callback]) and delayOFF(t [,callback])

or

delayOn(...) and delayOff(...)

output method

t is the required time delay in milliseconds. Output object will turn ON or OFF after the expiration of time delay.

callback function will be executed asynchronously when time delay expires.

Example

if(sw[0].state && actuator[0].state === false){
  // actuator5 will turn ON after 1 sec
  actuator[0].delayON(1000, function(){
    console.log('actuator is ON'); // outputs after 1 sec  
  });
  console.log('turning ON actuator ...'); // outputs immediately
}
else if(sw[1].state && actuator[1].state){
  actuator[0].delayOFF(1500, function(){
    console.log('actuator is OFF'); // outputs after 1.5 sec  
  }); 
  console.log('turning OFF actuator ...'); // outputs immediately
}

pulse(cs, T, pw [,callback])

output method

Allows the generation of basic square-wave pulses for each output object for simple timing applications using software emulation. This is not as precise compared to using hardware implementation.

cs is a control flag.

Use 1 to start generating pulses with other provided arguments.

It provides a verbose console output like signal info, start or stop confirmation etc. If it bothers you, use 2 instead.

Use 1 without any other arguments or just drop all arguments to stop the pulsing process. Use 2 to stop in silent mode.

T (ms) is the period or the time interval of the pulse signal. Minimum T period is 5 ms. The first pulse will be generated on the 2nd T period during start up.

pw (ms) is the pulse width of the pulse generated. Minimum width is 1 ms.

callback function will be executed or triggered half-way of the pulse width on a best effort method.

Example 1

const GPIO = require('array-gpio');

let sw = GPIO.input(11,13,15);
// connect an led to each outpin pin 
let waveGenerator = GPIO.output(33,35,37);

GPIO.main = () => {
  // using waveGenerator[0]
  if(sw[0].isOn){
    // start generating pulse using 10% duty cycle
    waveGenerator[0].pulse(1, 100, 10);
  }
  else if(sw[0].isOff){
    waveGenerator[0].pulse(); // stop pulsing
  }
  // using waveGenerator[1]
  if(sw[1].isOn){
    waveGenerator[1].pulse(1, 1000, 250);
  }
  else if(sw[1].isOff){
    waveGenerator[1].pulse(); 
  }
  // using waveGenerator[2]
  if(sw[2].isOn){
    waveGenerator[2].pulse(1, 200, 100); 
  }
  else if(sw[2].isOff){
    waveGenerator[2].pulse();
  }
};

Example 2

const GPIO = require('array-gpio');

// using two button switches connected to pin 11 and 13
const input = GPIO.input(11,13);
// using two led's connected to each outpin pins
const output = GPIO.output(33,35);

let start = input[0];
let stop = input[1];

let wave1 = output[0];
let wave2 = output[1];

const T = 2000;
const pw = 5;

// synchronize wave2 pulse with wave1
function trigger(){
  if(wave1.state && wave2.state){
    console.log('overlap detected');
    wave2.pulse(); // reset 
    wave2.pulse(1, T, pw, stopCounter ); // synchronize and restart 
  }
}

var count = 0;
function stopCounter(){
  if( count !== 3 ){
    count += 1;
    console.log('pulsing together ' + count );
  } else {
    console.log('done with pulsing!');
    wave1.pulse();
    wave2.pulse();
    count = 0;
  }
}

/*
*  Generate two square-wave pulses 
*  with different pulse width and cycle period.
*  At some point in time, both pulses will overlap. 
*  Let us capture that first instance of overlap
*  when both pulses are in high state.
*  After which, we will synchronize both waves, count 3 pulses
*  and stop both the pulsing process.
*/

GPIO.main = function (){
  if(start.isOn){
    wave1.pulse(1, T, pw, trigger);
    wave2.pulse(1, 45, 2, trigger);
  }
  if(stop.isOn){
    wave1.pulse();
    wave2.pulse();
  }
};

function appExitProcess(){
  console.log('closing all I/O objects');
  for(let x in input){
    input[x].close();      
  }
  for(let x in output){
    output[x].close();
  }
}

// using Ctrl-C for app exit
process.on('SIGINT', function (){
  appExitProcess();
  process.exit(0);  
});

loop(cs, T, callback)

output method

This is a utility function for general purpose looping operations.

It is attached to an output object as a property method but it is totaly independent from its GPIO operations. So you can continue using the output object for other purposes while using the loop utility.

It is not very different from setInterval() function. However, it has some internal flags to prevent a race condition.

cs is a control flag.

Use 1 to start the looping operation along with the other arguments.

Use 0 or without any arguments to stop.

T (ms) is the time interval of the looping operation. Minimum is 10 ms.

callback function will be executed asynchronously at the end of time interval. This is the task or process you want to loop or cycle continously.

The total elapsed time of the process must be accounted for or determined if you are using a lot of time delays in your I/O operations.

Example

const GPIO = require('array-gpio');

const input = GPIO.Input(11,13);
const led = GPIO.Output(33,35,37,36,38,40);

let start = input[0];
let stop = input[1];

// using the loop utility from led[0]
// without affecting its led ON/OFF operation
let ledSequence = led[0];

// turn ON and OFF led's sequentially
// total elapsed time is 700 ms 
let ledOnOff = () => {
  let t = 50; 
  for (let x in led){
    t += 50;
    led[x].delayOn(t, () => console.log('led[' + x + '] is ON')); 
    led[x].delayOff(t + 400, () => console.log('led[' + x + '] is OFF')); 
  }
};

GPIO.main = () => {
  if(start.isOn){
    // start the ledOnOff sequence  
    ledSequence.loop(1, 1000, ledOnOff);
  }
  else if(stop.isOn){
    // stop the ledOnOff sequence  
    ledSequence.loop();
  }
};

var appExitProcess = () => {
  console.log('closing all I/O objects');
  for(let x in input){
    input[x].close();      
  }
  for(let x in led){
    led[x].close();
  }
}

// using Ctrl-C for app exit
process.on('SIGINT', () => {
  appExitProcess();
  process.exit(0);  
});

pin

input/output property

Returns the GPIO pin used during setInput() or setOutput() procedure.

Example

const r = require('array-gpio');

let sw = r.Input(11);
let led = r.Output(33);

console.log(sw.pin); // 11
console.log(led.pin); // 33

close()

input/output method

Closes any input/output object.

Example 1

const r = require('array-gpio');

let sw = r.Input(11);
let led = r.Output(33);

sw.close();
led.close();

Example 2

const r = require('array-gpio');

let input = r.Input(11, 13);
let output = r.Output(33, 35);

function appExitProcess(){
  console.log('closing all I/O objects');
  for(let x in input){
    input[x].close();      
  }
  for(let x in output){
    output[x].close();
  }
}

// using Ctrl-C for app exit
process.on('SIGINT', function (){
  appExitProcess();
  process.exit(0);  
});

setR(intR)

input method

Sets or changes input internal resistor using either pull up or pull down.

intR

'pu' or 1 - Enable pull up resistor.

'pd' or 0 - Enable pull down resistor.

If no parameter is provided, no internal resistor will be used.

Example

const r = require('array-gpio');

let sw = r.setInput(11,13,15);

// using pull up resistor
sw[0].setR('pu'); 
// using pull down resistor
sw[1].setR(0);
// no internal resistor
sw[2].setR();

Metadata

RunKit is a free, in-browser JavaScript dev environment for prototyping Node.js code, with every npm package installed. Sign up to share your code.
Sign Up for Free