Swift WS281x library




Version Platforms Architectures Languages License

swixel is a library for interfacing with WS281x-based LED lights. The goal is to support Raspberry Pi2, Beaglebone, and more.

Work has just begun, so if you interested in helping, drop me a line.

Protocol specification

Adafruit hosts the datasheet for the device. The best way to think of them is as a very long shift register that uses pulse-width modulation. By that I mean that there is no data and clock pins. One wire is used for communication. There are two speeds that are selectable when the chip is used, and it's likely selected by the manufacturer of the lights that you're using. I'm no expert on what's available, but the LEDs that I have use the high speed mode.

Low speed High speed
1 High period 1200 ± 150 nS 600 ± 75 nS
0 High period 500 ± 150 nS 250 ± 75 nS
1 Low period 1300 ± 150 nS 650 ± 75 nS
0 Low period 2000 ± 150 nS 1000 ± 75 nS
Total 2500 nS 1250 nS
Reset > 50 μS > 25 μS

During idle periods the pin should be low. There are a number of edge cases that may be useful or important while driving this protocol from linux systems. The reason for this is that relative a microcontroller it's much more difficult to precisely drive the protocol.

For example, the current implementation on the Beaglebone (ab)uses the SPI bus to generate the waveform. On the beagleone the idle state for SPI data out pin is high, so it's not obvious how to make it work. It would be possible to use a inverting level shifter, but that's not an avenue I've explored extensively yet.

Another consideration is that the WS2811 needs a high drive level 0.7*VDD > VIH > VDD+0.5. Most (if not all) ARM devices drive the output pins at a maximum of 3.3 volts. Therefore, some kind of level translator is necessary. I've used a dual-MOSFET non-inverting solution in most of my tests. Schematic Simulation Oscilloscope

The non-inverting converter burns about 5mA on average. To get a reasonable output of an inverting version, at least 7-10mA is necessary at idle.