Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

node-pixel-async

hweeks88MIT1.3.0TypeScript support: included

Library for controlling addressable LEDs (such as NeoPixels) from firmata or Johnny Five.

nodebots, johnny-five, leds, ws2812, ws2812b, ws2811, firmata, neopixel, rgb led

readme

Node Pixel Async

A completely derivative work of node-pixel

Intent

I am using this repo as a place to make rapid changes, as it matures and I am able to add more meaningful updates to it I will update this readme. Until then consider this repo as unuseable unless you understand all of the code in it. I will be keeping it up to date with node-pixel, and providing what patches I can. I'm trying to get something done by end of this month and iteration spped is vital!

Back to the README!

Built Docs

We are building docs for this now here. Please use them for info about this project, they are aut-generated.

Overview

The purpose of this library is to provide a node js interface for addressable RGB LEDs. Most commonly these are known as Neo Pixels (if you shop at Adafruit) however any WS2812b addressable LED should work with this library.

The current iteration supports two methods of set up:

  • a custom version of firmata that provides an interface to talk to the "pixels".
  • an I2C "backpack" using an arduino pro mini or nano that provides the interface and control of the pixels and then the IO controller talks to this backpack over I2C messages.

The pixel library can be used with both Johnny-Five or stock Node Firmata and can be used by any board that provides an IO interface with I2C support such as a Raspberry PI.

Both fimwares are provided in this repo in the firmware/build directory.

Getting help

If you need some help getting your pixel strip working with johnny five jump into the Gitter Chat or reach out to ajfisher on twitter or just raise an issue here.

Installation

Installation of both backpack and custom firmata are covered in detail in the Installation Guide.

Short version for node-pixel custom firmata.

npm install node-pixel
npm install -g nodebots-interchange

Plug in your arduino

interchange install git+https://github.com/ajfisher/node-pixel -a uno --firmata

Note that on windows, you may need to explictly pass a port to flash due to the way com ports work. eg:

interchange install git+https://github.com/ajfisher/node-pixel -a uno -p COM3 --firmata

A note on multiple strips

Multiple led strips on one arduino or backpack are supported up to a maximum of 8 individual strips (8 pins in use at once). Each strip can be different lengths but you can only have a maximum of 192 pixels for Firmata and about 500 pixels for the backpack version.

Multiple strips connected to a single board or backpack are for the purposes of node-pixel considered to be a single strip and are joined together in sequence in the order that you define them.

On a backpack, the strips are defined sequentially from pin 0-7 on the backpack.

On an arduino, each strip can be defined with an individual pin which doesn't need to be sequential (eg you can use pin 3, then pin 9, then pin 7).

One thing to note is that the timings on these strips are quite tight and you will reach an upper limit of how much data you can push to the board controlling the pixels (all that RGB data going over the wire) and the sheer number of pixels you can refresh quickly (each pixel is written "in turn"). As such, you may run into some blocking conflicts. These are discussed in this issue.

Pixel API

The Pixel API is provided below.

Strip

A sequence of LEDs collected together is called a strip. A strip has a controller to tell it to use the custom firmata or I2C backpack. A strip can be a single physical strip in which case a single pin and length can be provided. Otherwise it is made up of multiple physical strips, each of which have their own pin and length and are composed together into order by using the strips array as part of the definition of the object.

For the purposes of interaction however, once a strip is defined, it is all one logical unit and the firmware will take care of writing data in the right order, performing optimisations for strips that have or haven't changed and writing in sequence or parallel as appropriate.

Parameters

  • options An object of property parameters
Property Type Value / Description Default Required
pin Number Digital Pin. Used to set which pin the signal line to the pixels is being used when using a single strip. 6 no (4)
length Number Number of pixels to be set on a single strip or all strips if individual lengths are not defined in the strips array 32 no (5)
color_order Constant Determines the order of the RGB values against the pixels. Can be GRB, RGB or BRG pixel.COLOR_ORDER.GRB no (6)
strips Array Array of pin and length objects or array of length objects 6 no (2)(3)
board IO Object IO Board object to use with Johnny Five undefined yes(1)
firmata Firmata board Firmata board object to use with Firmata directly undefined yes(1)
controller String I2CBACKPACK, FIRMATA FIRMATA no
skip_firmware_check Boolean If the controller is FIRMATA, optionally skip the check for the matching node-pixel sketch false no
gamma Number A number representing the gamma correction for a strip. Can be any decimal number. 2.8 generally works well. 1.0 (7) no

(1) A board or firmata object is required but only one of these needs to be set.

(2) If using a backpack use an array of lengths eg [8, 8, 8] which would set pins 0, 1 & 2 on the backpack to have strips of length 8 each on them.

(3) If using custom firmata then use an array of objects eg [ {pin: 4, length: 8}, {pin: 10, length: 8}, {pin: 11, length: 8} ] which would set pins 4, 10 & 11 to have strips of length 8 on each of them.

(4) If not supplied, it is assumed a strips array will be provided with a pin parameter for each object in the array.

(5) If not supplied, it is assumed a strips array will be provided with a length parameter for each object in the array.

(6) If supplied it will apply to all strips unless overridden selectively in the strips array eg [ {color_order: pixel.COLOR_ORDER.RGB}, ..]

(7) Currently set to 1.0 to maintain current behaviour. Will move to 2.8 default in version 0.10.

Properties

  • length - number of pixels in the strip
  • gamma - the currently set gamma for the strip

Events

  • onready() - emits when the strip is configured.
  • onerror() - returns the error that occurred.

Examples

Johnny-Five instantiation

pixel = require("node-pixel");
five = require("johnny-five");

var board = new five.Board(opts);
var strip = null;

board.on("ready", function() {

    strip = pixel.Strip({
        board: this,
        controller: "FIRMATA",
        strips: [ {pin: 6, length: 4}, ], // this is preferred form for definition
        gamma: 2.8, // set to a gamma that works nicely for WS2812
    });

    strip.on("ready", function() {
        // do stuff with the strip here.
    });
});

Firmata instantiation

pixel = require("node-pixel");
var firmata = require('firmata');

var board = new firmata.Board('path to usb',function(){

    strip = pixel.Strip({
        pin: 6, // this is still supported as a shorthand
        length: 4,
        firmata: board,
        controller: "FIRMATA",

    });

    strip.on("ready", function() {
        // do stuff with the strip here.
    });
});

Johnny Five with backpack

pixel = require("node-pixel");
five = require("johnny-five");

var board = new five.Board(opts);

board.on("ready", function() {
    strip = pixel.Strip({
        board: this,
        controller: "I2CBACKPACK",
        strips: [4, 6, 8], // 3 physical strips on pins 0, 1 & 2 with lengths 4, 6 & 8.
    });

    strip.on("ready", function() {
        // do stuff with the strip here.

    });
});

Note that Johnny-Five uses the board option and firmata uses the firmata option. This is because the pixel library supports a Board capable of presenting an IO interface. The library will work out the right thing to do based on the board being passed and the controller being set.

Methods

show();

The show method should be called at the point you want to "set" the frame on the strip of pixels and show them.

Note that when this method is called it will trigger the process that writes the frame to the strips. If you have a very long strip of LEDs this may take some time (assume 0.5ms per pixel) and is a blocking operation in most cases.

This gives you an upper limit as to how many frames you can drive per second.

Example

// ... make pixel modifications

strip.show(); // make the strip latch and update the LEDs

Addressable LEDs work by clocking data along their entire length and so you make the various changes you want to the strip as you need to without triggering the display (like a frame buffer). Once you're ready you can then call show() to propagate this data through the LEDs and display the frame.

off();

All LEDs on the strip can be turned off by using the .off() method. This effectively clears the current colours set on the strip.

.clear() is also aliased to the same method.

Example

strip.off(); // turn the strip off / clear pixel colours

color( colourstring );

All LEDs on the strip can be set to the same colour using the .color() method.

.colour() is also aliased to the same method.

Parameters

  • colourstring A String as a standard HTML hex colour or a CSS colour name, or a CSS rgb(r, g, b) value used to specify the colour of the strip. Alternatively an Array object as an rgb value eg [r, g, b]

Examples

Set strip using a hex value

strip.color("#ff0000"); // turns entire strip red using a hex colour
strip.show();

Update strip using a named CSS colour

strip.colour("teal"); // sets strip to a blue-green color using a named colour
strip.show();

You can also use CSS RGB values

strip.color("rgb(0, 255, 0)"); // sets strip to green using rgb values
strip.show();

Or set using an array of RGB values

strip.color([255, 255, 0]); // Sets strip using an array
strip.show();

shift( amt, direction, wrap );

All LEDs on the strip can be shifted along the strip forwards or backwards by the given amount. This is very useful for long strip animation when you're moving the whole strip by a pixel in one direction each frame and means you don't have to send an update of framelength messages

Parameters

  • amt A Number representing the number of pixels you want everything to shift by.
  • direction Either Pixel.FORWARD or Pixel.BACKWARD value which determines direction of travel. Forward direction is in the flow index values (ie index 1->2 etc).
  • wrap a Boolean representing whether to wrap the values that go off the "end" of the strip back around to the start - useful for circular displays.

Example

strip.pixel(0).color("#000");
strip.pixel(1).color("red");
strip.shift(1, pixel.FORWARD, true);
strip.pixel(1).color; // will now be nothing
strip.pixel(2).color; // will now be red.

pixel( address );

Individual pixels can be addressed by the pixel method using their address in the sequence.

Note that if you have two physical strips of 8 and 10 then pixel(10) will be the third pixel on the second physical strip.

Parameters

  • address A Number indexing the pixel you want. Returns a Pixel object.

Example

var p = strip.pixel(1); // get the second LED. p is now a Pixel object

Pixel

A pixel is an individual element in the strip. It is fairly basic and it's API is detailed below.

Methods

color( color string )

Colors work exactly the same way on individual pixels as per strips so see the strip.color reference above.

.colour() is aliased to this method as well.

Parameters

  • color string A String providing the hex colour, CSS colour name or CSS rgb() values to be used to set the individual pixel a certain colour. You can also pass in an Array object that is a set of RGB values as [r, g, b].

Examples

var p = strip.pixel(1);     // get second LED
p.color("#0000FF");         // set second pixel blue.

p = strip.pixel(2);         // get third LED
p.colour("orange");          // set third pixel red/yellow

p = strip.pixel(3);         // get fourth LED
p.color("rgb(0, 255, 0)");  // set fourth LED green

p = strip.pixel(4);         // get fifth LED
p.color([255, 0, 255]);     // set fifth LED magenta

color()

Returns an object representing the color of this pixel with the shape below.

.colour() is aliased to this method as well.

Parameters

  • none

Shape

{
    r: 0,               // red component
    g: 0,               // green component
    b: 0,               // blue component
    hexcode: "#000000", // hexcode of color
    color: "black",     // keyword name of color if matching
    rgb: [0,0,0],       // RGB component array
}

Example

Get a pixel, set it's colour and then query it's current state.

var p = strip.pixel(1); // get second LED

p.color("#0000FF"); // set second pixel blue.

p.color(); // returns {r:0, g:0, b:255, hexcode:"#0000ff", color:"blue", rgb[0,0,255]}

off()

Turns the pixel to it's off state.

.clear() is also aliased to this method.

Example

Set a pixel value to off


var p = strip.pixel(1); // get second LED
p.off(); // turn it off
p.color(); // returns {r: 0, g: 0, b: 0, hexcode:"#000000", color:"black", rgb: [0,0,0]}
strip.show(); // pixel will be off

Detailed examples with circuits

TODO and roadmap

This library is under active development and planned modifications are:

  • Provide methods of having different shapes to the strips including 3D
  • Prvide method of pixel selection using polar coordinates for circles and hexes

changelog

1.3.0 (2020-11-27)

Features

1.2.0 (2020-11-26)

Bug Fixes

  • allow color conversion based on channel maximums (4f1d542)

Features

  • color: allow color conversion based on channel maximums (2bd4264)
  • add base config for function (ac5bac9)

1.1.0 (2020-11-22)

Features

  • pixel breakdown to match strip (137a623)

1.0.0 (2020-11-22)

Features

  • core: move to ts completly, strip factory (fc6e016)

BREAKING CHANGES

  • core: strip class becomes a factory, private api changes

0.13.0 (2020-11-21)

Features

Changelog

All notable changes to this project will be documented in this file. See standard-version for commit guidelines.

0.11.0 (2020-10-25)

Features

  • build: Updated build process to use arduino-cli (#175) (effa990)

Build System

  • deps: bump color-string from 1.5.3 to 1.5.4 (3588aff)
  • deps-dev: bump eslint from 7.10.0 to 7.11.0 (1fd6af1)
  • deps-dev: bump sinon from 9.1.0 to 9.2.0 (#179) (a9ea21f)
  • Added github action for testing board compilation (#176) (5847799)
  • Move testing and coveralls to github actions (#178) (a49db6f), closes #177

Documentation

  • Updated readme to provide extra help for windows users. Fixes #182 (#183) (5e22e8a)

Chores

0.10.5 (2020-10-05)

Bug Fixes

  • linting: Added linting checks to the JS files to the repo (#169) (f32c302)
  • utils: Removed debug msg and added release recipe (#172) (710f29d)

Chores

  • ci: Add husky to repo with tests hooked correctly (#170) (e5e1a0e)
  • ci: Updated node versions to 12 and 14 for current support for travis (#171) (01f120e)

Build System

  • Additional make recipes to make life a bit easier (#174) (690d972)
  • docs: Added changelog controls to standard-version to include other detail (#173) (0444aaa)

0.10.4 (2020-10-04)

Bug Fixes

  • security: Bump websocket-extensions from 0.1.3 to 0.1.4 (#166) (be57708)

0.10.3 (2020-10-04)

0.10.2 (2019-06-05)

Bug Fixes

  • package: update johnny-five to version 1.0.0 (a43c8dc)

0.10.1

  • Security updates to fix dependency security issues

0.10.0

  • Updates for all major packages in the repo in order to bring back in line
  • Build now passing for nodejs v10 and this has been added to build testing script
  • Updates for johnny five and firmata and move firmata to peer dependency

0.9.3

  • Breaking change with Sinon as a result of 3.0, needed to reactor tests as a result
  • Range of other package updates bringing back into line.

0.9.2

  • Range of general changes related to upstream package dependencies and bringing back into line.

0.9.1

  • Example documentation updates to bring in line with the new .length API - thanks @rupl
  • Upgraded mockfirmata for testing

0.9.0

  • Added capability for gamma correction for the strip. Currently set to no correction by default, it can now be added as an initialisation parameter gamma.
  • Package updates for all dependencies
  • Bug fixes:
    • Made pixel.off() behaviour actually work properly as a result of test coverage - YAY Tests!
    • Better handling for the way exceptions are raised for range errors.
  • Major update to tests
    • Roll out of istanbul for code coverage testing
    • Updates of tests to all work again properly with latest API due to drift
    • Addition of new test for gamma value creation
    • New test for ensuring stripLength throws an error
    • Removed redundant tests that were testing ColorString.
    • Fixes to test messages to better indicate what they were testing.
    • Large refactor to tests for exception handling
    • Added test for pixel.off correctness.
    • Tests for handling garbage colour values
    • Added tests for handling wrapping / shifting conditions.
    • Removed redundant checks in codebase where preconditions had to be met so checks were irrelevant
    • Added tests for handling issues where strips are incorrectly initialised
    • Achieved significant coverage improvement using Istanbul
  • Added travis integration and integrated with gitter and coveralls.
  • Added green keeper integration

0.8.3

  • Fixes to all examples to bring in line with new length API and removal of deprecration notices as a result of this change. Thanks @The-Alchemist

0.8.2

  • Fixes to testing setup - thanks @reconbot

0.8.1

  • Put in error check to make sure the firmata firmware is capable of doing node-pixel stuff. Fixes #74
  • Put in I2C write check to deal with specifically time outs on high bandwidth writes that appear to happen on RPi. Fixes #71 and
  • Added .off() option to individual pixels. Completed: #61

0.8.0

  • Moved all strip manipulation up to the level of the ws2812 library in order to consolidate into a single array. This means that the Strips are now relatively dumb and just operate on the array they are passed which is ripe for further consolidation down the line. ( = more memory for pixels - YAY!)
  • Added a SHIFT operation to the protocol per #32 which is what required this large refactor above.
  • Begun deprecation of strip.stripLength() and move to strip.length as the more logic alternative. 0.8 generates warning, 0.9 will throw error, 0.10 will have function removed
  • Added example examples/repl that exposes strip object so you can manipulate it from a repl environment

0.7.1

Thanks to @stevemao for the following:

  • Updated strip color to consistently take arrays for the rgb model
  • Made Strip.off() behaviour intuitive so it latches as soon as it's set and turns the strip off.
  • Updated package file to be able to run npm test

0.7.0

  • updated packages to bring dependency list up to scratch.
  • removed es6-collections shim YAY ES6.
  • Updated node-pixel-firmata with latest version of StandardFirmata (v2.5.3)
  • Updated lib to use new color string api.
  • Resolved issue with an osx segfault when trying to write too quickly after firmware returns
  • Update to grunt file to now build and compile hexes to target MCU architecture
  • Manifest file for interchange to be able to install to targets.
  • Update of examples as needed.

0.6.1

  • Fixed some default I2C address issues - thanks @frxnz

0.6.0

  • Added strip.off() functionality and tests - thanks again @noopkat

0.5.2

  • Documentation fixes around syntax highlighting thanks to @noopkat

0.5.1

  • Modified maximum firmata to 192 pixels after profiling and lack of memory issue

0.5

  • Strip multipin! You can now use and define multiple strips on different pins in the firmata and I2C backpack versions of node-pixel.
  • Tests are starting to be laid in for any development. New features require tests to be built out as well from now on.
  • Removed the AdaFruit lib and switched to lightweight lib with a number of modifications from https://github.com/cpldcpu/light_ws2812 (mostly removals of things we don't need because the JS side will take care of it).
  • Added protocol changes to set the colour order of the strip so that you can use different types of pixels
  • Added protocol changes to define multiple strips of varying legnths
  • Interface to the virtual strip is singular and the C lib takes care of the mapping to the actual pixel required.
  • Added set_off() in order to rapidly and efficiently wipe an entire strip of values back to zero in the firmware.
  • Implemented error checking for too many strips and too many pixels that would exceed memory limits in the firmware.
  • Updated new examples and updated examples documentation properly incuding the updates to the master readme and installation guides. All examples have code in them as well as proper wiring diagrams.
  • Package dependencies updated to bring into line.
  • New tests for pixel lengths, strip maximums, ensuring calculations are correct.

0.4.1

  • Fixed bug in backpack firmware that meant it was doing full scale serial debugging by default.

0.4

  • Major refactor to deal with install and symlinking issues. Updates mean a Grunt task which is used to build the destination trees properly so the firmware can be compiled. This means better cross-platform support as well as no symlinking when npm installed the package. More details here https://github.com/ajfisher/node-pixel/issues/34
  • New documentation added and installation instruction fixed.
  • Grunt file used to do all building operations from a source tree to produce the relevant files in the right place for building
  • renamed the examples to be more sensical.

0.3.3

  • @pierceray contributed two examples porting "rainbow" behaviour with a static rainbow effect and a dynamic moving one.

0.3.2

  • Various documentation updates to clean up errors.
  • npm installation fixes - thanks @frxnz

0.3.1

  • Documentation updates and bug fixes around Baudrate on backpack for RPi installation
  • Thanks to @frxnz

0.3.0

  • Added pin selection to the constructor in order to be able to set which pin you are using for the strip.
  • Added custom I2C controller in pixel.js
  • added custom I2C Backpack firmware.
  • Removed ATTIny85 support due to bugginess.
  • Updated all documentation including firmware install support etc.

0.2.3

  • Restructure of the firmware folder ahead of providing backpack and native firmata controllers.
  • Updated all of the package versions.

0.2.2

  • Migration of all protocol messages to use firmata SYSEX commands with custom command set that will be viable when moving to I2C / SPI.
  • Updates to Pixel lib to talk this protocol
  • Optimisation of the SYSEX commands to ensure high bitrate (now at 150fps on test rig - up from 18)
  • Removal of all the string processing code which drops hex file size from 20K to 11K
  • documentation of protocol as it's being created.

0.2.1

  • First implementation of Pixel library on JS side against firmata API
  • big restructure of entire code base to work properly in ino and arduino

0.2.0

  • Removal of 95% of all custom firmata messages and compression of existing messages in order to speed things up.
  • Entire restructure of code library including ino support and structure to support no-dependency firmware compilation.

0.1.0

  • Firmata only implementation
  • Specific implementation in firmata to provide functions
  • Naive implementation against Adafruit NP library.
  • Initial build of library