Test program for my Multi_WS2811 library that started out as a fork of heroic/WS2811. My library uses hardware DMA on the FRDM-KL25Z to drive up to 16 strings of WS2811 or WS2812 LEDs in parallel.
Dependencies: Multi_WS2811 mbed MMA8451Q
Fork of WS2811 by
NOTE: I have accidentally pushed changes for another fork of this program that I used in the recent Georgetown Carnival Power Tool Races. When I get some time, I will restore the test program to its original glory.
You can see my power tool racer (Nevermore's Revenge) here

This tests my FRDM-KL25Z multi-string WS2811/WS2812 library. It uses the accelerometer to change the rainbow phase on two strings of LEDs as well as the touch sense to change brightness.
A video of this program in operation is here.
Here is the library that I developed to run the LEDs:
Import libraryMulti_WS2811
Library allowing up to 16 strings of 60 WS2811 or WS2812 LEDs to be driven from a single FRDM-KL25Z board. Uses hardware DMA to do a full 800 KHz rate without much CPU burden.
Diff: LPD8806.cpp
- Revision:
- 2:af5af64e114d
- Parent:
- 1:6ebd3ac910b6
- Child:
- 3:a415f73507c9
--- a/LPD8806.cpp Fri Dec 16 10:26:35 2011 +0000
+++ b/LPD8806.cpp Sun Sep 16 13:09:54 2012 +0000
@@ -5,33 +5,40 @@
// and their strips: http://www.adafruit.com/products/306
// Released under the MIT License: http://mbed.org/license/mit
//
-// standard connected to 1st hardware SPI
-// LPD8806 <> MBED
-// DATA -> P5
-// CLOCK -> p7
+// Parameterized and modified to use soft SPI.
+// Jas Strong <jasmine@electronpusher.org>
/*****************************************************************************/
#include "LPD8806.h"
-//Define SPI pins
-//Connected to first SPI module
-SPI spi(p5, p6, p7); // mosi, miso, sclk
-//SPI spi(p11, p12, p13); // mosi, miso, sclk
-
-LPD8806::LPD8806(uint16_t n) {
+LPD8806::LPD8806(PinName dataPin, PinName clockPin, int n) :
+ dat(dataPin),
+ clk(clockPin) {
// Allocate 3 bytes per pixel:
+ numLEDs = n;
if (NULL != (pixels = (uint8_t *)malloc(numLEDs * 3))) {
memset(pixels, 0x80, numLEDs * 3); // Init to RGB 'off' state
- numLEDs = n;
}
}
-void LPD8806::begin(void) {
+/*
+ * Soft SPI clock-out implementation (CPOL = 0, CPHA = 0).
+ * Certainly not the fastest in the world but it'll do.
+ * Gets about 3.6 MHz; could get several times as much
+ * using the bitbands directly - jas.
+ */
+
+void LPD8806::write(uint8_t byte) {
+ for (int i=0; i<8; i++) {
+ clk = 0;
+ dat = (byte & 0x80);
+ clk = 1;
+ byte <<= 1;
+ }
+ clk = 0;
+}
- // Setup the spi for 8 bit data, low steady state clock,
- // first edge capture, with a 2MHz clock rate
- spi.format(8,0);
- spi.frequency(2000000);
+void LPD8806::begin(void) {
// Issue initial latch to 'wake up' strip (latch length varies w/numLEDs)
writezeros(3 * ((numLEDs + 63) / 64));
@@ -42,7 +49,11 @@
}
void LPD8806::writezeros(uint16_t n) {
- while (n--) spi.write(0x00);
+ while (n--) write(0x00);
+}
+
+void LPD8806::blank(void) {
+ memset(pixels, 0x80, numLEDs * 3);
}
// This is how data is pushed to the strip. Unfortunately, the company
@@ -53,15 +64,11 @@
uint16_t i, nl3 = numLEDs * 3; // 3 bytes per LED
for (i=0; i<nl3; i++ ) {
- spi.write(pixels[i]);
+ write(pixels[i]);
}
// Write latch at end of data; latch length varies with number of LEDs
writezeros(3 * ((numLEDs + 63) / 64));
-
- // We need to have a delay here, a few ms seems to do the job
- // shorter may be OK as well - need to experiment :(
-// wait_ms(3);
}
// Convert R,G,B to combined 32-bit color
@@ -81,6 +88,31 @@
pixels[n*3+2] = b | 0x80;
}
+void LPD8806::setPixelGB(uint16_t n, uint8_t g, uint8_t b) {
+ if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
+
+ pixels[n*3 ] = g | 0x80;
+ pixels[n*3+2] = b | 0x80;
+}
+
+void LPD8806::setPixelR(uint16_t n, uint8_t r) {
+ if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
+
+ pixels[n*3+1] = r | 0x80;
+}
+
+void LPD8806::setPixelG(uint16_t n, uint8_t g) {
+ if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
+
+ pixels[n*3] = g | 0x80;
+}
+
+void LPD8806::setPixelB(uint16_t n, uint8_t b) {
+ if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
+
+ pixels[n*3+2] = b | 0x80;
+}
+
void LPD8806::setPixelColor(uint16_t n, uint32_t c) {
if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
Ned Konz


Generic WS2811/WS2812