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 19:600deef36348, committed 2013-12-06
- 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
--- /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