if you happen to know C++ and node/iojs/V8, I would really appreciate any help and feedback on this module. There is certainly lots of room for improvement.
This module provides native bindings to the rpi_ws281x library by Jeremy Garff to provide a very basic set of functions to write data to a strip of ws2811/ws2812 LEDs. this will only run on the Raspberry Pi.
this module is available via npm:
npm install rpi-ws281x-native
if you prefer installing from source:
npm install -g node-gyp
git clone --recursive https://github.com/beyondscreen/node-rpi-ws281x-native.git
cd rpi-ws281x-native
npm install
node-gyp rebuild
this module mainly exports four functions to send data to the LED-String.
exports = {
/**
* configures PWM and DMA for sending data to the LEDs.
*
* @param {Number} numLeds number of LEDs to be controlled
* @param {?Object} options (acutally only tested with default-values)
* intialization-options for the library
* (PWM frequency, DMA channel, GPIO, Brightness)
*/
init: function(numLeds, options) {},
/**
* register a mapping to manipulate array-indices within the
* data-array before rendering.
*
* @param {Array.<Number>} map the mapping, indexed by destination.
*/
setIndexMapping: function(map) {},
/**
* set the overall-brightness for the entire strip.
* This is a fixed scaling applied by the driver when
* data is sent to the strip
*
* @param {Number} brightness the brightness, value from 0 to 255.
*/
setBrightness: function(brightness) {},
/**
* send data to the LED-strip.
*
* @param {Uint32Array} data the pixel-data, 24bit per pixel in
* RGB-format (0xff0000 is red).
*/
render: function(data) {},
/**
* clears all LEDs, resets the PWM and DMA-parts and deallocates
* all internal structures.
*/
reset: function() {}
};
As the wiring of the LEDs not neccessarily corresponds to the pixel-ordering in the data-array, this module supports index-remapping. So, if you are building a grid of LEDs you can just use an alternating, top-to-bottom or mirrored wiring and use the remapping in order to use a unified structure in the incoming data-arrays.
In addition to that, the exported object is an EventEmitter
that will emit
the following Events:
beforeRender
: emitted just before the data is prepared and sent to the LED-driver. The handler will receive the pixel-data array (anUint32Array
) as single argument. As this event is handled synchronously, you can use this to manipulate the data before it is sent to the LED-Strip.render
: emitted after the data has been sent to the LED-Strip. The single argument passed to the handler is the final pixel-data array, after index-remapping and gamma-correction.
connect the WS2812-strip to the raspberry-pi as described
here and run
the command sudo node examples/rainbow.js <numLeds>
.
You should now see some rainbow-colors animation on the LED-strip.
As the native part of this module needs to directly interface with the physical memory of the raspberry-pi (which is required in order to configure the PWM and DMA-modules), it always has to run with root-privileges (there are probably ways around this requirement, but that doesn't change the fact that the node-process running the LEDs needs access to the raw physical memory – a thing you should never allow to any user other than root).
If you are using this module as part of a program that should not be run with elevated privileges, it would be a good idea to have the LED-driver running in a seperate process. In such a case you could use the openpixel-control protocol to send the pixel-data to the driver-process. A stream-based node-implementation and some more information can be found here.
There is a guide over at adafruit.com on how to get the hardware up and running. I followed these instructions by the word and had a working LED-strip.
Essentially, you need the Raspberry Pi, a logic-level converter to shift the output-voltage of the GPIO from 3.3V up to 5V (the guide mentions the 74AHCT125, mine is an 74HCT125N which works just as well) and of course a LED-Strip or other types of WS2812-LEDs.
To connect all that together, I'd recommend buying a small breadboard and some jumper-wires. Also, consider buying a 5V power-supply that can deliver up to 60mA per LED (so you'll need up to 6A (30W) to fully power 100 LEDs). For smaller applications, a decent USB-charger should do.
A short checklist of what you will need:
- Raspberry-PI and SD-Card
- 5V power-supply (Meanwell for instance builds really good ones)
- LED-Strip with WS2811/WS2812 Controllers (there are several other controller-variations that are not supported)
- a breadboard and some jumper-wires (m/m as well as at least two f/m to connect the GPIO-Pins)
- a 3.3V to 5V logic-level converter (74AHCT125 or 74HCT125N, others will probably also work)
- more wire to connect the LED-strips
You can buy everything at adafruit.com, sparkfun, on ebay or your favourite electronics retailer (germany: check conrad electronic, watterott or reichelt where i bought most of my stuff).
There is a conflict where the internal soundcard uses the same GPIO / DMA / PWM functions that are needed to run the LED-drivers. As far as I know you can not use both at the same time.
One workaround is to use an external (USB) soundcard and make it the default device:
Edit /etc/modprobe.d/alsa-base.conf and comment out the line
options snd-usb-audio index=-2
If anyone finds a better solution please get in touch!