Moves a glow up and down a strip of WS2812 LEDs

Dependencies:   mbed wsDrive

Files at this revision

API Documentation at this revision

Comitter:
AndyA
Date:
Fri Nov 07 16:28:27 2014 +0000
Parent:
0:35d68d1652e1
Commit message:
Now supports an arbitrary number of glows each traveling at their own speed.

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
wsDrive.lib Show annotated file Show diff for this revision Revisions of this file
--- a/main.cpp	Wed Nov 05 16:50:38 2014 +0000
+++ b/main.cpp	Fri Nov 07 16:28:27 2014 +0000
@@ -2,20 +2,11 @@
 #include "wsDrive.h"
 
 // time period between each movement
-#define updatePeriodMS 25
+#define updatePeriodMS 15
 
 // number of LEDs in chain
 #define chainLen 144
 
-// length of the fade off behind the bright spot.
-// 1/8th of the chain length seems to look good (18 LEDs for a 144 chain)
-#define glowTail (chainLen/8)
-
-// background brightness left after the tail has passed.
-// final brightness = peak/backgroundRatio
-// set to be the same as the glow tail length for a smooth transition
-#define backgroundRatio glowTail
-
 // set the pulldown and then create the driver
 DigitalIn dummy(P0_21,PullDown);
 wsDrive ledDriver(P0_21,P0_22,P1_15);
@@ -27,122 +18,165 @@
 Timer updateRateTimer;
 
 // pixel storage buffer
-pixelInfo pixelData[chainLen];
+pixelInfo16 pixelData[chainLen];
+
+const uint8_t trailCount = 3;
+
+// info for each trail
+struct trailInfo {
+    float start;  // location of the trail from 0 to chainLen-1
+    int length;   // length of the trail
+    float speed;  // speed in moves at in LEDs per update
+    int backgroundRatio; // background glow level
+    pixelInfo colour;  // colour (and brightness) at the start of the chain
+    bool dir;       // direction of travel - true = increasing location
+};
+
+
+struct trailInfo lines[trailCount];
+
 
 void blankBuffer(pixelInfo *Ptr)
 {
     memset( (void *)Ptr, 0, chainLen*sizeof(pixelInfo) );
 }
 
+void blankBuffer(pixelInfo16 *Ptr)
+{
+    memset( (void *)Ptr, 0, chainLen*sizeof(pixelInfo16) );
+}
+
 void setPixel (pixelInfo *pixel, pixelInfo *colour, float level)
 {
+    pixel->R = (colour->R * level);
+    pixel->G = (colour->G * level);
+    pixel->B = (colour->B * level);
+}
 
-    pixel->R = (unsigned char) (colour->R * level);
-    pixel->G = (unsigned char) (colour->G * level);
-    pixel->B = (unsigned char) (colour->B * level);
+void addPixel (pixelInfo16 *pixel, pixelInfo *colour, float level)
+{
+    pixel->R = pixel->R + (int)(colour->R * level);
+    pixel->G = pixel->G + (int)(colour->G * level);
+    pixel->B = pixel->B + (int)(colour->B * level);
+}
+
+void subtractPixel (pixelInfo16 *pixel, pixelInfo *colour, float level)
+{
+    pixel->R = pixel->R - (int)(colour->R * level);
+    pixel->G = pixel->G - (int)(colour->G * level);
+    pixel->B = pixel->B - (int)(colour->B * level);
 }
 
 
-void setTrail (pixelInfo *colour, int peakPoint, bool increasing, int len)
+void setTrail(bool add, pixelInfo16* buffer, pixelInfo *colour, int peakPoint, bool increasing, int len)
 {
     int pixelToUpdate = peakPoint;
-    for (int pixel = 0; pixel <= len; pixel++) {
-        if (pixel == len) {
-            setPixel((pixelData+pixelToUpdate), colour, 1.0/backgroundRatio);
-            break;
-        }
-        setPixel((pixelData+pixelToUpdate), colour, 1.0 - (float)pixel/(float)len);
+    for (int pixel = 0; pixel < len; pixel++) {
+
+        if (add)
+            addPixel((buffer+pixelToUpdate), colour, 1.0 - (float)pixel/(float)len);
+        else
+            subtractPixel((buffer+pixelToUpdate), colour, 1.0 - (float)pixel/(float)len);
+
         increasing ? pixelToUpdate-- : pixelToUpdate++;
+
         if (pixelToUpdate == chainLen) {
             increasing = false;
-            pixelToUpdate = peakPoint - 1;
-            pixel = pixel*2;
+            pixelToUpdate = chainLen-2;
         }
         if (pixelToUpdate == -1) {
             increasing = true;
-            pixelToUpdate = peakPoint + 1;
-            pixel = pixel*2;
+            pixelToUpdate = 1;
         }
     }
 }
 
-
-void setColour(pixelInfo *colour)
+void removeTrail (pixelInfo16* buffer, pixelInfo *colour, int peakPoint, bool increasing, int len)
 {
-    static int cycleNumber = 0;
-
-    const int maxCycle = 40;
-    if (cycleNumber > maxCycle)
-        cycleNumber = 0;
+    setTrail (false, buffer, colour, peakPoint, increasing, len);
+}
 
-    switch (cycleNumber) {
-        case maxCycle:
-            cycleNumber = 0;
-        case 0:
-            colour->R = 0x80;
-            colour->G = 0x00;
-            colour->B = 0x00;
-            break;
-        case 10:
-            colour->R = 0x00;
-            colour->G = 0x70;
-            colour->B = 0x00;
-            break;
-        case 20:
-            colour->R = 0x00;
-            colour->G = 0x00;
-            colour->B = 0x80;
-            break;
-        case 30:
-            colour->R = 0x50;
-            colour->G = 0x40;
-            colour->B = 0x50;
-            break;
-        default:
-            break;
-    }
-    cycleNumber++;
+void addTrail (pixelInfo16* buffer, pixelInfo *colour, int peakPoint, bool increasing, int len)
+{
+    setTrail (true, buffer, colour, peakPoint, increasing, len);
 }
 
 
 int main ()
 {
     LEDs = 0;
-    // intialise variables
-    int peakPoint = 0;
-    bool increasing = true;
+
+
+    // set up the lights.
+    lines[0].start = 0;
+    lines[0].speed = 1.1;
+    lines[0].length = 20;
+    lines[0].backgroundRatio = 40;
+    lines[0].colour.R = 120;
+    lines[0].colour.G = 0;
+    lines[0].colour.B = 0;
+    lines[0].dir = true;
 
-    pixelInfo colour;
-    setColour(&colour);
+    lines[1].start = 0;
+    lines[1].speed = 2.0/3.0;
+    lines[1].length = 16;
+    lines[1].backgroundRatio = 40;
+    lines[1].colour.R = 0;
+    lines[1].colour.G = 0;
+    lines[1].colour.B = 120;
+    lines[1].dir = true;
 
+    lines[2].start = 143;
+    lines[2].speed = 1;
+    lines[2].length = 20;
+    lines[2].backgroundRatio = 40;
+    lines[2].colour.R = 0;
+    lines[2].colour.G = 120;
+    lines[2].colour.B = 0;
+    lines[2].dir = false;
+
+    // clear the buffer
     blankBuffer(pixelData);
 
+    // add the optional background
+    /*
+        for (int i = 0; i< chainLen; i++) {
+            for (int j = 0; j <trailCount; j++) {
+                addPixel((pixelData+i), &(lines[j].colour), 1.0/lines[j].backgroundRatio);
+            }
+        }
+    */
+
+// add the initial lines
+    for (int j = 0; j <trailCount; j++) {
+        addTrail (pixelData, &(lines[j].colour), lines[j].start, lines[j].dir, lines[j].length); // set the LED data
+    }
     // give the LED driver the buffer to use.
     ledDriver.setData(pixelData, chainLen);
 
     LEDs = 1;
 
-    setTrail (&colour, peakPoint, increasing, glowTail); // set the LED data
-
     updateRateTimer.start();
     while (true) {
         ledDriver.sendData(); // send the LED data
+
         LEDs = LEDs+1;
 
-        increasing ? peakPoint++ : peakPoint--; 
-        if (peakPoint == chainLen) {
-            increasing = false;
-            peakPoint = chainLen-2;
+        // subtract the current trail locations and then add the new locations.
+        for (int j = 0; j <trailCount; j++) {
+            removeTrail (pixelData, &(lines[j].colour), lines[j].start, lines[j].dir, lines[j].length); // set the LED data
+
+            lines[j].dir ? lines[j].start+=lines[j].speed : lines[j].start-=lines[j].speed;
+            if ((int)lines[j].start >= chainLen) {
+                lines[j].dir = false;
+                lines[j].start = chainLen-1 - lines[j].speed;
+            }
+            if ((int)lines[j].start <= -1) {
+                lines[j].dir = true;
+                lines[j].start = lines[j].speed;
+            }
+            addTrail (pixelData, &(lines[j].colour), lines[j].start, lines[j].dir, lines[j].length); // set the LED data
         }
-        if (peakPoint == -1) {
-            setColour(&colour);
-            increasing = true;
-            peakPoint = 1;
-        }
-        
-        // update to the next trail ready for the next update.
-        setTrail (&colour, peakPoint, increasing, glowTail); // set the LED data
-
         // wait for the next update time.
         while (updateRateTimer.read_ms() < updatePeriodMS) {
         }
--- a/wsDrive.lib	Wed Nov 05 16:50:38 2014 +0000
+++ b/wsDrive.lib	Fri Nov 07 16:28:27 2014 +0000
@@ -1,1 +1,1 @@
-http://developer.mbed.org/users/AndyA/code/wsDrive/#b3665f91bedc
+http://developer.mbed.org/users/AndyA/code/wsDrive/#1f20efb81649