Moves a glow up and down a strip of WS2812 LEDs

Dependencies:   mbed wsDrive

Committer:
AndyA
Date:
Fri Nov 07 16:28:27 2014 +0000
Revision:
1:054df9ecd479
Parent:
0:35d68d1652e1
Now supports an arbitrary number of glows each traveling at their own speed.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AndyA 0:35d68d1652e1 1 #include "mbed.h"
AndyA 0:35d68d1652e1 2 #include "wsDrive.h"
AndyA 0:35d68d1652e1 3
AndyA 0:35d68d1652e1 4 // time period between each movement
AndyA 1:054df9ecd479 5 #define updatePeriodMS 15
AndyA 0:35d68d1652e1 6
AndyA 0:35d68d1652e1 7 // number of LEDs in chain
AndyA 0:35d68d1652e1 8 #define chainLen 144
AndyA 0:35d68d1652e1 9
AndyA 0:35d68d1652e1 10 // set the pulldown and then create the driver
AndyA 0:35d68d1652e1 11 DigitalIn dummy(P0_21,PullDown);
AndyA 0:35d68d1652e1 12 wsDrive ledDriver(P0_21,P0_22,P1_15);
AndyA 0:35d68d1652e1 13
AndyA 0:35d68d1652e1 14 // mbuino stnadard definitions
AndyA 0:35d68d1652e1 15 DigitalIn progMode(P0_3,PullDown); // fix the power wasted if we ever sleep.
AndyA 0:35d68d1652e1 16 BusOut LEDs(LED1, LED2, LED3, LED4, LED5, LED6, LED7); // control the LEDs
AndyA 0:35d68d1652e1 17
AndyA 0:35d68d1652e1 18 Timer updateRateTimer;
AndyA 0:35d68d1652e1 19
AndyA 0:35d68d1652e1 20 // pixel storage buffer
AndyA 1:054df9ecd479 21 pixelInfo16 pixelData[chainLen];
AndyA 1:054df9ecd479 22
AndyA 1:054df9ecd479 23 const uint8_t trailCount = 3;
AndyA 1:054df9ecd479 24
AndyA 1:054df9ecd479 25 // info for each trail
AndyA 1:054df9ecd479 26 struct trailInfo {
AndyA 1:054df9ecd479 27 float start; // location of the trail from 0 to chainLen-1
AndyA 1:054df9ecd479 28 int length; // length of the trail
AndyA 1:054df9ecd479 29 float speed; // speed in moves at in LEDs per update
AndyA 1:054df9ecd479 30 int backgroundRatio; // background glow level
AndyA 1:054df9ecd479 31 pixelInfo colour; // colour (and brightness) at the start of the chain
AndyA 1:054df9ecd479 32 bool dir; // direction of travel - true = increasing location
AndyA 1:054df9ecd479 33 };
AndyA 1:054df9ecd479 34
AndyA 1:054df9ecd479 35
AndyA 1:054df9ecd479 36 struct trailInfo lines[trailCount];
AndyA 1:054df9ecd479 37
AndyA 0:35d68d1652e1 38
AndyA 0:35d68d1652e1 39 void blankBuffer(pixelInfo *Ptr)
AndyA 0:35d68d1652e1 40 {
AndyA 0:35d68d1652e1 41 memset( (void *)Ptr, 0, chainLen*sizeof(pixelInfo) );
AndyA 0:35d68d1652e1 42 }
AndyA 0:35d68d1652e1 43
AndyA 1:054df9ecd479 44 void blankBuffer(pixelInfo16 *Ptr)
AndyA 1:054df9ecd479 45 {
AndyA 1:054df9ecd479 46 memset( (void *)Ptr, 0, chainLen*sizeof(pixelInfo16) );
AndyA 1:054df9ecd479 47 }
AndyA 1:054df9ecd479 48
AndyA 0:35d68d1652e1 49 void setPixel (pixelInfo *pixel, pixelInfo *colour, float level)
AndyA 0:35d68d1652e1 50 {
AndyA 1:054df9ecd479 51 pixel->R = (colour->R * level);
AndyA 1:054df9ecd479 52 pixel->G = (colour->G * level);
AndyA 1:054df9ecd479 53 pixel->B = (colour->B * level);
AndyA 1:054df9ecd479 54 }
AndyA 0:35d68d1652e1 55
AndyA 1:054df9ecd479 56 void addPixel (pixelInfo16 *pixel, pixelInfo *colour, float level)
AndyA 1:054df9ecd479 57 {
AndyA 1:054df9ecd479 58 pixel->R = pixel->R + (int)(colour->R * level);
AndyA 1:054df9ecd479 59 pixel->G = pixel->G + (int)(colour->G * level);
AndyA 1:054df9ecd479 60 pixel->B = pixel->B + (int)(colour->B * level);
AndyA 1:054df9ecd479 61 }
AndyA 1:054df9ecd479 62
AndyA 1:054df9ecd479 63 void subtractPixel (pixelInfo16 *pixel, pixelInfo *colour, float level)
AndyA 1:054df9ecd479 64 {
AndyA 1:054df9ecd479 65 pixel->R = pixel->R - (int)(colour->R * level);
AndyA 1:054df9ecd479 66 pixel->G = pixel->G - (int)(colour->G * level);
AndyA 1:054df9ecd479 67 pixel->B = pixel->B - (int)(colour->B * level);
AndyA 0:35d68d1652e1 68 }
AndyA 0:35d68d1652e1 69
AndyA 0:35d68d1652e1 70
AndyA 1:054df9ecd479 71 void setTrail(bool add, pixelInfo16* buffer, pixelInfo *colour, int peakPoint, bool increasing, int len)
AndyA 0:35d68d1652e1 72 {
AndyA 0:35d68d1652e1 73 int pixelToUpdate = peakPoint;
AndyA 1:054df9ecd479 74 for (int pixel = 0; pixel < len; pixel++) {
AndyA 1:054df9ecd479 75
AndyA 1:054df9ecd479 76 if (add)
AndyA 1:054df9ecd479 77 addPixel((buffer+pixelToUpdate), colour, 1.0 - (float)pixel/(float)len);
AndyA 1:054df9ecd479 78 else
AndyA 1:054df9ecd479 79 subtractPixel((buffer+pixelToUpdate), colour, 1.0 - (float)pixel/(float)len);
AndyA 1:054df9ecd479 80
AndyA 0:35d68d1652e1 81 increasing ? pixelToUpdate-- : pixelToUpdate++;
AndyA 1:054df9ecd479 82
AndyA 0:35d68d1652e1 83 if (pixelToUpdate == chainLen) {
AndyA 0:35d68d1652e1 84 increasing = false;
AndyA 1:054df9ecd479 85 pixelToUpdate = chainLen-2;
AndyA 0:35d68d1652e1 86 }
AndyA 0:35d68d1652e1 87 if (pixelToUpdate == -1) {
AndyA 0:35d68d1652e1 88 increasing = true;
AndyA 1:054df9ecd479 89 pixelToUpdate = 1;
AndyA 0:35d68d1652e1 90 }
AndyA 0:35d68d1652e1 91 }
AndyA 0:35d68d1652e1 92 }
AndyA 0:35d68d1652e1 93
AndyA 1:054df9ecd479 94 void removeTrail (pixelInfo16* buffer, pixelInfo *colour, int peakPoint, bool increasing, int len)
AndyA 0:35d68d1652e1 95 {
AndyA 1:054df9ecd479 96 setTrail (false, buffer, colour, peakPoint, increasing, len);
AndyA 1:054df9ecd479 97 }
AndyA 0:35d68d1652e1 98
AndyA 1:054df9ecd479 99 void addTrail (pixelInfo16* buffer, pixelInfo *colour, int peakPoint, bool increasing, int len)
AndyA 1:054df9ecd479 100 {
AndyA 1:054df9ecd479 101 setTrail (true, buffer, colour, peakPoint, increasing, len);
AndyA 0:35d68d1652e1 102 }
AndyA 0:35d68d1652e1 103
AndyA 0:35d68d1652e1 104
AndyA 0:35d68d1652e1 105 int main ()
AndyA 0:35d68d1652e1 106 {
AndyA 0:35d68d1652e1 107 LEDs = 0;
AndyA 1:054df9ecd479 108
AndyA 1:054df9ecd479 109
AndyA 1:054df9ecd479 110 // set up the lights.
AndyA 1:054df9ecd479 111 lines[0].start = 0;
AndyA 1:054df9ecd479 112 lines[0].speed = 1.1;
AndyA 1:054df9ecd479 113 lines[0].length = 20;
AndyA 1:054df9ecd479 114 lines[0].backgroundRatio = 40;
AndyA 1:054df9ecd479 115 lines[0].colour.R = 120;
AndyA 1:054df9ecd479 116 lines[0].colour.G = 0;
AndyA 1:054df9ecd479 117 lines[0].colour.B = 0;
AndyA 1:054df9ecd479 118 lines[0].dir = true;
AndyA 0:35d68d1652e1 119
AndyA 1:054df9ecd479 120 lines[1].start = 0;
AndyA 1:054df9ecd479 121 lines[1].speed = 2.0/3.0;
AndyA 1:054df9ecd479 122 lines[1].length = 16;
AndyA 1:054df9ecd479 123 lines[1].backgroundRatio = 40;
AndyA 1:054df9ecd479 124 lines[1].colour.R = 0;
AndyA 1:054df9ecd479 125 lines[1].colour.G = 0;
AndyA 1:054df9ecd479 126 lines[1].colour.B = 120;
AndyA 1:054df9ecd479 127 lines[1].dir = true;
AndyA 0:35d68d1652e1 128
AndyA 1:054df9ecd479 129 lines[2].start = 143;
AndyA 1:054df9ecd479 130 lines[2].speed = 1;
AndyA 1:054df9ecd479 131 lines[2].length = 20;
AndyA 1:054df9ecd479 132 lines[2].backgroundRatio = 40;
AndyA 1:054df9ecd479 133 lines[2].colour.R = 0;
AndyA 1:054df9ecd479 134 lines[2].colour.G = 120;
AndyA 1:054df9ecd479 135 lines[2].colour.B = 0;
AndyA 1:054df9ecd479 136 lines[2].dir = false;
AndyA 1:054df9ecd479 137
AndyA 1:054df9ecd479 138 // clear the buffer
AndyA 0:35d68d1652e1 139 blankBuffer(pixelData);
AndyA 0:35d68d1652e1 140
AndyA 1:054df9ecd479 141 // add the optional background
AndyA 1:054df9ecd479 142 /*
AndyA 1:054df9ecd479 143 for (int i = 0; i< chainLen; i++) {
AndyA 1:054df9ecd479 144 for (int j = 0; j <trailCount; j++) {
AndyA 1:054df9ecd479 145 addPixel((pixelData+i), &(lines[j].colour), 1.0/lines[j].backgroundRatio);
AndyA 1:054df9ecd479 146 }
AndyA 1:054df9ecd479 147 }
AndyA 1:054df9ecd479 148 */
AndyA 1:054df9ecd479 149
AndyA 1:054df9ecd479 150 // add the initial lines
AndyA 1:054df9ecd479 151 for (int j = 0; j <trailCount; j++) {
AndyA 1:054df9ecd479 152 addTrail (pixelData, &(lines[j].colour), lines[j].start, lines[j].dir, lines[j].length); // set the LED data
AndyA 1:054df9ecd479 153 }
AndyA 0:35d68d1652e1 154 // give the LED driver the buffer to use.
AndyA 0:35d68d1652e1 155 ledDriver.setData(pixelData, chainLen);
AndyA 0:35d68d1652e1 156
AndyA 0:35d68d1652e1 157 LEDs = 1;
AndyA 0:35d68d1652e1 158
AndyA 0:35d68d1652e1 159 updateRateTimer.start();
AndyA 0:35d68d1652e1 160 while (true) {
AndyA 0:35d68d1652e1 161 ledDriver.sendData(); // send the LED data
AndyA 1:054df9ecd479 162
AndyA 0:35d68d1652e1 163 LEDs = LEDs+1;
AndyA 0:35d68d1652e1 164
AndyA 1:054df9ecd479 165 // subtract the current trail locations and then add the new locations.
AndyA 1:054df9ecd479 166 for (int j = 0; j <trailCount; j++) {
AndyA 1:054df9ecd479 167 removeTrail (pixelData, &(lines[j].colour), lines[j].start, lines[j].dir, lines[j].length); // set the LED data
AndyA 1:054df9ecd479 168
AndyA 1:054df9ecd479 169 lines[j].dir ? lines[j].start+=lines[j].speed : lines[j].start-=lines[j].speed;
AndyA 1:054df9ecd479 170 if ((int)lines[j].start >= chainLen) {
AndyA 1:054df9ecd479 171 lines[j].dir = false;
AndyA 1:054df9ecd479 172 lines[j].start = chainLen-1 - lines[j].speed;
AndyA 1:054df9ecd479 173 }
AndyA 1:054df9ecd479 174 if ((int)lines[j].start <= -1) {
AndyA 1:054df9ecd479 175 lines[j].dir = true;
AndyA 1:054df9ecd479 176 lines[j].start = lines[j].speed;
AndyA 1:054df9ecd479 177 }
AndyA 1:054df9ecd479 178 addTrail (pixelData, &(lines[j].colour), lines[j].start, lines[j].dir, lines[j].length); // set the LED data
AndyA 0:35d68d1652e1 179 }
AndyA 0:35d68d1652e1 180 // wait for the next update time.
AndyA 0:35d68d1652e1 181 while (updateRateTimer.read_ms() < updatePeriodMS) {
AndyA 0:35d68d1652e1 182 }
AndyA 0:35d68d1652e1 183 updateRateTimer.reset();
AndyA 0:35d68d1652e1 184 }
AndyA 0:35d68d1652e1 185
AndyA 0:35d68d1652e1 186 }