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:
bikeNomad
Date:
Fri Dec 06 06:58:12 2013 +0000
Parent:
18:d98353e8c61c
Child:
20:b9d76e567637
Commit message:
added HSB/RGB conversions; removed unnecessary virtuals

Changed in this revision

Colors.cpp Show annotated file Show diff for this revision Revisions of this file
Colors.h Show annotated file Show diff for this revision Revisions of this file
LedStrip.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Colors.cpp	Fri Dec 06 06:58:12 2013 +0000
@@ -0,0 +1,90 @@
+#include <math.h>
+#include <mbed.h>
+#include "Colors.h"
+
+void HSBtoRGB(float hue, float saturation, float brightness, uint8_t *pr, uint8_t *pg, uint8_t *pb)
+{
+    uint8_t r = 0, g = 0, b = 0;
+    if (saturation == 0) {
+        r = g = b = (uint8_t) (brightness * 255.0f + 0.5f);
+    } else {
+        float h = (hue - (float)floor(hue)) * 6.0f;
+        float f = h - (float)floor(h);
+        float p = brightness * (1.0f - saturation);
+        float q = brightness * (1.0f - saturation * f);
+        float t = brightness * (1.0f - (saturation * (1.0f - f)));
+        switch ((int) h) {
+            case 0:
+                r = (int) (brightness * 255.0f + 0.5f);
+                g = (int) (t * 255.0f + 0.5f);
+                b = (int) (p * 255.0f + 0.5f);
+                break;
+            case 1:
+                r = (int) (q * 255.0f + 0.5f);
+                g = (int) (brightness * 255.0f + 0.5f);
+                b = (int) (p * 255.0f + 0.5f);
+                break;
+            case 2:
+                r = (int) (p * 255.0f + 0.5f);
+                g = (int) (brightness * 255.0f + 0.5f);
+                b = (int) (t * 255.0f + 0.5f);
+                break;
+            case 3:
+                r = (int) (p * 255.0f + 0.5f);
+                g = (int) (q * 255.0f + 0.5f);
+                b = (int) (brightness * 255.0f + 0.5f);
+                break;
+            case 4:
+                r = (int) (t * 255.0f + 0.5f);
+                g = (int) (p * 255.0f + 0.5f);
+                b = (int) (brightness * 255.0f + 0.5f);
+                break;
+            case 5:
+                r = (int) (brightness * 255.0f + 0.5f);
+                g = (int) (p * 255.0f + 0.5f);
+                b = (int) (q * 255.0f + 0.5f);
+                break;
+        }
+    }
+    *pr = r;
+    *pg = g;
+    *pb = b;
+}
+
+float* RGBtoHSB(uint8_t r, uint8_t g, uint8_t b, float* hsbvals)
+{
+    float hue, saturation, brightness;
+    if (!hsbvals) {
+        hsbvals = new float[3];
+    }
+    uint8_t cmax = (r > g) ? r : g;
+    if (b > cmax) cmax = b;
+    uint8_t cmin = (r < g) ? r : g;
+    if (b < cmin) cmin = b;
+
+    brightness = ((float) cmax) / 255.0f;
+    if (cmax != 0)
+        saturation = ((float) (cmax - cmin)) / ((float) cmax);
+    else
+        saturation = 0;
+    if (saturation == 0)
+        hue = 0;
+    else {
+        float redc = ((float) (cmax - r)) / ((float) (cmax - cmin));
+        float greenc = ((float) (cmax - g)) / ((float) (cmax - cmin));
+        float bluec = ((float) (cmax - b)) / ((float) (cmax - cmin));
+        if (r == cmax)
+            hue = bluec - greenc;
+        else if (g == cmax)
+            hue = 2.0f + redc - bluec;
+        else
+            hue = 4.0f + greenc - redc;
+        hue = hue / 6.0f;
+        if (hue < 0)
+            hue = hue + 1.0f;
+    }
+    hsbvals[0] = hue;
+    hsbvals[1] = saturation;
+    hsbvals[2] = brightness;
+    return hsbvals;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Colors.h	Fri Dec 06 06:58:12 2013 +0000
@@ -0,0 +1,51 @@
+#include <mbed.h>
+
+#ifndef __included_colors_h
+#define __included_colors_h
+
+/**
+ * Converts the components of a color, as specified by the HSB
+ * model, to an equivalent set of values for the default RGB model.
+ * <p>
+ * The <code>saturation</code> and <code>brightness</code> components
+ * should be floating-point values between zero and one
+ * (numbers in the range 0.0-1.0).  The <code>hue</code> component
+ * can be any floating-point number.  The floor of this number is
+ * subtracted from it to create a fraction between 0 and 1.  This
+ * fractional number is then multiplied by 360 to produce the hue
+ * angle in the HSB color model.
+ * <p>
+ * The integer that is returned by <code>HSBtoRGB</code> encodes the
+ * value of a color in bits 0-23 of an integer value that is the same
+ * format used by the method {@link #getRGB() <code>getRGB</code>}.
+ * This integer can be supplied as an argument to the
+ * <code>Color</code> constructor that takes a single integer argument.
+ * @param     hue   the hue component of the color
+ * @param     saturation   the saturation of the color
+ * @param     brightness   the brightness of the color
+ * @return    the RGB value of the color with the indicated hue,
+ *                            saturation, and brightness.
+ */
+void HSBtoRGB(float hue, float saturation, float brightness, uint8_t *pr, uint8_t *pg, uint8_t *pb);
+
+/**
+ * Converts the components of a color, as specified by the default RGB
+ * model, to an equivalent set of values for hue, saturation, and
+ * brightness that are the three components of the HSB model.
+ * <p>
+ * If the <code>hsbvals</code> argument is <code>null</code>, then a
+ * new array is allocated to return the result. Otherwise, the method
+ * returns the array <code>hsbvals</code>, with the values put into
+ * that array.
+ * @param     r   the red component of the color
+ * @param     g   the green component of the color
+ * @param     b   the blue component of the color
+ * @param     hsbvals  the array used to return the
+ *                     three HSB values, or <code>null</code>
+ * @return    an array of three elements containing the hue, saturation,
+ *                     and brightness (in that order), of the color with
+ *                     the indicated red, green, and blue components.
+ */
+float* RGBtoHSB(uint8_t r, uint8_t g, uint8_t b, float* hsbvals);
+
+#endif
--- a/LedStrip.h	Thu Dec 05 15:39:39 2013 +0000
+++ b/LedStrip.h	Fri Dec 06 06:58:12 2013 +0000
@@ -23,16 +23,19 @@
     virtual void show(void)=0;
     virtual void blank(void)=0;
 
+    static uint32_t Color(uint8_t r, uint8_t g, uint8_t b);
+
     uint16_t numPixels(void) { return numLEDs; }
     uint16_t numPixelBytes(void) { return numLEDs * 3; }
-    virtual uint32_t Color(uint8_t, uint8_t, uint8_t);
-    virtual uint32_t total_luminance(void);
-    virtual void setPixelB(uint16_t n, uint8_t b);
-    virtual void setPixelG(uint16_t n, uint8_t g);
-    virtual void setPixelR(uint16_t n, uint8_t r);
-    virtual void setPixelColor(uint16_t n, uint32_t c);
-    virtual void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b);
-    virtual void setPackedPixels(uint8_t * buffer, uint32_t n);
+    uint32_t total_luminance(void);
+
+    void setPixelB(uint16_t n, uint8_t b);
+    void setPixelG(uint16_t n, uint8_t g);
+    void setPixelR(uint16_t n, uint8_t r);
+    
+    void setPixelColor(uint16_t n, uint32_t c);
+    void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b);
+    void setPackedPixels(uint8_t * buffer, uint32_t n);
 
 protected:
     uint8_t *pixels;     // Holds LED color values
--- a/main.cpp	Thu Dec 05 15:39:39 2013 +0000
+++ b/main.cpp	Fri Dec 06 06:58:12 2013 +0000
@@ -1,7 +1,24 @@
 #include "mbed.h"
 #include "WS2811.h"
+#include "Colors.h"
 
 int main(void)
 {
-    WS2811 lightStrip(60*4, PTD2, PTD3);
+    const unsigned nLEDs = 60*4;
+
+    //                NLEDs  MOSI SCK
+    WS2811 lightStrip(nLEDs, PTD2, PTD3);
+
+    float sat = 1.0;
+    float brite = 0.25;
+    for (float hueShift = 0.0; hueShift < 10.0; hueShift += 1.0 / 20) {
+        for (unsigned i = 0; i < nLEDs; i++) {
+            uint8_t r, g, b;
+            float hue = ((float)i / (float)nLEDs) + hueShift;
+            HSBtoRGB(hue, sat, brite, &r, &g, &b);
+            lightStrip.setPixelColor(i, LedStrip::Color(r, g, b));
+        }
+        lightStrip.begin();
+        wait(0.5);
+    }
 }
\ No newline at end of file