Controlling Ten Thousand RGB LEDs

RGB LEDs are awesome – especially the new, fancy ones with the WS2812 RGB LED driver. These LEDs can be individually controlled to display red, green, and blue, but interfacing them with a microcontroller or computer presents a problem: microcontrollers generally don’t have a whole lot of RAM to store an image, and devices with enough memory to do something really cool with these LEDs don’t have a real-time operating system or the ability to do the very precise timing these LEDs require. [Sprite_tm] thought about this problem and came up with a great solution for controlling a whole lot of these WS2812 LEDs.

[Sprite] figured there was one device on the current lot of ARM/Linux boards that provides the extremely precise timing required to drive a large array of WS2812 LEDs: the video interface. Even though the video interface on these boards is digital, it’s possible to turn the 16-bit LCD interface on an oLinuXino Nano into something that simply spits out digital values very fast with a consistent timing. Just what a huge array of RGB pixels needs.

Using a Linux board to drive RGB pixels using the video output meant [Sprite_tm] needed video output. He’s running the latest Linux kernel, so he didn’t have the drivers to enable the video hardware. Not a problem for [Sprite], as he can just add a few files to define the 16-bit LCD interface and add the proper display mode.

[Sprite_tm] already taken an oscilloscope to his board while simulating 16 strips of 600 LEDs, and was able to get a frame rate of 30 fps. That’s nearly 10,000 LEDs controlled by a single €22/$30USD board.

Now the only obstacle for building a huge LED display is actually buying the RGB LED strips. A little back-of-the-envelope math tells us a 640×480 display would be about $50,000 in LEDs alone. Anyone know where we can get these LED strips cheap?

Things just to make it more obnoxious:
* Typical VGA-mimicking hardware supports a maximum width (almost always 2048) and a maximum height (almost always 1024 or 2048). While newer CRTCs can support higher resolutions (e.g. for 4K displays) I’d be skeptical if this one particular one could.
* At 120×1 pixels per 3 LEDs, the maximum you can display is either floor(2048/120)·1024·16 (= 280k) pixels, or floor(2048/120)·2048·16 (=560k) pixels.
* At 4MHz and 120 pixels per 16 LEDs, you get an effective dotclock of 533kHz: one can control about 9000 LEDs at 60Hz, and it goes down from there. 640×480 would drop you down to around 2fps.

Ugh. These things are probably one of the most frustrating things to deal with. I bought 4m of these plus an Arduino Due from Adafruit before Christmas and tried putting together a simple 16×11 display.
I initially tried driving them from 3.3v data line from the Due, no joy even when connecting ground lines. I’m using some logic level converters, multiple channels. Terrible problems all round as during my prebuild of the display I managed to break around 20% of them all!
It’s not like I was all that rough with them physically, and I ensured during soldering that I didn’t overheat them.
Even during the display build as I built up the 11 rows that previously fully working rows failed! Didn’t even touch them!
Anybody thinking of using these strips who doesn’t own a good oscilloscope be prepared for a world of pain!

I have never had a problem driving these w/ 3.3V; 3.3 AVRs and even direct from the GPIO of beaglebones. I believe as long as the first LED can read the signal, its internal buffer will act as a step-up to VCC for the consecutive LEDs. Heck I power mine from a ~3.8~4V 1S LiPo. AVRs are tolerant to that range which means I need absolutely no wasteful regulation outside the LiPo over-discharge protection.

I don’t think the hackaday editors have even tried to use these LEDs. They keep writing about how hard they are to use when they aren’t hard to use at all. If you get your data close enough to what it wants the first led in the chain cleans it up for you as you said. I think the ws2812 is hackadays new smt soldiering.. They used to like to write about how that was impossible to do by hand.

The 5050 package is super easy to hand solder, the SOT (pitch/”e”=1.27mm) package is my preferred SMT, it even matches IDC ribbon pitch – perfect for deadbugging.
The newer “B” versions are only 4 pin, a nice fat gap sans the middle pins for even easier soldering.
About timings, bah I say. Sure you may run into issues on non-realtime multi-process/task-switching/interrupting environments where timing is concerned – hence these articles, but on dedicated hardware you’re right this is a non-issue/non-story (uC[AVR,PIC], “PRU” on some TI ARM [BeagleB*]). If you keep track of instruction timings you don’t even need an oscilloscope, but they sure do help.

Hmmm. Well perhaps I should look again at using them at 3.3v data. I did actually get them working at 3.3v but only when powering the strips at that voltage too.
I tried powering them at 5v whilst driving the data at 3.3v, no luck even with grounds connected. In fact this is where I made most of these 20% breakages I believe.
The problem with powering them from lithium Ion or Lipo is that you dont get the best colour out of them, whites are distinctly off colour, for instance.

True to the colour, it can redden slightly and you don’t get full brightness. I think the colour is negligible though if you stay above the voltage needs of the actual LED dies (they say the WS2811 is a current regulator, so die voltage shouldn’t be linearly impacted by VCC). But honestly I do like the whites warmer at the lower voltage, it can be too blue at 5V for me.

I’ve only ordered about 20 reels of 4m 60/m and of those only 1 would not accept lower voltage signaling when testing them. All due to the first LED. If I made that particular strip secondary (following a different strip signaled at low voltage) it worked just fine, likely due to the internal buffers. If this is your scenario you can do a simple experiment by injecting the signal further up the strip (just touch any of the exposed DI pads).

BTW: Since the WS2812 LEDs are connected in series, wouldn’t there be a delay from the 1st LED in the chain updating to the last?

307,200 LEDs * 3 bytes each (RGB) = 921,600 bytes or 7,372,800 bits. The bus runs at 800KbpS. The lag from writing the first bit for the first LED to writing the last bit for the last LED would be 9.216 seconds. Ouch. Even with interleaving the ‘scan lines’, that’s still 4.6 seconds from first to last LED (or even frame to odd frame).

>BTW: Since the WS2812 LEDs are connected in series,
>wouldn’t there be a delay from the 1st LED in the chain updating to the last?

Yes, the first led shifts in 24 bits and the passes any following bits out of its out port until it is reset. If you want to build big displays you need to have multiple buses. You can’t rely on the tracks in the strip to carry a lot of current (I have 3 60 led strips and the two last strips are very dim without having their own tap back to the PSU) so you have to have some wiring back to the guts of your project anyhow so having multiple buses isn’t a big problem as long as you can drive them.

Yeah, parallel driving is where it’s at with larger displays on these. e.g. 8 parallel outputs you could pre-process & redistribute the pixel data like so, assuming 8-bit GPIO ports addressable by 8b registers or memory locations:
In byte0:bit0 to Out byte0:bit0
In byte1:bit0 to Out byte0:bit1
In byte2:bit0 to Out byte0:bit2
In byte3:bit0 to Out byte0:bit3
In byte4:bit0 to Out byte0:bit4
In byte5:bit0 to Out byte0:bit5
In byte6:bit0 to Out byte0:bit6
In byte7:bit0 to Out byte0:bit7

In byte0:bit1 to Out byte1:bit0
In byte1:bit1 to Out byte1:bit1
In byte2:bit1 to Out byte1:bit2
In byte3:bit1 to Out byte1:bit3
In byte4:bit1 to Out byte1:bit4
In byte5:bit1 to Out byte1:bit5
In byte6:bit1 to Out byte1:bit6
In byte7:bit1 to Out byte1:bit7
etc

So you have 8 outputs from a source image/frame cut into 8 sections pumping out simultaneously.
AVR has 8bit GPIO “ports”, ARM on the BeagleB* are 32bit memory locations, but many of those GPIO are reserved so can be tough to get a solid 32bit block of GPIO

With that kind of budget for LED, power supply (or even mounting/heat
hardware), I am sure one could afford to use a FPGA with a frame buffer
memory to do most of the heavy lifting instead of software.

This is another great use of code to drive parallel sets of leds. However, recent work on the LEDscape code https://github.com/Yona-Appletree/LEDscape can now drive 48 parallel outputs. String of up to 512 leds can be driven at 50 fps. We will have breakout boards for the BBB available to handle these outputs with our matrices at http://www.rgb-123.com very soon!