Moves a glow up and down a strip of WS2812 LEDs
Revision 1:054df9ecd479, committed 2014-11-07
- 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 |
diff -r 35d68d1652e1 -r 054df9ecd479 main.cpp --- 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) { }
diff -r 35d68d1652e1 -r 054df9ecd479 wsDrive.lib --- 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