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:
- 40:d5c8ce80b6c4
- Parent:
- 39:e735259e1d2e
--- a/main.cpp Mon Jun 15 07:24:39 2015 -0700 +++ b/main.cpp Fri Jun 10 08:56:46 2016 -0700 @@ -7,11 +7,22 @@ #define INSTANTIATE_TEMPLATES 1 #include "WS2811.h" +#include "audio.h" +using namespace NKAudio; + +#include "1khz_1sec.h" + +AudioFile audioFiles[] = { + { __1khz_1sec_s8, __1khz_1sec_s8_len }, + { 0, 0 } // mark end +}; + // I/O pin usage // PTD2 (D11) data output for strip# 1 // PTD3 (D12) data output for strip# 2 -// PTA2 (D3) blinking eyes output (HI = ON) -// PTA5 (D5) servomotor (20 msec period; 1.0-2.0msec ON) +// PTA12 (D3) servomotor (20 msec period; 1.0-2.0msec ON) +// PTA5 (D5) blinking eyes output (HI = ON) +// PTE30 const unsigned DATA_OUT_PIN1 = 2; // PTD2 const unsigned DATA_OUT_PIN2 = 3; // PTD3 @@ -37,18 +48,12 @@ static MMA8451Q acc(PTE25, PTE24, MMA8451_I2C_ADDRESS); // RGB LED on FRDM board -static DigitalOut rled(LED_RED); // max = 0.0 -static DigitalOut gled(LED_GREEN); // max = 0.0 +static DigitalOut rled(LED_RED); // PTB18 max = 0.0 +static DigitalOut gled(LED_GREEN); // PTB19 max = 0.0 // LED_BLUE is on PTD1 -// 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 PwmOut servo(D3); // PTA12 +static DigitalOut eyes(D5); // PTA5 // static DigitalOut greenLED2(D4); // max = 1.0 static DigitalIn button1(D6); // low=ON, debounced @@ -62,33 +67,8 @@ // 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 -// test run was about 6 meters in about 5 seconds, for -// a final velocity of 2.4m/s, and a uniform acceleration of 0.48 m/s^2 -// or about 0.048g -static float restZAccel; // in m/s^2 1g = 9.8 m/s^2 -static float currentZAccel; // in m/s^2 -static float currentSpeed; // in m/s - -const float speedUpdateInterval = 0.1; -static Ticker speedUpdateTicker; - -static float wingFlapTime = maxFlapTime; - -// we have to know delta T to compute speed. -// So this is called at speedUpdateInterval seconds intervals. -static void updateSpeedAndAcceleration() -{ - currentZAccel = acc.getAccZ() * 9.8; - currentSpeed += (currentZAccel - restZAccel) * speedUpdateInterval; -} - -static void resetSpeedAndAcceleration() -{ - restZAccel = currentZAccel; - currentSpeed = 0.0; -} +float currentPosition = 1.0; +float currentSpeed = 1.0; // @brief sets different colors in each of the LEDs of a strip // @param strip the light strip @@ -112,8 +92,7 @@ last = nLEDs; } - for (int i = first; i != last; i += direction) - { + 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); @@ -128,8 +107,7 @@ static void showSolidColor(MyWS2811 &strip, uint8_t r, uint8_t g, uint8_t b) { unsigned nLEDs = strip.numPixels(); - for (unsigned i = 0; i < nLEDs; i++) - { + for (unsigned i = 0; i < nLEDs; i++) { strip.setPixelColor(i, r, g, b); } strip.show(); @@ -146,18 +124,22 @@ if (pos < 0.0) { rled = 0; gled = 1; - } - else if (pos > 0.0) { + } else if (pos > 0.0) { rled = 1; gled = 0; - } - else { + } else { rled = gled = 1; } servo.pulsewidth_us((1.5 + (pos / 2.0)) * 1000.0); } +void flap() +{ + positionServo(currentPosition); + currentPosition = -currentPosition; +} + static void selfTestServo() { pc.printf("Servo:\r\n"); @@ -208,8 +190,7 @@ blankLightStrips(); pc.printf("light strips"); uint8_t rgb[4] = { (uint8_t)(255 * maxBrite), 0, 0, 0 }; - for (int i = 0; i < 3; i++) - { + for (int i = 0; i < 3; i++) { showSolidColor(lightStrip1, rgb[0], rgb[1], rgb[2]); showSolidColor(lightStrip2, rgb[1], rgb[2], rgb[0]); refreshLightStrips(); @@ -231,6 +212,8 @@ selfTestLightStrips(); selfTestServo(); selfTestLEDs(); + + pc.printf("done\n"); } // rainbow that wraps around entire frame @@ -245,21 +228,11 @@ skip %= 3; } -static float currentPosition = 0.0; - -void setWingFlapTime(float desired) +void updateEyes() { - static float lastWingFlapTime = 0.0; - if (desired < minFlapTime) - desired = minFlapTime; - else if (desired > maxFlapTime) - desired = maxFlapTime; - wingFlapTime = desired; - - if (lastWingFlapTime != wingFlapTime) - { - lastWingFlapTime = wingFlapTime; - } + static bool eyesOn; + eyes = eyesOn ? 1 : 0; + eyesOn = !eyesOn; } int main(void) @@ -272,67 +245,41 @@ rled = 1.0; gled = 1.0; -// greenLED2 = 0.0; servo.period_ms(20); selfTest(); - resetSpeedAndAcceleration(); - speedUpdateTicker.attach(updateSpeedAndAcceleration, speedUpdateInterval); + Timer elapsedTime; - Timer elapsedTime; + Ticker flapper; + flapper.attach(flap, maxFlapTime); + + Ticker stripUpdater; + stripUpdater.attach(updateStripsRainbow, 0.3); + + Ticker eyeUpdater; + eyeUpdater.attach(updateEyes, 0.2); + 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; + bool lastButton = button1.read(); - float lastCurrentSpeed = 0.0; - for (;; ) - { - float relativeAccel = fabs(currentZAccel - restZAccel); - if ((relativeAccel < 1.0) || !button1.read()) - { - resetSpeedAndAcceleration(); - setWingFlapTime(maxFlapTime); - stripUpdateTime = 0.3; - } - else - { - setWingFlapTime(minFlapTime); - stripUpdateTime = 0.1; + for (;; ) { + bool buttonValue = button1.read(); + if (buttonValue != lastButton) { + if (!buttonValue) { + flapper.detach(); + flapper.attach(flap, maxFlapTime); + stripUpdater.detach(); + stripUpdater.attach(updateStripsRainbow, 0.3); + } else { + flapper.detach(); + flapper.attach(flap, minFlapTime); + stripUpdater.detach(); + stripUpdater.attach(updateStripsRainbow, 0.1); + } } - if (lastCurrentSpeed != currentSpeed) - { - lastCurrentSpeed = currentSpeed; - pc.printf("%f %f %f\r\n", relativeAccel, currentSpeed, wingFlapTime); - } - - 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); + wait(0.1); } }