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:
Ned Konz
Date:
Mon Jun 15 07:24:39 2015 -0700
Parent:
38:3b1ce6902a1b
Child:
40:d5c8ce80b6c4
Commit message:
race version

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
--- 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);
     }
 }