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.
Revision 7:3025f0e0d70a, committed 2012-10-12
- Comitter:
- heroic
- Date:
- Fri Oct 12 04:16:40 2012 +0000
- Parent:
- 6:7aebe547f0f0
- Child:
- 8:e3249c2b7607
- Commit message:
- Add logic to compute total luminance and hence current.
Changed in this revision
--- a/LedStrip.h Thu Oct 11 08:34:21 2012 +0000 +++ b/LedStrip.h Fri Oct 12 04:16:40 2012 +0000 @@ -24,5 +24,6 @@ virtual void setPixelColor(uint16_t n, uint32_t c)=0; virtual uint16_t numPixels(void)=0; virtual uint32_t Color(uint8_t, uint8_t, uint8_t)=0; + virtual uint32_t total_luminance(void); }; #endif \ No newline at end of file
--- a/WS2801.cpp Thu Oct 11 08:34:21 2012 +0000 +++ b/WS2801.cpp Fri Oct 12 04:16:40 2012 +0000 @@ -1,114 +1,123 @@ -// Mbed library to control LPD8806-based RGB LED Strips -// (c) 2011 Jelmer Tiete -// This library is ported from the Arduino implementation of Adafruit Industries -// found at: http://github.com/adafruit/LPD8806 -// and their strips: http://www.adafruit.com/products/306 -// Released under the MIT License: http://mbed.org/license/mit -// -// Parameterized and modified to use soft SPI. -// Jas Strong <jasmine@electronpusher.org> -/*****************************************************************************/ - -#include "LedStrip.h" -#include "WS2801.h" - -WS2801::WS2801(PinName dataPin, PinName clockPin, int n) : - dat(dataPin), - clk(clockPin) { - // Allocate 3 bytes per pixel: - numLEDs = n; - if ((pixels = (uint8_t *)malloc(numLEDs * 3))) { - memset(pixels, 0x00, numLEDs * 3); // Init to RGB 'off' state - } - guardtime.start(); -} - -/* - * 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 WS2801::write(uint8_t byte) { - for (int i=0; i<8; i++) { - clk = 0; - wait_us(WS2801_DELAY); - dat = (byte & 0x80); - clk = 1; - wait_us(WS2801_DELAY); - byte <<= 1; - } - clk = 0; -} - -void WS2801::begin(void) { - blank(); - show(); -} - -uint16_t WS2801::numPixels(void) { - return numLEDs; -} - -void WS2801::blank(void) { - memset(pixels, 0x00, numLEDs * 3); -} - -// This is how data is pushed to the strip. Unfortunately, the company -// that makes the chip didnt release the protocol document or you need -// to sign an NDA or something stupid like that, but we reverse engineered -// this from a strip controller and it seems to work very nicely! -void WS2801::show(void) { - uint16_t i, nl3 = numLEDs * 3; // 3 bytes per LED - while (guardtime.read_us() < 500) - /* spin */; - for (i=0; i<nl3; i++ ) { - write(pixels[i]); - } - - guardtime.reset(); -} - -// Convert R,G,B to combined 32-bit color -uint32_t WS2801::Color(uint8_t r, uint8_t g, uint8_t b) { - // Take the lowest 7 bits of each value and append them end to end - // We have the top bit set high (its a 'parity-like' bit in the protocol - // and must be set!) - return ((uint32_t)g << 16) | ((uint32_t)r << 8) | (uint32_t)b; -} - -// store the rgb component in our array -void WS2801::setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b) { - if (n >= numLEDs) return; // '>=' because arrays are 0-indexed - - pixels[n*3 ] = g; - pixels[n*3+1] = r; - pixels[n*3+2] = b; -} - -void WS2801::setPixelR(uint16_t n, uint8_t r) { - if (n >= numLEDs) return; // '>=' because arrays are 0-indexed - - pixels[n*3+1] = r; -} - -void WS2801::setPixelG(uint16_t n, uint8_t g) { - if (n >= numLEDs) return; // '>=' because arrays are 0-indexed - - pixels[n*3] = g; -} - -void WS2801::setPixelB(uint16_t n, uint8_t b) { - if (n >= numLEDs) return; // '>=' because arrays are 0-indexed - - pixels[n*3+2] = b; -} - -void WS2801::setPixelColor(uint16_t n, uint32_t c) { - if (n >= numLEDs) return; // '>=' because arrays are 0-indexed - - pixels[n*3 ] = (c >> 16); - pixels[n*3+1] = (c >> 8); - pixels[n*3+2] = c; -} +// Mbed library to control LPD8806-based RGB LED Strips +// (c) 2011 Jelmer Tiete +// This library is ported from the Arduino implementation of Adafruit Industries +// found at: http://github.com/adafruit/LPD8806 +// and their strips: http://www.adafruit.com/products/306 +// Released under the MIT License: http://mbed.org/license/mit +// +// Parameterized and modified to use soft SPI. +// Jas Strong <jasmine@electronpusher.org> +/*****************************************************************************/ + +#include "LedStrip.h" +#include "WS2801.h" + +WS2801::WS2801(PinName dataPin, PinName clockPin, int n) : + dat(dataPin), + clk(clockPin) { + // Allocate 3 bytes per pixel: + numLEDs = n; + if ((pixels = (uint8_t *)malloc(numLEDs * 3))) { + memset(pixels, 0x00, numLEDs * 3); // Init to RGB 'off' state + } + guardtime.start(); +} + +/* + * 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 WS2801::write(uint8_t byte) { + for (int i=0; i<8; i++) { + clk = 0; + wait_us(WS2801_DELAY); + dat = (byte & 0x80); + clk = 1; + wait_us(WS2801_DELAY); + byte <<= 1; + } + clk = 0; +} + +void WS2801::begin(void) { + blank(); + show(); +} + +uint16_t WS2801::numPixels(void) { + return numLEDs; +} + +void WS2801::blank(void) { + memset(pixels, 0x00, numLEDs * 3); +} + +// This is how data is pushed to the strip. Unfortunately, the company +// that makes the chip didnt release the protocol document or you need +// to sign an NDA or something stupid like that, but we reverse engineered +// this from a strip controller and it seems to work very nicely! +void WS2801::show(void) { + uint16_t i, nl3 = numLEDs * 3; // 3 bytes per LED + while (guardtime.read_us() < 500) + /* spin */; + for (i=0; i<nl3; i++ ) { + write(pixels[i]); + } + + guardtime.reset(); +} + + +uint32_t WS2801::total_luminance(void) { + uint32_t running_total; + running_total = 0; + for (int i=0; i<numLEDs*3; i++) + running_total += pixels[i]; + return running_total; +} + +// Convert R,G,B to combined 32-bit color +uint32_t WS2801::Color(uint8_t r, uint8_t g, uint8_t b) { + // Take the lowest 7 bits of each value and append them end to end + // We have the top bit set high (its a 'parity-like' bit in the protocol + // and must be set!) + return ((uint32_t)g << 16) | ((uint32_t)r << 8) | (uint32_t)b; +} + +// store the rgb component in our array +void WS2801::setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b) { + if (n >= numLEDs) return; // '>=' because arrays are 0-indexed + + pixels[n*3 ] = g; + pixels[n*3+1] = r; + pixels[n*3+2] = b; +} + +void WS2801::setPixelR(uint16_t n, uint8_t r) { + if (n >= numLEDs) return; // '>=' because arrays are 0-indexed + + pixels[n*3+1] = r; +} + +void WS2801::setPixelG(uint16_t n, uint8_t g) { + if (n >= numLEDs) return; // '>=' because arrays are 0-indexed + + pixels[n*3] = g; +} + +void WS2801::setPixelB(uint16_t n, uint8_t b) { + if (n >= numLEDs) return; // '>=' because arrays are 0-indexed + + pixels[n*3+2] = b; +} + +void WS2801::setPixelColor(uint16_t n, uint32_t c) { + if (n >= numLEDs) return; // '>=' because arrays are 0-indexed + + pixels[n*3 ] = (c >> 16); + pixels[n*3+1] = (c >> 8); + pixels[n*3+2] = c; +}
--- a/WS2801.h Thu Oct 11 08:34:21 2012 +0000 +++ b/WS2801.h Fri Oct 12 04:16:40 2012 +0000 @@ -32,6 +32,7 @@ virtual void setPixelColor(uint16_t n, uint32_t c); virtual uint16_t numPixels(void); virtual uint32_t Color(uint8_t, uint8_t, uint8_t); + virtual uint32_t total_luminance(void); private: DigitalOut dat;