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: main.cpp
- Revision:
- 39:e735259e1d2e
- Parent:
- 38:3b1ce6902a1b
- Child:
- 40:d5c8ce80b6c4
diff -r 3b1ce6902a1b -r e735259e1d2e main.cpp
--- a/main.cpp Sat Jun 13 00:18:26 2015 -0700
+++ b/main.cpp Mon Jun 15 07:24:39 2015 -0700
@@ -37,21 +37,30 @@
static MMA8451Q acc(PTE25, PTE24, MMA8451_I2C_ADDRESS);
// RGB LED on FRDM board
-static PwmOut rled(LED_RED); // max = 0.0
-static PwmOut gled(LED_GREEN); // max = 0.0
+static DigitalOut rled(LED_RED); // max = 0.0
+static DigitalOut gled(LED_GREEN); // max = 0.0
// LED_BLUE is on PTD1
-static PwmOut eyes(D3); // also redLED1; max = 1.0
-static PwmOut servo(D5);
-static DigitalOut greenLED2(D4); // max = 1.0
+// D0, D1 are out. D3-D7 are OK
+// D4 doesn't work.
+// D5 is original.
+// D6 doesn't work.
+// D7 doesn't work.
+// D3 works for eyes.
+static PwmOut servo(D3); // PTA5
+static DigitalOut eyes(D5); // PTA2 also redLED1; max = 1.0
+
+// static DigitalOut greenLED2(D4); // max = 1.0
static DigitalIn button1(D6); // low=ON, debounced
-static DigitalIn button2(D7); // low=ON, debounced
+// static DigitalIn button2(D7); // low=ON, debounced
// Limits
const float maxBrite = 0.5;
const float minServo = -0.7; // -1.0 = -60°
const float maxServo = 0.6; // 1.0 = +60°
-const float minFlapTime = (maxServo - minServo) * 0.17; // 0.17 seconds / 60° at 4.8V
+
+// const float minFlapTime = (maxServo - minServo) * 0.17; // 0.17 seconds / 60° at 4.8V
+const float minFlapTime = 0.5;
const float maxFlapTime = 1.0;
// Globals
@@ -65,12 +74,7 @@
const float speedUpdateInterval = 0.1;
static Ticker speedUpdateTicker;
-static Ticker eyeUpdateTicker;
-
-static Ticker stripUpdateTicker;
-
static float wingFlapTime = maxFlapTime;
-static Ticker wingUpdateTicker;
// we have to know delta T to compute speed.
// So this is called at speedUpdateInterval seconds intervals.
@@ -91,15 +95,32 @@
// @param sat saturation, 0.0 - 1.0
// @param brite brightness, 0.0 - 1.0
// @param hueShift shift, 0.0 - 1.0 is equivalent to 0 - 360 degrees
-static void showRainbow(MyWS2811 &strip, float sat, float brite, float hueShift, float hueRange = 1.0)
+static void showRainbow(MyWS2811 &strip, float sat, float brite, float hueShift, float hueRange = 1.0, int span = 1, int skip=0)
{
- unsigned nLEDs = strip.numPixels();
- for (unsigned i = 0; i < nLEDs; i++)
+ int nLEDs = strip.numPixels();
+ int direction, first, last;
+
+ if (span < 0) {
+ direction = -1;
+ first = nLEDs-1;
+ last = -1;
+ span = -span;
+ skip = -skip;
+ } else {
+ direction = 1;
+ first = 0;
+ last = nLEDs;
+ }
+
+ for (int i = first; i != last; i += direction)
{
uint8_t r, g, b;
float hue = (i * hueRange / nLEDs) + hueShift;
HSBtoRGB(hue, sat, brite, &r, &g, &b);
- strip.setPixelColor(i, r, g, b);
+ if ((i + skip) % span == 0)
+ strip.setPixelColor((unsigned)i, r, g, b);
+ else
+ strip.setPixelColor((unsigned)i, 0, 0, 0);
}
strip.show();
}
@@ -123,15 +144,15 @@
pos = maxServo;
if (pos < 0.0) {
- rled = pos + 1.0;
- gled = 1.0;
+ rled = 0;
+ gled = 1;
}
else if (pos > 0.0) {
- rled = 1.0;
- gled = 1.0 - pos ;
+ rled = 1;
+ gled = 0;
}
else {
- rled = gled = 0.5;
+ rled = gled = 1;
}
servo.pulsewidth_us((1.5 + (pos / 2.0)) * 1000.0);
@@ -153,18 +174,18 @@
static void selfTestLEDs()
{
pc.printf("LEDs .");
- rled = 0.0; // red LED on
+ rled = 0; // red LED on
wait(0.5);
pc.printf(".");
- rled = 1.0; // red LED off, green LED on
- gled = 0.0;
+ rled = 1; // red LED off, green LED on
+ gled = 0;
wait(0.5);
pc.printf(".");
- gled = 1.0; // green LED off, eyes on
- eyes = 1.0;
+ gled = 1; // green LED off, eyes on
+ eyes = 1;
wait(0.5);
pc.printf(".");
- eyes = 0.0;
+ eyes = 0;
pc.printf("\r\n");
}
@@ -207,47 +228,24 @@
{
pc.printf("self test: ");
+ selfTestLightStrips();
selfTestServo();
selfTestLEDs();
- selfTestLightStrips();
-}
-
-void updateEyes()
-{
- static float brite = 1.0;
- static float increment = -0.1;
-
- eyes = brite;
-
- brite += increment;
- if (brite >= 1.0)
- {
- increment = -0.05;
- brite = 1.0;
- }
- else if (brite <= 0.0)
- {
- increment = 0.05;
- brite = 0.0;
- }
}
// rainbow that wraps around entire frame
void updateStripsRainbow()
{
- showRainbow(lightStrip1, 1.0, maxBrite, currentSpeed, 0.5);
- showRainbow(lightStrip2, 1.0, maxBrite, currentSpeed + 0.5, 0.5);
+ static int skip = 0;
+
+ showRainbow(lightStrip1, 1.0, maxBrite, currentSpeed, 0.5, 3, skip);
+ showRainbow(lightStrip2, 1.0, maxBrite, currentSpeed + 0.5, 0.5, -3, skip);
refreshLightStrips();
+ skip++;
+ skip %= 3;
}
-// callback
-void updateWings()
-{
- static float currentPosition = 1.0;
-
- currentPosition = -currentPosition;
- positionServo(currentPosition);
-}
+static float currentPosition = 0.0;
void setWingFlapTime(float desired)
{
@@ -260,8 +258,6 @@
if (lastWingFlapTime != wingFlapTime)
{
- wingUpdateTicker.detach();
- wingUpdateTicker.attach(updateWings, wingFlapTime);
lastWingFlapTime = wingFlapTime;
}
}
@@ -276,31 +272,39 @@
rled = 1.0;
gled = 1.0;
- greenLED2 = 0.0;
+// greenLED2 = 0.0;
servo.period_ms(20);
selfTest();
- eyeUpdateTicker.attach(updateEyes, 0.05);
- wingUpdateTicker.attach(updateWings, wingFlapTime);
-
resetSpeedAndAcceleration();
speedUpdateTicker.attach(updateSpeedAndAcceleration, speedUpdateInterval);
- stripUpdateTicker.attach(updateStripsRainbow, 0.1);
+ Timer elapsedTime;
+ elapsedTime.start();
+ float nextWingUpdate = elapsedTime.read();
+ float nextStripUpdate = nextWingUpdate;
+ float nextEyeUpdate = nextWingUpdate;
+ currentPosition = -1.0;
+
+ float stripUpdateTime = 0.3;
+ float eyeUpdateTime = 0.3;
+ bool eyesOn = true;
float lastCurrentSpeed = 0.0;
for (;; )
{
float relativeAccel = fabs(currentZAccel - restZAccel);
- if ((relativeAccel < 1.0) || !button2.read())
+ if ((relativeAccel < 1.0) || !button1.read())
{
resetSpeedAndAcceleration();
setWingFlapTime(maxFlapTime);
+ stripUpdateTime = 0.3;
}
else
{
setWingFlapTime(minFlapTime);
+ stripUpdateTime = 0.1;
}
if (lastCurrentSpeed != currentSpeed)
@@ -308,6 +312,27 @@
lastCurrentSpeed = currentSpeed;
pc.printf("%f %f %f\r\n", relativeAccel, currentSpeed, wingFlapTime);
}
- wait(0.1);
+
+ float now = elapsedTime.read();
+
+ if (now >= nextWingUpdate) {
+ positionServo(currentPosition);
+ currentPosition = -currentPosition;
+ nextWingUpdate = now + wingFlapTime;
+ }
+
+ if (now >= nextStripUpdate) {
+ updateStripsRainbow();
+ nextStripUpdate = now + stripUpdateTime;
+ }
+
+ if (now >= nextEyeUpdate) {
+ if (eyesOn) eyes = 1;
+ else eyes = 0;
+ eyesOn = !eyesOn;
+ nextEyeUpdate = now + eyeUpdateTime;
+ }
+
+ wait(0.05);
}
}
Ned Konz


Generic WS2811/WS2812