OctoWS2811 LED Library


Use this OctoWS2811 Adaptor board for reliable communication from Teensy 3.2 to large LED projects.
OctoWS2811 is a high performance WS2811 & WS2812 & WS2812B LED library, written by Paul Stoffregen, featuring simultaneous update to 8 LED strips using efficient DMA-based data transfer (technical details below). Minimal CPU impact and double buffering allows complex animation. A VideoDisplay example is included, capable of scaling to extremely large LED installations using multiple Teensy 3.x boards with a frame sync signal for precise refresh timing.

Download: Included with the Teensyduino Installer
Latest Developments on Github

Update: Some of the latest WS2812B LED strips require 5 volt signals. You MUST use a 74HCT245 or similar buffer chip to increase Teensy's 3.3V signal to 5 volts for compatibility with these newer WS2812B LED strips. The OctoWS2811 Adaptor board or similar 5V buffer hardware must be used for reliable signals to large LED projects.

OctoWS2811 requires the DMA (Direct Memory Access) engine which is available only in Teensy LC & 3.x & 4.x.

Teensy 4.x boards support use of any set of pins, not limited to only 8 fixed pins.

Safety First

LEDs can produce extremely bright light. Please use caution when viewing large numbers of LEDs at close distance. A diffusing material in front the LEDs is usually a good idea.

Large LED arrays consume considerable power. Appropriate wiring should be used. AC mains voltage should be wired properly according to electrical codes.

Hardware Requirements

Eight LED strips should be connected as shown. Fewer or shorter strips may be used, with addressing described below.
Teensy
LC
Pin
Teensy
3.0
Pin
Teensy
3.1 & 3.2
Pin
Teensy
3.5 & 3.6
Pin
Teensy
4.0 & 4.1
Pin**
Function
22222LED Strip #1
1414141414LED Strip #2
77777LED Strip #3
88888LED Strip #4
66666LED Strip #5
2020202020LED Strip #6
2121212121LED Strip #7
55555LED Strip #8
-----Connect together
-432--Do not use
3, 432529, 30-Do not use as PWM
12*12*12*12*12*Frame Sync (Video)
TPM2FTM1FTM2FTM2QTimer4Timer Hardware Used
* Pin 12 only used by VideoDisplay example
** Default pins when custom pin list is not used

Teensy 4.0 and Teensy 4.1 can use any group of pins, even groups smaller or larger than 8 pins! In Arduino, open File > Examples > OctoWS2811 > Teensy4_PinList for details. If a custom pin list is not specified, the same group of 8 pins as Teensy 3.x will be used by default.

OctoWS2811 uses internally uses a timer, and a PWM waveform at a pin on some boards. This PWM pin and the timer must not be used. See the table above for details.

Early versions of OctoWS2811 required pins 15 & 16 to be connected together. Modern versions do not use pin 15 or 16.

Approximately 1000 LEDs per Teensy 3.0 or 4000 LEDs per Teensy 3.2 are recommended for large LED projects, to maintain high performance. Any number of Teensy boards may be used to support large LED arrays. The video frame sync signal must be connected to pin 12 of all the boards.

Basic Usage

OctoWS2811 leds(ledsPerStrip, displayMemory, drawingMemory, config);

Create OctoWS2811 object. You can only create a single object, but it must be created with these parameters:

leds.begin();

Initialize the library. This must be called before using setPixel or show.

leds.setPixel(num, red, green, blue);

Set a pixel. Red, green and blue are 0 to 255.

leds.setPixel(num, color);

Set a pixel. Color is a 24 bit color in RGB order (the same as html).

leds.show();

Start an update of the LEDs. This function returns within 2 microseconds. The display update continues, taking 30 microseconds for for each LED, plus 50 microseconds to reset the WS2811. If called while a previous update is running, this function waits for previous update to complete and then starts a new update.

leds.busy();

Check if a previous show() is still running. Returns true if the WS2811 LEDs are busy being updated, or false if no update is in progress.

leds.getPixel(num);

Read a pixel's color. The return is a 24 bit color number.

BasicTest Example Program

BasicTest can be loaded from File > Examples > OctoWS2811 > BasicTest.

The BasicTest is useful to verify your LEDs work, and to find the correct color configuration. Most WS2811 LEDs are wired for WS2811_GRB. If yours have different wiring, the colors will appear in a different order.


LED Addressing & Different Strip Lengths

OctoWS2811 is designed to drive 8 LED strips of equal length. LEDs on the first strip are numbered starting at zero. The second strip begins at the strip length and goes to strip length minus 1, and so on for each strip.


Shorter strips may be used on some or all 8 outputs. Outputs may be left unused. The LED addresses for setPixel() and getPixel() are the same as if 8 full length strips had been connected.


Even if fewer LEDs are connected, OctoWS2811 must be initialized with a memory buffer of 6 integers per LED in the configured strip length. Using shorter strips uses memory inefficiently, but can be done if fewer than 8 full length strips are needed.

VideoDisplay Example Program

The VideoDisplay example can show a video file streamed from a PC, Mac, Raspberry Pi or similar computer. One or more Teensy 3.0 boards running VideoDisplay can receive the streaming video, allow construction of very large LED arrays!

For best performance, connect approximately 1000 WS2811 LEDs per Teensy 3.0. When using more than 1 board, the video Frame Sync (pin 12) signal must be connected to all boards.


VideoDisplay with 1920 LEDs (60x32) driven by two Teensy 3.0 boards.

The code can be loaded from File > Examples > OctoWS2811 > VideoDisplay.

For each Teensy running VideoDisplay, you must configure seven parameters. The parameters are configured by editing the VideoDisplay.ino example.

#include <OctoWS2811.h>

// The actual arrangement of the LEDs connected to this Teensy 3.0 board.
#define LED_WIDTH      60   // number of LEDs horizontally
#define LED_HEIGHT     16   // number of LEDs vertically (must be multiple of 8)
#define LED_LAYOUT     0    // 0 = even rows left->right, 1 = even rows right->left

// The portion of the video image to show on this set of LEDs.  All 4 numbers
// are percentages, from 0 to 100.
#define VIDEO_XOFFSET  0
#define VIDEO_YOFFSET  0       // display entire image (single Teensy)
#define VIDEO_WIDTH    100
#define VIDEO_HEIGHT   100

When using more than one Teensy, each is configured for the LEDs it drives.

ParametersFunction
LED_WIDTH, LED_HEIGHT The number of LEDs connected to each individual Teensy 3.0.
LED_HEIGHT must be a multiple of 8.
LED_LAYOUT Zig-Zag layout of rows from each strip.
  0 = Left->Right, then Right->Left
  1 = Right->Left, then Left->Right
VIDEO_XOFFSET, VIDEO_YOFFSET The upper right corner of the portion of the video this Teensy should display. These numbers are percentages, from 0 to 100. When using only one Teensy, set these to 0, 0.
VIDEO_WIDTH, VIDEO_HEIGHT The size of portion of the video this Teensy should display. These numbers are percentages, from 0 to 100. When using only one Teensy, set these to 100, 100.

The LED_LAYOUT setting configures which direction the LEDs are physically arranged. If LED_HEIGHT is 8 (each strip is a single row), then 0 means the LEDs are left to right, and 1 means they are right to left oriented.


When LED_HEIGHT is 16, 24, 32, etc, each strip of LEDs forms multiple rows in a zig-zag layout. LED_LAYOUT = 0 means the leds go left to right, then right to left, and so on. Typically LED_LAYOUT = 0 is used when Teensy 3.0 is located on the left side of the display, and LED_LAYOUT = 1 is used when Teensy is on the right side. A very large LED project may use both layouts, where several boards drive the LEDs from both sides.

Each Teensy must also be configured with information about the portion of the video frame it should display. The video transmit application queries this information, for a "plug and play" style automatic configuration, even if your operating system assigns the serial device names or COM port numbers differently.


40x24 LEDs using one Teensy 3.0

These parameters allow you to easily construct large LED arrays by using multiple boards.


60x32 LEDs using two Teensy 3.0s

With each Teensy 3.0 driving approximately 1000 LEDs (or less), you can scale up to a very large high performance LED array!


120x64 LEDs using eight Teensy 3.0s

When using more than one Teensy, connect the Frame Sync (pin 12) signal between all boards. The first board will output a pulse and the others will synchronize their WS2811 update, for a very accurately timed update of the entire LED array.

For programming several Teensy 3.0s, the simplest way is to edit the VideoDisplay.ino parameters, click Verify, and then press the pushbutton on the desired board for those parameters, repeating for each board in the array.

This forum post has more information about possible challenges constructing extremely large LED arrays.

Processing movie2serial Program

The movie2serial Processing program can transmit video data to any number of Teensy boards running the VideoDisplay code. It is included inside the VideoDisplay example folder.

Processing is an open source programming environment. Arduino is based on Processing, so they share a similar user interface. Processing programs run on your computer, usually for graphics.


Processing can transmit video to any number of Teensy 3.0 boards.

Movie2serial receives most configuration information by querying the parameters stored in each Teensy. However, a few settings must be edited:

  1. edit myMovie to the video file to play.
  2. edit the port names on the serialConfigure lines in setup().
  3. (optional) if your LED strips have unusual wiring, edit colorWiring()
  4. (optional) if playing 50 or 60 Hz progressive video (or faster), edit framerate.


movie2serial program

The large image is the original video file. The small icon-size image above is the actual image sent to the LEDs. 1920 is a large number of LEDs, but relatively low image resolution for video.


Actual display on 1920 LEDs (view large original image)

This last photo was taken in a brightly lit room. The LEDs are incredibly bright, forcing the camera to low exposure, making the room look nearly pitch-black dark. Cameras really can't capture the live awesomeness of thousands of LEDs!

Signal Quality

While testing OctoWS2811, the 5 volt WS2811 chips were able to work with Teensy 3.0's 3.3 volt output signals. However, a series resistor located close to the Teensy 3.0 pin is often necessary to reduce ringing and cross-coupled signals.


Signal after 12 inches of wire

With 220 ohm resistor added

The series resistors help match Teensy's outputs to the characteristic impedance of your wiring. The best value to use depends on the type of wire and its spacing to nearby ground wires. Values in the range of 47 to 220 ohms are probably best.

Update: This OctoWS2811 Adaptor is now available, with the 74HCT245 buffer chip, 100 ohm resistors, and RJ-45 jacks for CAT6 cable, which exactly matches 100 ohm resistors. This adaptor is highly recommended for any large LED project. Please also follow its wiring recommendations, where the LED power supplies are located close to the LED strips using short wires for the power, and signal grounds from Teensy meet the power ground at or near the LED strip data inputs.


Place resistors close to the Teensy pins.

The WS2811 input high specification of "0.7*VDD". To truly meet this requirement, a buffer chip should be used to convert the 3.3 volt signal to 5 volts. A 74HCT245 is recommended.


Ryan wrote a detailed post about signal quality on the forum, with great investigation into signal corruption effects involving multiple power supplies, different resistors, and other issues. For anyone building a very large OctoWS2811-based installation, Ryan's writeup is worth reading!

Teensy 3.0 Power

Usually Teensy 3.0 should be powered by the same +5 volt power supply as the WS2811 LEDs. By default, Teensy 3.0 has VUSB connected to VIN. They can be separated by cutting apart pads on the bottom side of the board.


Power by VIN, not VUSB

Once cut apart, it is safe to apply +5 volt power to VIN. The USB cable will not attempt to power the LEDs, and the power supply will not feed power back to your computer.

When Teensy is powered by VIN, you can only load new code when VIN has power, because VUSB is disconnected.

LED Power Requirements

When illuminated at full brightness, each LED can consume approximately 0.25 Watts of power. For a large LED array, a very substantial 5 volt power source is required.


Three 5V, 40A power supplies used for 1920 LEDs

The 3 power supplies show above are some of the cheapest available from Ebay and Alibaba merchants. They must be attached to a large metal surface for adequate cooling. These 3 units arrived with their 120/240 volt input select switch missing (effectively leaving them in 240 volt mode, only able to run about 10% before losing regulation with 120 volts input).

Caution: ATX power supplies meant for PC computers are usually designed to deliver most of their power to the 12V lines. Even if the 5V output is rated for many amps, it may not be stable when there is no load on the 12V lines. Even name brand PC power supplies do this. In one severe case, the 5V line spiked to at least 9 volts, destroying a Teensy 3.0 board. Caution is advised with using any ATX power supply.

A strip of 60 LEDs can draw about 3 amps of current. Each strip should have its own connection directly to the power supply, using #22 or larger wire to avoid loss of voltage. Power can travel through about 2 meters of LED strip. If longer strips are used, both ends should be connected by wires directly to the power supply.

The LED power and Teensy 3.0 must have their grounds connected together.

A very large LED array can consume a tremendous amount of power. A standard 120V USA mains outlet can provide enough power for about 6000 LEDs. When building larger arrays, a 240 volt line may be needed.

Cheap power supplies lacking active power factor correction, when used in large numbers, may result is a very large inrush current surge when the AC power is applied. Extremely large LED projects should consider power supplies with inrush limiting and power factor correction. Also, if you build such an awesome LED project, please send photos!

WS2811 Idle Power

When the LED is off, the WS2811 chip consumes approximately 0.9 mA of current. For battery powered LEDs, this current can easily drain the battery. A P-channel MOSFET transistor or similar switch may be needed to disconnect power from the LEDs, if the battery remains connected when the LEDs are not in use.

This circuit was recommended by David Beaudry to manage the power. David also tested Vishay SUP75P03-07-E3 and SI4465ADY-T1-E3 transistors, which are able to power more LEDs.


OctoWS2811 Technical Details

OctoWS2811 is designed for highly efficient data output to WS2811-based LEDs, able scale to very large LED arrays. The WS2811 requires very specific waveform timing. Each LED uses 24 bits, each 1.25 µs, for a total of 30 µs per LED in the strip.


Driving 8 LED strips simultaneously allows each strip to be only 1/8th the length. All LEDs update 8X faster than driving only a single long strip. 1000 LEDs can be updated in 3.8 ms, which allows a theoretical update rate of 240 Hz.

The VideoDisplay example implements a Frame Sync signal, allowing many Teensy 3.0 boards to work together, each driving 1000 LEDs. The boards precisely synchronize their update, even if the USB delivers data to the many boards with some varying latency. Fast update times are preserved when scaling up to extremely large LED arrays.

OctoWS2811 uses Direct Memory Access (DMA) to create the WS2811 waveforms with nearly zero CPU usage. Because the CPU is free and interrupts remain enabled, the processor is free to receive data or perform computations in preparation for the next frame of display, while the previous one is still be transferred to the LEDs. The 8X faster update and free CPU time the key differences between OctoWS2811 and other libraries, which create the WS2811 waveforms for a single strip using carefully timed software.

DMA is a special hardware feature which allows data to be automatically moved between memory and I/O registers in response to hardware events, without any CPU usage (other than initially configuring parameters). OctoWS2811 uses 3 DMA channels to synthesize the WS2811 waveforms.


Three DMA Channels Synthesize WS2811 Waveform

The hardware events which trigger the DMA channels are a pair of PWM waveforms, corresponding to the WS2811 bit low and high waveforms. The rising edge (both PWM rise at the same moment) triggers channel #1, which copies a fixed byte (0xFF) to an I/O register which sets all 8 output bits, causing the WS2811 waveform to begin each bit. The first falling edge triggers DMA channel #2, which copies one byte of the actual frame buffer data to all 8 pins. The bits which are low transition to low at the correct time to create a zero bit to each WS2811 LED. The bits that are high have no effect, because channel #1 already set all 8 pins high. The 3rd DMA channel triggers at the second falling PWM edge, causing all the WS2811 bits to be written to zeros. The pins which were left high by channel #2, become low, as required by the WS2811 timing for a one bit. The pins which were already low are not changed. Together, these 3 I/O updates create a WS2811 waveform automatically without any CPU activity.

The ARM-based chip from Freescale used on Teensy 3.0 has crossbar switch and dual-bus RAM, which allows the DMA and ARM CPU to work together very efficiently.


Data flow with OctoWS2811

The crossbar switch allows 4 separate bus masters to access 4 different bus devices simultaneously. Only when 2 bus masters wish to access the same device at the same time is one master made to wait.

OctoWS2811 utilizes the dual-bus RAM and crossbar switch for maximum efficiency. The display memory is declared with "DMAMEM", which forces that memory to be allocated in the lower half of the RAM. USB buffers are also allocated in the lower RAM. The CPU accesses both, but the heavily used stack memory for local variables and temporary data is located in the upper RAM, which minimizes wait-inducing conflicts between the CPU and DMA. During normal operation, the CPU primarily accesses the upper RAM through a dedicated channel in the crossbar switch, which the DMA is able to read the lower half RAM and write to the I/O registers, also through crossbar switch paths that do not impact the ARM CPU's access to code and the most commonly accessed data. Of course, the USB also utilizes its own built-in DMA to transfer incoming data very efficiently into the lower RAM area.

Extremely efficient synthesis of the tight-timing WS2811 waveforms, with almost zero impact to the CPU is the primary benefit of OctoWS2811. The fast 32 bit CPU is fully available to prepare the next display frame. Interrupts remain enabled during transfers, allowing serial protocols like DMX to work. These features together with 8X faster updates and scalability to use many boards give OctoWS2811 the ability to make extremely large LED arrays very easy to implement with very high performance!

WS2811 Sources and Buying Guide

Adafruit's Neopixel and Flora RGB Smart Neo Pixel are probably the most user-friendly products, backed by a great USA-based company.

GreeLED is a Chinese manufacturer, usually the first to introduce newest LED products. They will sell small quantities to individuals, but you may need to send funds by wire transfer?

Alibaba/Aliexpress is a site offering consumer-level access to Asian vendors with great prices. Search for "WS2811". Many of them seem to be "Ray Wu". Usually you can expect fast shipping, but little or no post-sale service or technical support.

Ebay has many vendors reselling WS2811 LED products. If you prefer to use Paypal, Ebay may be the easist path. Like Alibaba, there is usually little or no post-sale service or support.

Most of these vendors also sell power supplies useful for LED projects.

For large LED project, you should purchase spares, especially if buying a large number of LEDs from an Alibaba or Ebay vendor. Numerous people have reported on forums a small number of bad LEDs within a large batch. The 1920 LED array PJRC constructed to develop and test this library has 3 LEDs that stop working after some time (perhaps overheating) and impact all others after them on the strip. One stops working within minutes, the others after a couple hours of use. These LEDs were purchased from Ray Wu via Aliexpress. It's possible to cut the strip and solder a replacement LED in, but only if you have spares on-hand.