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); } }