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 Heroic Robotics

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

/media/uploads/bikeNomad/img_0482.jpg

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.

Files at this revision

API Documentation at this revision

Comitter:
heroic
Date:
Sun Sep 16 13:09:54 2012 +0000
Parent:
1:6ebd3ac910b6
Child:
3:a415f73507c9
Commit message:
Add extra functions and parameterize; support software SPI.

Changed in this revision

LPD8806.cpp Show annotated file Show diff for this revision Revisions of this file
LPD8806.h Show annotated file Show diff for this revision Revisions of this file
--- 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
 
--- a/LPD8806.h	Fri Dec 16 10:26:35 2011 +0000
+++ b/LPD8806.h	Sun Sep 16 13:09:54 2012 +0000
@@ -19,11 +19,17 @@
 
  public:
 
-  LPD8806(uint16_t n);
+  LPD8806(PinName dataPin, PinName clockPin, int n);
   void
     begin(void),
     show(void),
+    blank(void),
     setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b),
+    setPixelGB(uint16_t n, uint8_t g, uint8_t b),
+    setPixelB(uint16_t n, uint8_t b),
+    setPixelG(uint16_t n, uint8_t g),
+    setPixelR(uint16_t n, uint8_t r),
+    
     setPixelColor(uint16_t n, uint32_t c);
   uint16_t
     numPixels(void);
@@ -31,7 +37,9 @@
     Color(uint8_t, uint8_t, uint8_t);
 
  private:
-
+  DigitalOut dat;
+  DigitalOut clk;
+  void write(uint8_t byte);
   uint8_t
     *pixels;     // Holds LED color values
   uint16_t