Userspace Raspberry Pi PWM library for WS281X LEDs
C Python Go
Latest commit 08ebf2e Jan 29, 2017 @kevmar kevmar committed with Fix sliced pixel setter/getter functions. (#145)
* Fix sliced pixel get/set functions by adding a missing tuple unpack operation.

* Use xrange instead of range.
Permalink
Failed to load latest commit information.
golang/ws2811 Add go (golang) support Dec 30, 2015
python Fix sliced pixel setter/getter functions. (#145) Jan 29, 2017
.gitignore no one wants my vim .swp files! May 9, 2016
LICENSE Initial commit Sep 3, 2014
README.md Add comment about /etc/modules to blacklisting instructions. Nov 5, 2016
SConscript Add version builder and version file. Jul 16, 2016
SConstruct Add version builder and version file. Jul 16, 2016
clk.h Add aligned attribute to avoid issues with gcc5+ when accessing regis… Mar 25, 2016
dma.c Clean up compiler warnings, including 64-bit. Even though the code do… Dec 21, 2015
dma.h Add aligned attribute to avoid issues with gcc5+ when accessing regis… Mar 25, 2016
gpio.h Add aligned attribute to avoid issues with gcc5+ when accessing regis… Mar 25, 2016
linux.py Add -fPIC to resolve unknown symbol during link. Issue #38. Dec 31, 2015
mailbox.c Refactoring of mailbox.c. Fixes munmap error. Jan 5, 2016
mailbox.h Add support for RPI2 and 4.1 kernels (using /dev/vcio). Oct 5, 2015
main.c fix argument parsing for --clear (#147) Jan 29, 2017
pwm.c Add multiple channel support and code cleanups. Oct 22, 2014
pwm.h Add aligned attribute to avoid issues with gcc5+ when accessing regis… Mar 25, 2016
rpihw.c support RPi CM3 (#148) Jan 29, 2017
rpihw.h Finish RPI2 changes. Ready for testing. Oct 5, 2015
version Update version to reflect new Pi hardware support. Nov 19, 2016
version.py Add version builder and version file. Jul 16, 2016
ws2811.c Added error codes and string representations Nov 5, 2016
ws2811.h Added error codes and string representations Nov 5, 2016

README.md

rpi_ws281x

Userspace Raspberry Pi PWM library for WS281X LEDs This includes WS2812 and SK6812RGB RGB LEDs Preliminary support is now included for SK6812RGBW LEDs (yes, RGB + W)

Background:

The BCM2835 in the Raspberry Pi has a PWM module that is well suited to driving individually controllable WS281X LEDs. Using the DMA, PWM FIFO, and serial mode in the PWM, it's possible to control almost any number of WS281X LEDs in a chain connected to the PWM output pin.

This library and test program set the clock rate of the PWM controller to 3X the desired output frequency and creates a bit pattern in RAM from an array of colors where each bit is represented by 3 bits for the PWM controller as follows.

Bit 1 - 1 1 0
Bit 0 - 1 0 0

Hardware:

WS281X LEDs are generally driven at 5V, which requires that the data signal be at the same level. Converting the output from a Raspberry Pi GPIO/PWM to a higher voltage through a level shifter is required.

It is possible to run the LEDs from a 3.3V - 3.6V power source, and connect the GPIO directly at a cost of brightness, but this isn't recommended.

The test program is designed to drive a 8x8 grid of LEDs from Adafruit (http://www.adafruit.com/products/1487). Please see the Adafruit website for more information.

Know what you're doing with the hardware and electricity. I take no reponsibility for damage, harm, or mistakes.

Build:

  • Install Scons (on raspbian, apt-get install scons).
  • Make sure to adjust the parameters in main.c to suit your hardare.
    • Signal rate (400kHz to 800kHz). Default 800kHz.
    • ledstring.invert=1 if using a inverting level shifter.
    • Width and height of LED matrix (height=1 for LED string).
  • Type 'scons' from inside the source directory.

Running:

  • Type 'sudo scons'.
  • Type 'sudo ./test'.
  • That's it. You should see a moving rainbow scroll across the display.

Limitations:

Since this library and the onboard Raspberry Pi audio both use the PWM, they cannot be used together. You will need to blacklist the Broadcom audio kernel module by creating a file /etc/modprobe.d/snd-blacklist.conf with

blacklist snd_bcm2835

If the audio device is still loading after blacklisting, you may also need to comment it out in the /etc/modules file.

Some distributions use audio by default, even if nothing is being played. If audio is needed, you can use a USB audio device instead.

Usage:

The API is very simple. Make sure to create and initialize the ws2811_t structure as seen in main.c. From there it can be initialized by calling ws2811_init(). LEDs are changed by modifying the color in the .led[index] array and calling ws2811_render(). The rest is handled by the library, which creates the DMA memory and starts the DMA/PWM.

Make sure to hook a signal handler for SIGKILL to do cleanup. From the handler make sure to call ws2811_fini(). It'll make sure that the DMA is finished before program execution stops.

That's it. Have fun. This was a fun little weekend project. I hope you find it useful.