effects.h
1 // SPDX-FileCopyrightText: 2019 Anne Barela for Adafruit Industries 2 // 3 // SPDX-License-Identifier: MIT 4 5 // Selection of effects from the FastLED library & Macetech RGB Shades 6 7 8 // Triple Sine Waves 9 void threeSine() { 10 11 static byte sineOffset = 0; // counter for current position of sine waves 12 13 // startup tasks 14 if (effectInit == false) { 15 effectInit = true; 16 effectDelay = 20; 17 } 18 19 // Draw one frame of the animation into the LED array 20 for (byte x = 0; x < kMatrixWidth; x++) { 21 for (int y = 0; y < kMatrixHeight; y++) { 22 23 // Calculate "sine" waves with varying periods 24 // sin8 is used for speed; cos8, quadwave8, or triwave8 would also work here 25 byte sinDistanceR = qmul8(abs(y * (255 / kMatrixHeight) - sin8(sineOffset * 9 + x * 16)), 2); 26 byte sinDistanceG = qmul8(abs(y * (255 / kMatrixHeight) - sin8(sineOffset * 10 + x * 16)), 2); 27 byte sinDistanceB = qmul8(abs(y * (255 / kMatrixHeight) - sin8(sineOffset * 11 + x * 16)), 2); 28 29 leds[XY(x, y)] = CRGB(255 - sinDistanceR, 255 - sinDistanceG, 255 - sinDistanceB); 30 } 31 } 32 33 sineOffset++; // byte will wrap from 255 to 0, matching sin8 0-255 cycle 34 35 } 36 37 38 39 // Solid Colors 40 // Create your own! 41 void SolidWhite() //for the porto-potty 42 { 43 fill_solid( leds, NUM_LEDS, CRGB::White); 44 } 45 46 void SolidRed() //for startup, good for saving battery 47 { 48 fill_solid( leds, NUM_LEDS, CRGB::Red); 49 } 50 51 52 53 // RGB Plasma 54 void plasma() { 55 56 static byte offset = 0; // counter for radial color wave motion 57 static int plasVector = 0; // counter for orbiting plasma center 58 59 // startup tasks 60 if (effectInit == false) { 61 effectInit = true; 62 effectDelay = 10; 63 } 64 65 // Calculate current center of plasma pattern (can be offscreen) 66 int xOffset = cos8(plasVector / 256); 67 int yOffset = sin8(plasVector / 256); 68 69 // Draw one frame of the animation into the LED array 70 for (int x = 0; x < kMatrixWidth; x++) { 71 for (int y = 0; y < kMatrixHeight; y++) { 72 byte color = sin8(sqrt(sq(((float)x - 7.5) * 10 + xOffset - 127) + sq(((float)y - 2) * 10 + yOffset - 127)) + offset); 73 leds[XY(x, y)] = CHSV(color, 255, 255); 74 } 75 } 76 77 offset++; // wraps at 255 for sin8 78 plasVector += 16; // using an int for slower orbit (wraps at 65536) 79 80 } 81 82 83 84 // Scanning pattern left/right, using global hue cycle 85 void rider() { 86 87 static byte riderPos = 0; 88 89 // startup tasks 90 if (effectInit == false) { 91 effectInit = true; 92 effectDelay = 5; 93 riderPos = 0; 94 } 95 96 // Draw one frame of the animation into the LED array 97 for (byte x = 0; x < kMatrixWidth; x++) { 98 int brightness = abs(x * (256 / kMatrixWidth) - triwave8(riderPos) * 2 + 127) * 3; 99 if (brightness > 255) brightness = 255; 100 brightness = 255 - brightness; 101 CRGB riderColor = CHSV(cycleHue, 255, brightness); 102 for (byte y = 0; y < kMatrixHeight; y++) { 103 leds[XY(x, y)] = riderColor; 104 } 105 } 106 107 riderPos++; // byte wraps to 0 at 255, triwave8 is also 0-255 periodic 108 109 } 110 111 112 113 // Fills saturated colors into the array from alternating directions 114 void colorFill() { 115 116 static byte currentColor = 0; 117 static byte currentRow = 0; 118 static byte currentDirection = 0; 119 120 // startup tasks 121 if (effectInit == false) { 122 effectInit = true; 123 effectDelay = 45; 124 currentColor = 0; 125 currentRow = 0; 126 currentDirection = 0; 127 currentPalette = RainbowColors_p; 128 } 129 130 // test a bitmask to fill up or down when currentDirection is 0 or 2 (0b00 or 0b10) 131 if (!(currentDirection & 1)) { 132 effectDelay = 45; // slower since vertical has fewer pixels 133 for (byte x = 0; x < kMatrixWidth; x++) { 134 byte y = currentRow; 135 if (currentDirection == 2) y = kMatrixHeight - 1 - currentRow; 136 leds[XY(x, y)] = currentPalette[currentColor]; 137 } 138 } 139 140 // test a bitmask to fill left or right when currentDirection is 1 or 3 (0b01 or 0b11) 141 if (currentDirection & 1) { 142 effectDelay = 20; // faster since horizontal has more pixels 143 for (byte y = 0; y < kMatrixHeight; y++) { 144 byte x = currentRow; 145 if (currentDirection == 3) x = kMatrixWidth - 1 - currentRow; 146 leds[XY(x, y)] = currentPalette[currentColor]; 147 } 148 } 149 150 currentRow++; 151 152 // detect when a fill is complete, change color and direction 153 if ((!(currentDirection & 1) && currentRow >= kMatrixHeight) || ((currentDirection & 1) && currentRow >= kMatrixWidth)) { 154 currentRow = 0; 155 currentColor += random8(3, 6); 156 if (currentColor > 15) currentColor -= 16; 157 currentDirection++; 158 if (currentDirection > 3) currentDirection = 0; 159 effectDelay = 300; // wait a little bit longer after completing a fill 160 } 161 } 162 163 164 165 // Random pixels scroll sideways, using current hue 166 #define rainDir 0 167 void sideRain() { 168 169 // startup tasks 170 if (effectInit == false) { 171 effectInit = true; 172 effectDelay = 30; 173 } 174 175 scrollArray(rainDir); 176 byte randPixel = random8(kMatrixHeight); 177 for (byte y = 0; y < kMatrixHeight; y++) leds[XY((kMatrixWidth - 1) * rainDir, y)] = CRGB::Black; 178 leds[XY((kMatrixWidth - 1)*rainDir, randPixel)] = CHSV(cycleHue, 255, 255); 179 180 } 181 182 183 184 // CONFETTI: pixels with random locations and random colors selected from a palette 185 // Create your own confetti modes using the built in Palettes (see utils.h) or create your own 186 // Use with the fadeAll function (see .ino) to allow old pixels to decay 187 void confetti() { 188 // startup tasks 189 if (effectInit == false) { 190 effectInit = true; 191 effectDelay = 10; 192 selectRandomPalette(); 193 } 194 195 // scatter random colored pixels at several random coordinates 196 for (byte i = 0; i < 4; i++) { 197 leds[XY(random16(kMatrixWidth), random16(kMatrixHeight))] = ColorFromPalette(currentPalette, random16(255), 255); //CHSV(random16(255), 255, 255); 198 random16_add_entropy(1); 199 } 200 } 201 202 //Palette for myConfetti 203 const TProgmemPalette16 MyColors_p PROGMEM = 204 { 205 CRGB:: Crimson, 206 CRGB:: Maroon, 207 CRGB:: Red, 208 CRGB:: OrangeRed, 209 210 CRGB:: Crimson, 211 CRGB:: Maroon, 212 CRGB:: Red, 213 CRGB:: OrangeRed, 214 215 CRGB:: Crimson, 216 CRGB:: Maroon, 217 CRGB:: Red, 218 CRGB:: OrangeRed, 219 220 CRGB:: Crimson, 221 CRGB:: Maroon, 222 CRGB:: Red, 223 CRGB:: OrangeRed, 224 }; 225 226 void myConfetti() { 227 // startup tasks 228 if (effectInit == false) { 229 effectInit = true; 230 effectDelay = 15; 231 } 232 233 234 // scatter random colored pixels at several random coordinates 235 for (byte i = 0; i < 4; i++) { 236 leds[XY(random16(kMatrixWidth), random16(kMatrixHeight))] = ColorFromPalette(MyColors_p, random16(255), 255); //CHSV(random16(255), 255, 255); 237 random16_add_entropy(1); 238 } 239 240 } 241 242 243 // Example from the NoisePlusPalette FastLED example sketch. See utils.h 244 void NoisePlusPalette() { 245 246 fillnoise8(); 247 248 mapNoiseToLEDsUsingPalette(); 249 250 } 251 252 253 // Draw slanting bars scrolling across the array, using current hue 254 void slantBars() { 255 256 static byte slantPos = 0; 257 258 // startup tasks 259 if (effectInit == false) { 260 effectInit = true; 261 effectDelay = 5; 262 } 263 264 for (byte x = 0; x < kMatrixWidth; x++) { 265 for (byte y = 0; y < kMatrixHeight; y++) { 266 leds[XY(x, y)] = CHSV(cycleHue, 255, quadwave8(x * 32 + y * 32 + slantPos)); 267 } 268 } 269 270 slantPos -= 4; 271 272 } 273 274 275 //from Mark Kriegsman 276 void swirly() 277 { 278 // startup tasks 279 if (effectInit == false) { 280 effectInit = true; 281 effectDelay = 15; 282 } 283 284 // Apply some blurring to whatever's already on the matrix 285 // Note that we never actually clear the matrix, we just constantly 286 // blur it repeatedly. Since the blurring is 'lossy', there's 287 // an automatic trend toward black -- by design. 288 uint8_t blurAmount = beatsin8(2,10,255); 289 blur2d( leds, kMatrixWidth, kMatrixHeight, blurAmount); 290 291 // Use two out-of-sync sine waves 292 uint8_t i = beatsin8( 27, kBorderWidth, kMatrixHeight-kBorderWidth); 293 uint8_t j = beatsin8( 41, kBorderWidth, kMatrixWidth-kBorderWidth); 294 // Also calculate some reflections 295 uint8_t ni = (kMatrixWidth-1)-i; 296 uint8_t nj = (kMatrixWidth-1)-j; 297 298 // The color of each point shifts over time, each at a different speed. 299 uint16_t ms = millis(); 300 leds[XY( i, j)] += CHSV( ms / 11, 200, 255); 301 leds[XY( j, i)] += CHSV( ms / 13, 200, 255); 302 leds[XY(ni,nj)] += CHSV( ms / 17, 200, 255); 303 leds[XY(nj,ni)] += CHSV( ms / 29, 200, 255); 304 leds[XY( i,nj)] += CHSV( ms / 37, 200, 255); 305 leds[XY(ni, j)] += CHSV( ms / 41, 200, 255); 306 307 FastLED.show(); 308 }