Widget of the Week #3: RGB LED arrays

Everyone likes addressable RGB LED arrays, they can be built into almost anything and they’re fun to program cycles and chases for.

First let’s cover some terminology.  We’re talking here about the LEDs arrays in which each pixel can be individually controlled.  They come in different formats – flexible strips, panels, bars, rings and individual pixels, but these all use the same device.

We also need to distinguish these LEDs from ordinary RGB LEDs which have no-board electronics but present three pairs of pins or a pin per LED and a common anode or cathode.  There’s also potential confusion with strips that are simply RGB LEDs wired in parallel with a dropper resistor in series with each to limit current, and a common cathode for all the LEDs.  The colour and brightness of these can only be controlled as a strip although there are chase varieties where colours cycle in groups rather like traditional ropelights.

Now you know which types to look for you’ll still be faced with a confusing range of descriptions but at the time of writing (autumn 2015) the only device to look for is the WS2812b.  This is essentially a three colour LED on top of a driver and serial controller chip in a single package.  You’ll often see advertisements mention the SMD 5050 or just 5050 which is the RGB LED itself (and supercedes the 3528 which is only a third as bright and the 3050 which is even less so).  The numbers in fact refer to the dimension of the LED package in tenths of a mm, thus the 5050 is 5mm square.

They’re often known as NeoPixels although that’s the simple brand name under which Adafruit brought them to the market.

When choosing flexible strips they’re commonly available in densities of 30, 60 or 144 LEDs per metre but other densities are available.  You can also choose between the bare strip and one or two grades or waterproofing for outdoor use.

So down to business – how do they work?  Control is accomplished by a single data bus daisy-chained along all the pixels of the array and fed with logic-level serial data.  The data is a simple protocol of 24 bits per pixel (that’s 8 bits each for Red, Green and Blue) at 800kHz for the WS2812, lower frequencies for earlier devices.  The controller for each pixel buffers 24 bits but as more data arrives it rotates the buffer, cleaning up the first bit and retransmitting it to the next pixel along which repeats the process.  So for instance if you had a string of 100 pixels you’d send a stream 2,400 bits (24 x 100) at the end of which the nearest pixel would be holding the last 24 bits and the furthest pixel the first 24 bits.  When they realise that the stream has stopped – when there’s no data for four bit-lengths – they latch what’s in the buffer and the latched values set the PWM level for the LEDs.

The protocol itself is a beautifully simple self-clocking arrangement with an 800kHz square wave, the rising edge of which is the timing reference.  Each cycle is pulse width modulated in a simple binary manner whereby a zero is a short high, long low and a one is a long high, short low.  The receiver synchronises its clock on the rising edges and examines the data around 500ns later at which point it will be low for a zero and high for a one.

The power requirement is nominally 5V but we’ve found that a 3.3V logic level is insufficient to control them when connected to a 5V supply but works fine (albeit with the LEDs a little less bright) when supplied at 3.3-4.0V.  Power consumption is a maxiumum of 20mA per LED element, so 60mA per RGB pixel, which can add up very quickly when using lengths of 60 or 144 LED/metre.  When using more than one strip the data line can be daisy-chained, along with the ground for reference, but feed each strip separately from the power supply.

There are several software libraries which I’ll write more about in the wiki entry but the Adafruit NeoPixel library will suffice for most purposes and you can find it at https://github.com/adafruit/Adafruit_NeoPixel.