WS2812/SK6812 RGB LED (NeoPixel)

Driver for the WS2812 or the SK6812 RGB LEDs sold as NeoPixel. More...

Detailed Description

Driver for the WS2812 or the SK6812 RGB LEDs sold as NeoPixel.

Summary

The WS2812 or SK6812 RGB LEDs, or more commonly known as NeoPixels, can be chained so that a single data pin of the MCU can control an arbitrary number of RGB LEDs. This driver supports both the WS2812/SK6812 and the WS2812b LEDs.

Support

The protocol to communicate with the WS281x is custom, so no hardware implementations can be used. Hence, the protocol needs to be bit banged in software. As the timing requirements are too strict to do this using the platform independent APIs for accessing GPIO and Timers, platform specific implementations of ws281x_write are needed.

ATmega

A bit banging implementation for ATmegas clocked at 8MHz and at 16MHz is provided. Boards clocked at any other core frequency are not supported. (But keep in mind that most (all?) ATmega MCUs do have an internal 8MHz oscillator, that could be enabled by changing the fuse settings.)

Warning
On 8MHz ATmegas, only pins at GPIO ports B, C, and D are supported. (On 16MHz ATmegas, any pin is fine.)

ESP32

The ESP32 implementation is frequency independent, as frequencies above 80MHz are high enough to support bit banging without assembly.

Native/VT100

The native (VT100) implementation writes the LED state to the console.

Usage

Add the following to your Makefile:

This will automatically pull in one of the backends supported by your board. In case multiple backends apply and the automatic selection does not pick your preferred backend, you can manually pick your preferred backend as described below.

Files

file  ws281x.h
 WS2812/SK6812 RGB LED Driver.
 
file  ws281x_backend.h
 Backend configuration for WS2812/SK6812 RGB LEDs.
 
file  ws281x_constants.h
 Constants for WS2812/SK6812 RGB LEDs.
 
file  ws281x_params.h
 Default configuration for WS2812/SK6812 RGB LEDs.
 

Data Structures

struct  ws281x_params_t
 Struct to hold initialization parameters for a WS281x RGB LED. More...
 
struct  ws281x_t
 Device descriptor of a WS281x RGB LED chain. More...
 

Macros

#define WS281X_BYTES_PER_DEVICE   (3U)
 The number of bytes to allocate in the data buffer per LED.
 

Functions

int ws281x_init (ws281x_t *dev, const ws281x_params_t *params)
 Initialize an WS281x RGB LED chain. More...
 
void ws281x_write_buffer (ws281x_t *dev, const void *buf, size_t size)
 Writes the color data of the user supplied buffer. More...
 
void ws281x_prepare_transmission (ws281x_t *dev)
 Sets up everything needed to write data to the WS281X LED chain. More...
 
void ws281x_end_transmission (ws281x_t *dev)
 Ends the transmission to the WS2812/SK6812 LED chain. More...
 
void ws281x_set_buffer (void *dest, uint16_t index, color_rgb_t color)
 Sets the color of an LED in the given data buffer. More...
 
static void ws281x_set (ws281x_t *dev, uint16_t index, color_rgb_t color)
 Sets the color of an LED in the chain in the internal buffer. More...
 
static void ws281x_write (ws281x_t *dev)
 Writes the internal buffer to the LED chain. More...
 

Function Documentation

◆ ws281x_end_transmission()

void ws281x_end_transmission ( ws281x_t dev)

Ends the transmission to the WS2812/SK6812 LED chain.

Parameters
devDevice descriptor of the LED chain to write to

Does any cleanup the backend needs after sending data. In the simplest case it simply waits for 80µs to send the end of transmission signal.

◆ ws281x_init()

int ws281x_init ( ws281x_t dev,
const ws281x_params_t params 
)

Initialize an WS281x RGB LED chain.

Parameters
devDevice descriptor to initialize
paramsParameters to initialize the device with
Return values
0Success
-EINVALInvalid argument
-EIOFailed to initialize the data GPIO pin

◆ ws281x_prepare_transmission()

void ws281x_prepare_transmission ( ws281x_t dev)

Sets up everything needed to write data to the WS281X LED chain.

Parameters
devDevice descriptor of the LED chain to write to

◆ ws281x_set()

static void ws281x_set ( ws281x_t dev,
uint16_t  index,
color_rgb_t  color 
)
inlinestatic

Sets the color of an LED in the chain in the internal buffer.

Parameters
devDevice descriptor of the LED chain to modify
indexThe index of the LED to set the color of
colorThe new color to apply
Warning
This change will not become active until ws281x_write is called

Definition at line 230 of file ws281x.h.

◆ ws281x_set_buffer()

void ws281x_set_buffer ( void *  dest,
uint16_t  index,
color_rgb_t  color 
)

Sets the color of an LED in the given data buffer.

Parameters
destBuffer to set the color in
indexThe index of the LED to set the color of
colorThe new color to apply
Warning
This change will not become active until ws281x_write is called

◆ ws281x_write()

static void ws281x_write ( ws281x_t dev)
inlinestatic

Writes the internal buffer to the LED chain.

Parameters
devDevice descriptor of the LED chain to write to
Note
This function implicitly calls ws281x_end_transmission
See also
ws281x_set

Definition at line 243 of file ws281x.h.

◆ ws281x_write_buffer()

void ws281x_write_buffer ( ws281x_t dev,
const void *  buf,
size_t  size 
)

Writes the color data of the user supplied buffer.

Parameters
devDevice descriptor of the LED chain to write to
bufBuffer to write
sizeSize of the buffer in bytes
Precondition
Before the transmission starts ws281x_prepare_transmission is called
Postcondition
At the end of the transmission ws281x_end_transmission is called

This function can be used to drive a huge number of LEDs with small data buffers. However, after the return of this function the next chunk should be send within a few microseconds to avoid accidentally sending the end of transmission signal.

Usage:

uint8_t chunk[CHUNK_SIZE];
while (more_chunks_available()) {
prepare_chunk(chunk);
ws281x_write_buffer(ws281x_dev, chunk, sizeof(chunk));
}
ws281x_prepare_transmission
void ws281x_prepare_transmission(ws281x_t *dev)
Sets up everything needed to write data to the WS281X LED chain.
ws281x_write_buffer
void ws281x_write_buffer(ws281x_t *dev, const void *buf, size_t size)
Writes the color data of the user supplied buffer.
ws281x_end_transmission
void ws281x_end_transmission(ws281x_t *dev)
Ends the transmission to the WS2812/SK6812 LED chain.