Moves a glow up and down a strip of WS2812 LEDs
main.cpp@1:054df9ecd479, 2014-11-07 (annotated)
- 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?
User | Revision | Line number | New 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 | } |