├── Baby_Speaker └── Baby_Speaker.ino ├── Baby_Speaker_FINAL.ino └── README.md /Baby_Speaker/Baby_Speaker.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /** BASIC CONFIGURATION **/ 5 | #define BRIGHTNESS 160 6 | #define FRAMES_PER_SECOND 120 7 | 8 | //The pin that controls the LEDs 9 | #define LED_PIN 2 10 | //The pin that we read sensor values form 11 | #define MIC_PIN A0 12 | #define switchPin 5 13 | 14 | uint8_t led_volts = 5; 15 | uint32_t max_milliamps = 2400; 16 | 17 | int newborn = 0; //indicates if in newborn mode, so color palette can be black and white 18 | 19 | //////////////////////////////////////////////////////////////////////////////// 20 | ////////////////MATRIX PATTERN SETUP 21 | 22 | const uint8_t kMatrixWidth = 16; 23 | const uint8_t kMatrixHeight = 16; 24 | const bool kMatrixSerpentineLayout = true; 25 | 26 | //The amount of LEDs in the setup 27 | #define NUM_LEDS (kMatrixWidth * kMatrixHeight) 28 | #define NUM_LEDS_HALF (NUM_LEDS / 2) 29 | #define NUM_LEDS_QUARTER (NUM_LEDS / 4) 30 | #define MAX_DIMENSION ((kMatrixWidth>kMatrixHeight) ? kMatrixWidth : kMatrixHeight) 31 | 32 | 33 | // The 16 bit version of our coordinates 34 | static uint16_t x; 35 | static uint16_t y; 36 | static uint16_t z; 37 | 38 | // We're using the x/y dimensions to map to the x/y pixels on the matrix. We'll 39 | // use the z-axis for "time". speed determines how fast time moves forward. Try 40 | // 1 for a very slow moving effect, or 60 for something that ends up looking like 41 | // water. 42 | uint16_t speed = 6; // speed is set dynamically once we've started up 43 | 44 | // Scale determines how far apart the pixels in our noise matrix are. Try 45 | // changing these values around to see how it affects the motion of the display. The 46 | // higher the value of scale, the more "zoomed out" the noise iwll be. A value 47 | // of 1 will be so zoomed in, you'll mostly see solid colors. 48 | uint16_t scale = 30; // scale is set dynamically once we've started up 49 | 50 | // This is the array that we keep our computed noise values in 51 | uint8_t noise[MAX_DIMENSION][MAX_DIMENSION]; 52 | 53 | 54 | CRGBPalette16 currentPalette( PartyColors_p ); 55 | uint8_t colorLoop = 1; 56 | 57 | // x,y, & time values 58 | uint32_t v_time,hue_time,hxy; 59 | 60 | // how many octaves to use for the brightness and hue functions 61 | uint8_t octaves=1; 62 | uint8_t hue_octaves=3; 63 | 64 | // the 'distance' between x/y points for the hue noise 65 | int hue_scale=1; 66 | 67 | // how fast we move through time & hue noise 68 | int time_speed=100; 69 | int hue_speed=10; 70 | 71 | // adjust these values to move along the x or y axis between frames 72 | int x_speed=331; 73 | int y_speed=1111; 74 | 75 | // the 'distance' between points on the x and y axis 76 | int xscale=57771; 77 | int yscale=57771; 78 | 79 | 80 | //////////////////////////////////////////////////////////////////////////////// 81 | ////////////////VISUALIZER SETUP 82 | 83 | //Confirmed microphone low value, and max value 84 | #define MIC_LOW 390.0 85 | #define MIC_HIGH 500.0 86 | /** Other macros */ 87 | //How many previous sensor values effects the operating average? 88 | #define AVGLEN 5 89 | //How many previous sensor values decides if we are on a peak/HIGH (e.g. in a song) 90 | #define LONG_SECTOR 20 91 | 92 | //Mneumonics 93 | #define HIGH 3 94 | #define NORMAL 2 95 | 96 | //How long do we keep the "current average" sound, before restarting the measuring 97 | #define MSECS 30 * 1000 98 | #define CYCLES MSECS / DELAY 99 | 100 | /*Sometimes readings are wrong or strange. How much is a reading allowed 101 | to deviate from the average to not be discarded? **/ 102 | #define DEV_THRESH 0.8 103 | 104 | //Arduino loop delay 105 | #define DELAY 1 106 | 107 | float fscale( float originalMin, float originalMax, float newBegin, float newEnd, float inputValue, float curve); 108 | void insert(int val, int *avgs, int len); 109 | int compute_average(int *avgs, int len); 110 | void visualize_music(); 111 | void led_mode2(); 112 | void led_mode3(); 113 | void led_mode4(); 114 | void led_mode5(); 115 | void led_off(); 116 | int oldMode = 0; // assume switch closed because of pull-down resistor 117 | const unsigned long debounceTime = 1000; // milliseconds 118 | 119 | //How many LEDs to we display 120 | int height = NUM_LEDS; 121 | 122 | /*Not really used yet. Thought to be able to switch between sound reactive 123 | mode, and general gradient pulsing/static color*/ 124 | int mode = 0; 125 | 126 | //Showing different colors based on the mode. 127 | int songmode = NORMAL; 128 | 129 | //Average sound measurement the last CYCLES 130 | unsigned long song_avg; 131 | 132 | //The amount of iterations since the song_avg was reset 133 | int iter = 0; 134 | 135 | //The speed the LEDs fade to black if not relit 136 | float fade_scale = 1.2; 137 | 138 | //Led array 139 | CRGB leds[NUM_LEDS]; 140 | 141 | /*Short sound avg used to "normalize" the input values. 142 | We use the short average instead of using the sensor input directly */ 143 | int avgs[AVGLEN] = {-1}; 144 | 145 | //Longer sound avg 146 | int long_avg[LONG_SECTOR] = {-1}; 147 | 148 | //Keeping track how often, and how long times we hit a certain mode 149 | struct time_keeping { 150 | unsigned long times_start; 151 | short times; 152 | }; 153 | 154 | //How much to increment or decrement each color every cycle 155 | struct color { 156 | int r; 157 | int g; 158 | int b; 159 | }; 160 | 161 | struct time_keeping high; 162 | struct color Color; 163 | 164 | //heigh_and_condition variables; 165 | int sensor_value, mapped, avg, longavg; 166 | 167 | //peak dot parameters 168 | byte 169 | peak = 0, // Used for falling dot 170 | dotCount = 0; // Frame counter for delaying dot-falling speed 171 | #define PEAK_FALL 1 // Rate of peak falling dot 172 | #define PEAK_FALL_split 0 // Rate of peak falling dot 173 | 174 | //Vu7 Parameters 175 | #define NSAMPLES 64 176 | unsigned int samplearray[NSAMPLES]; 177 | unsigned long samplesum = 0; 178 | unsigned int sampleavg = 0; 179 | int samplecount = 0; 180 | unsigned int sample = 0; 181 | unsigned long oldtime = 0; 182 | unsigned long newtime = 0; 183 | 184 | //vu ripple 185 | uint8_t colour; 186 | uint8_t myfade = 255; // Starting brightness. 187 | #define maxsteps 16 // Case statement wouldn't allow a variable. 188 | int peakspersec = 0; 189 | int peakcount = 0; 190 | uint8_t bgcol = 0; 191 | int thisdelay = 20; 192 | int color; 193 | int center = 0; 194 | int center_2 = 0; 195 | int step = -1; 196 | float fadeRate = 0.80; 197 | int diff; 198 | int width=45; 199 | 200 | //center burst FHT parameters 201 | CRGBPalette16 targetPalette; 202 | TBlendType currentBlending; // NOBLEND or LINEARBLEND 203 | uint8_t maxChanges = 48; 204 | 205 | 206 | 207 | // FOR SYLON ETC 208 | uint8_t thisbeat = 23; 209 | uint8_t thatbeat = 28; 210 | uint8_t thisfade = 2; // How quickly does it fade? Lower = slower fade rate. 211 | uint8_t thissat = 255; // The saturation, where 255 = brilliant colours. 212 | uint8_t thisbri = 255; 213 | int myhue = 0; 214 | 215 | //FOR JUGGLE 216 | uint8_t numdots = 4; // Number of dots in use. 217 | uint8_t faderate = 2; // How long should the trails be. Very low value = longer trails. 218 | uint8_t hueinc = 16; // Incremental change in hue between each dot. 219 | uint8_t thishue = 0; // Starting hue. 220 | uint8_t curhue = 0; 221 | uint8_t thisbright = 255; // How bright should the LED/display be. 222 | uint8_t basebeat = 5; 223 | uint8_t max_bright = 255; 224 | 225 | // Twinkle 226 | float redStates[NUM_LEDS]; 227 | float blueStates[NUM_LEDS]; 228 | float greenStates[NUM_LEDS]; 229 | float Fade = 0.96; 230 | //unsigned int sample; 231 | 232 | ////For Fire 233 | //#define SPARKING 50 234 | //#define COOLING 55 235 | //bool gReverseDirection = false; 236 | //#define FRAMES_PER_SECOND 60 237 | 238 | //For Fireplace 239 | CRGBPalette16 gPal; 240 | #define FPS 48 241 | #define FPS_DELAY 1000/FPS 242 | #define COOLING 20 243 | #define HOT 100 244 | #define MAXHOT HOT*kMatrixHeight 245 | 246 | 247 | uint8_t gHue = 0; // rotating "base color" used by many of the patterns 248 | 249 | 250 | void setup() { 251 | analogReference(EXTERNAL); // Connect 3.3V to AREF pin for any microphones using 3.3V 252 | 253 | Serial.begin(9600); 254 | pinMode (switchPin, INPUT); 255 | //Set all lights to make sure all are working as expected 256 | FastLED.addLeds(leds, NUM_LEDS); 257 | set_max_power_in_volts_and_milliamps (led_volts, max_milliamps); 258 | 259 | for (int i = 0; i < NUM_LEDS; i++) 260 | leds[i] = CRGB(70, 70, 70); 261 | FastLED.show(); 262 | delay(1000); 263 | 264 | //bootstrap average with some low values 265 | for (int i = 0; i < AVGLEN; i++) { 266 | insert(250, avgs, AVGLEN); 267 | } 268 | 269 | //Initial values 270 | high.times = 0; 271 | high.times_start = millis(); 272 | Color.r = 0; 273 | Color.g = 0; 274 | Color.b = 1; 275 | 276 | // Initialize our coordinates to some random values 277 | x = random16(); 278 | y = random16(); 279 | z = random16(); 280 | 281 | //pallette for fireplace 282 | gPal = HeatColors_p; 283 | 284 | 285 | 286 | } 287 | 288 | // List of patterns to cycle through. Each is defined as a separate function below. 289 | typedef void (*SimplePatternList[])(); 290 | SimplePatternList gPatterns = { blobby_flow_gaps, XYmatrix, blobby_flow, rainbow, rainbowWithGlitter, confetti, sinelon, juggle, bpm }; 291 | 292 | uint8_t gCurrentPatternNumber = 0; // Index number of which pattern is current 293 | 294 | void loop () 295 | { 296 | // see if switch is open or closed 297 | int switchState = digitalRead (switchPin); 298 | 299 | // has it changed since last time? 300 | if (switchState == 0) 301 | { 302 | delay(300); 303 | if (oldMode == 9) 304 | { 305 | oldMode = 0; 306 | // Serial.print("oldMode is "); 307 | // Serial.println(oldMode); 308 | 309 | } // end if switchState is LOW 310 | else { 311 | oldMode++; 312 | if (oldMode == 1) 313 | { newborn = 1;} 314 | else newborn = 0; 315 | // Serial.print("oldMode is "); 316 | // Serial.println(oldMode); 317 | 318 | } 319 | } // end of state change 320 | 321 | switch(oldMode) { 322 | case 0: 323 | blobby_flow(); 324 | break; 325 | 326 | case 1: 327 | blobby_flow(); 328 | break; 329 | 330 | case 2: 331 | matrix_code(); 332 | //center_burst_quad_pulse(); 333 | //matrix_sinelon(); 334 | break; 335 | 336 | case 3: 337 | Fireplace(); 338 | //matrix_sinelon(); 339 | break; 340 | 341 | case 4: 342 | center_burst_VU(); 343 | //all2(); 344 | break; 345 | 346 | case 5: 347 | center_burst_FHT(); 348 | break; 349 | 350 | case 6: 351 | vu10(); 352 | break; 353 | 354 | case 7: 355 | visualize_music_4(); 356 | break; 357 | 358 | case 8: 359 | led_off(); 360 | break; 361 | 362 | case 9: 363 | rotate_all_patterns(); 364 | break; 365 | 366 | 367 | default: 368 | break; 369 | } 370 | delay(DELAY); // delay in between reads for stability 371 | } 372 | 373 | void led_mode2() { 374 | 375 | Serial.println("running led_mode2"); 376 | for (int i =0; i < NUM_LEDS; i++) 377 | leds[i] = CRGB(240, 100, 240); 378 | 379 | 380 | FastLED.show(); 381 | delay(5); 382 | } 383 | 384 | void led_mode3() { 385 | Serial.println("running led_mode3"); 386 | 387 | for (int i =0; i < NUM_LEDS; i++) 388 | leds[i] = CRGB(0, 240, 0); 389 | 390 | 391 | FastLED.show(); 392 | delay(5); 393 | } 394 | 395 | void led_mode4() { 396 | 397 | Serial.println("running led_mode4"); 398 | 399 | for (int i =0; i < NUM_LEDS; i++) 400 | leds[i] = CRGB(0, 0, 240); 401 | 402 | 403 | FastLED.show(); 404 | delay(5); 405 | } 406 | 407 | void led_mode5() { 408 | Serial.println("running led_mode5"); 409 | 410 | for (int i =0; i < NUM_LEDS; i++) 411 | leds[i] = CRGB(240, 0, 0); 412 | 413 | 414 | FastLED.show(); 415 | delay(5); 416 | } 417 | 418 | 419 | void led_off() { 420 | Serial.println("turning off LEDs"); 421 | 422 | for (int i =0; i < NUM_LEDS; i++) 423 | leds[i] = CRGB(0, 0, 0); 424 | 425 | 426 | FastLED.show(); 427 | delay(5); 428 | } 429 | 430 | /**Funtion to check if the lamp should either enter a HIGH mode, 431 | or revert to NORMAL if already in HIGH. If the sensors report values 432 | that are higher than 1.1 times the average values, and this has happened 433 | more than 30 times the last few milliseconds, it will enter HIGH mode. 434 | TODO: Not very well written, remove hardcoded values, and make it more 435 | reusable and configurable. */ 436 | void check_high(int avg) { 437 | if (avg > (song_avg/iter * 1.1)) { 438 | if (high.times != 0) { 439 | if (millis() - high.times_start > 200.0) { 440 | high.times = 0; 441 | songmode = NORMAL; 442 | } else { 443 | high.times_start = millis(); 444 | high.times++; 445 | } 446 | } else { 447 | high.times++; 448 | high.times_start = millis(); 449 | 450 | } 451 | } 452 | if (high.times > 30 && millis() - high.times_start < 50.0) 453 | songmode = HIGH; 454 | else if (millis() - high.times_start > 200) { 455 | high.times = 0; 456 | songmode = NORMAL; 457 | } 458 | } 459 | 460 | void height_and_condition () { 461 | 462 | //Actual sensor value 463 | sensor_value = analogRead(MIC_PIN); 464 | 465 | //If 0, discard immediately. Probably not right and save CPU. 466 | if (sensor_value == 0) 467 | return; 468 | 469 | //Discard readings that deviates too much from the past avg. 470 | mapped = (float)fscale(MIC_LOW, MIC_HIGH, MIC_LOW, (float)MIC_HIGH, (float)sensor_value, 2.0); 471 | avg = compute_average(avgs, AVGLEN); 472 | 473 | if (((avg - mapped) > avg*DEV_THRESH)) //|| ((avg - mapped) < -avg*DEV_THRESH)) 474 | return; 475 | 476 | //Insert new avg. values 477 | insert(mapped, avgs, AVGLEN); 478 | insert(avg, long_avg, LONG_SECTOR); 479 | 480 | //Compute the "song average" sensor value 481 | song_avg += avg; 482 | iter++; 483 | if (iter > CYCLES) { 484 | song_avg = song_avg / iter; 485 | iter = 1; 486 | } 487 | 488 | longavg = compute_average(long_avg, LONG_SECTOR); 489 | 490 | //Check if we enter HIGH mode 491 | check_high(longavg); 492 | 493 | if (songmode == HIGH) { 494 | fade_scale = 3; 495 | Color.r = 5; 496 | Color.g = 3; 497 | Color.b = -1; 498 | } 499 | else if (songmode == NORMAL) { 500 | fade_scale = 2; 501 | Color.r = -1; 502 | Color.b = 2; 503 | Color.g = 1; 504 | } 505 | 506 | //Decides how many of the LEDs will be lit 507 | height = fscale(MIC_LOW, MIC_HIGH, 0.0, (float)NUM_LEDS, (float)avg, -1); 508 | //height_2 = fscale(MIC_LOW, MIC_HIGH, 0.0, (float)NUM_LEDS_2, (float)avg, -1); 509 | } 510 | 511 | 512 | /////////////////////////////////////////////// 513 | //Main function for visualizing the sounds in the lamp 514 | 515 | void visualize_music() { 516 | 517 | height_and_condition(); 518 | 519 | /*Set the different leds. Control for too high and too low values. 520 | Fun thing to try: Dont account for overflow in one direction, 521 | some interesting light effects appear! */ 522 | for (int i = 0; i < NUM_LEDS; i++) 523 | //The leds we want to show 524 | if (i < height) { 525 | if (leds[i].r + Color.r > 255) 526 | leds[i].r = 255; 527 | else if (leds[i].r + Color.r < 0) 528 | leds[i].r = 0; 529 | else 530 | leds[i].r = leds[i].r + Color.r; 531 | 532 | if (leds[i].g + Color.g > 255) 533 | leds[i].g = 255; 534 | else if (leds[i].g + Color.g < 0) 535 | leds[i].g = 0; 536 | else 537 | leds[i].g = leds[i].g + Color.g; 538 | 539 | if (leds[i].b + Color.b > 255) 540 | leds[i].b = 255; 541 | else if (leds[i].b + Color.b < 0) 542 | leds[i].b = 0; 543 | else 544 | leds[i].b = leds[i].b + Color.b; 545 | 546 | //All the other LEDs begin their fading journey to eventual total darkness 547 | } else { 548 | leds[i] = CRGB(leds[i].r/fade_scale, leds[i].g/fade_scale, leds[i].b/fade_scale); 549 | } 550 | 551 | //keep peak at top 552 | if(height > peak) peak = height; // Keep 'peak' dot at top 553 | if(peak > 0 && peak < NUM_LEDS) leds[peak] = CHSV(200, 200, 200); // set peak dot 554 | FastLED.show(); 555 | 556 | if(++dotCount >= PEAK_FALL) { //fall rate 557 | 558 | if(peak > 0) peak--; 559 | dotCount = 0; 560 | } 561 | } 562 | 563 | 564 | 565 | 566 | ///////////////////////////////////////////////////////////////////////////////////// 567 | //Center out spread visualizer 568 | 569 | void visualize_music_2() { 570 | 571 | height_and_condition(); 572 | height = height / 2; 573 | 574 | /*Set the different leds. Control for too high and too low values. 575 | Fun thing to try: Dont account for overflow in one direction, 576 | some interesting light effects appear! */ 577 | for (int i = 0; i < NUM_LEDS_HALF; i++) 578 | //The leds we want to show 579 | if (i < height) { 580 | if (leds[NUM_LEDS_HALF-i-1].r + Color.r > 255) { 581 | leds[NUM_LEDS_HALF-i-1].r = 255; 582 | leds[NUM_LEDS_HALF+i].r = 255; 583 | } 584 | else if (leds[NUM_LEDS_HALF-i-1].r + Color.r < 0) { 585 | leds[NUM_LEDS_HALF-i-1].r = 0; 586 | leds[NUM_LEDS_HALF+i].r = 0; 587 | } 588 | else { 589 | leds[NUM_LEDS_HALF-i-1].r = leds[NUM_LEDS_HALF-i-1].r + Color.r; 590 | leds[NUM_LEDS_HALF+i].r = leds[NUM_LEDS_HALF+i].r + Color.r; 591 | } 592 | 593 | if (leds[NUM_LEDS_HALF-i-1].g + Color.g > 255) { 594 | leds[NUM_LEDS_HALF-i-1].g = 255; 595 | leds[NUM_LEDS_HALF+i].g = 255; 596 | } 597 | else if (leds[NUM_LEDS_HALF-i-1].g + Color.g < 0) { 598 | leds[NUM_LEDS_HALF-i-1].g = 0; 599 | leds[NUM_LEDS_HALF+i].g = 0; 600 | } 601 | else { 602 | leds[NUM_LEDS_HALF-i-1].g = leds[NUM_LEDS_HALF-i-1].g + Color.g; 603 | leds[NUM_LEDS_HALF+i].g = leds[NUM_LEDS_HALF+i].g + Color.g; 604 | } 605 | 606 | 607 | if (leds[NUM_LEDS_HALF-i-1].b + Color.b > 255) { 608 | leds[NUM_LEDS_HALF-i-1].b = 255; 609 | leds[NUM_LEDS_HALF+i].b = 255; 610 | } 611 | else if (leds[NUM_LEDS_HALF-i-1].b + Color.b < 0) { 612 | leds[NUM_LEDS_HALF-i-1].b = 0; 613 | leds[NUM_LEDS_HALF+i].b = 0; 614 | } 615 | else { 616 | leds[NUM_LEDS_HALF-i-1].b = leds[NUM_LEDS_HALF-i-1].b + Color.b; 617 | leds[NUM_LEDS_HALF+i].b = leds[NUM_LEDS_HALF+i].b + Color.b; 618 | } 619 | 620 | //All the other LEDs begin their fading journey to eventual total darkness 621 | } else { 622 | leds[NUM_LEDS_HALF-i-1] = CRGB(leds[NUM_LEDS_HALF-i-1].r/fade_scale, leds[NUM_LEDS_HALF-i-1].g/fade_scale, leds[NUM_LEDS_HALF-i-1].b/fade_scale); 623 | leds[NUM_LEDS_HALF+i] = CRGB(leds[NUM_LEDS_HALF+i].r/fade_scale, leds[NUM_LEDS_HALF+i].g/fade_scale, leds[NUM_LEDS_HALF+i].b/fade_scale); 624 | 625 | } 626 | 627 | //keep peak at top for small LED array 628 | if(height > peak) peak = height; // Keep 'peak' dot at top 629 | if(peak > 0 && peak < NUM_LEDS_HALF) { 630 | leds[NUM_LEDS_HALF-peak] = CHSV(200, 200, 200); // set peak dot 631 | leds[NUM_LEDS_HALF+peak-1] = CHSV(200, 200, 200); // set peak dot 632 | } 633 | 634 | 635 | FastLED.show(); 636 | 637 | // Every few frames, make the peak pixel drop by 1: 638 | 639 | if(++dotCount >= PEAK_FALL_split) { //fall rate 640 | 641 | if(peak > 0) peak--; 642 | dotCount = 0; 643 | } 644 | 645 | 646 | } 647 | 648 | 649 | ///////////////////////////////////////////////////////////////////////////////////// 650 | //quadrasect spread out VU w/ falling dot 651 | 652 | void visualize_music_3() { 653 | 654 | height_and_condition(); 655 | height = height / 4; 656 | 657 | 658 | /*Set the different leds. Control for too high and too low values. 659 | Fun thing to try: Dont account for overflow in one direction, 660 | some interesting light effects appear! */ 661 | //Small LED Array 662 | for (int i = 0; i < NUM_LEDS_QUARTER; i++) 663 | //The leds we want to show 664 | if (i < height) { 665 | if (leds[i].r + Color.r > 255) { 666 | leds[i].r = 255; 667 | leds[NUM_LEDS_QUARTER+i].r = 255; 668 | leds[NUM_LEDS_HALF+i].r = 255; 669 | leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i].r = 255; 670 | } 671 | else if (leds[i].r + Color.r < 0) { 672 | leds[i].r = 0; 673 | leds[NUM_LEDS_QUARTER+i].r = 0; 674 | leds[NUM_LEDS_HALF+i].r = 0; 675 | leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i].r = 0; 676 | } 677 | else { 678 | leds[i].r = leds[i].r + Color.r; 679 | leds[NUM_LEDS_QUARTER+i].r = leds[NUM_LEDS_QUARTER+i].r + Color.r; 680 | leds[NUM_LEDS_HALF+i].r = leds[NUM_LEDS_HALF+i].r + Color.r; 681 | leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i].r = leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i].r + Color.r; 682 | } 683 | 684 | if (leds[i].g + Color.g > 255) { 685 | leds[i].g = 255; 686 | leds[NUM_LEDS_QUARTER+i].g = 255; 687 | leds[NUM_LEDS_HALF+i].g = 255; 688 | leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i].g = 255; 689 | } 690 | else if (leds[i].g + Color.g < 0) { 691 | leds[i].g = 0; 692 | leds[NUM_LEDS_QUARTER+i].g = 0; 693 | leds[NUM_LEDS_HALF+i].g = 0; 694 | leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i].g = 0; 695 | } 696 | else { 697 | leds[i].g = leds[i].g + Color.g; 698 | leds[NUM_LEDS_QUARTER+i].g = leds[NUM_LEDS_QUARTER+i].g + Color.g; 699 | leds[NUM_LEDS_HALF+i].g = leds[NUM_LEDS_HALF+i].g + Color.g; 700 | leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i].g = leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i].g + Color.g; 701 | } 702 | 703 | 704 | if (leds[i].b + Color.b > 255) { 705 | leds[i].b = 255; 706 | leds[NUM_LEDS_QUARTER+i].b = 255; 707 | leds[NUM_LEDS_HALF+i].b = 255; 708 | leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i].b = 255; 709 | } 710 | else if (leds[i].b + Color.b < 0) { 711 | leds[i].b = 0; 712 | leds[NUM_LEDS_QUARTER+i].b = 0; 713 | leds[NUM_LEDS_HALF+i].b = 0; 714 | leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i].b = 0; 715 | } 716 | else { 717 | leds[i].b = leds[i].b + Color.b; 718 | leds[NUM_LEDS_QUARTER+i].b = leds[NUM_LEDS_QUARTER+i].b + Color.b; 719 | leds[NUM_LEDS_HALF+i].b = leds[NUM_LEDS_HALF+i].b + Color.b; 720 | leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i].b = leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i].b + Color.b; 721 | } 722 | 723 | //All the other LEDs begin their fading journey to eventual total darkness 724 | } else { 725 | leds[i] = CRGB(leds[i].r/fade_scale, leds[i].g/fade_scale, leds[i].b/fade_scale); 726 | leds[NUM_LEDS_QUARTER+i] = CRGB(leds[NUM_LEDS_QUARTER+i].r/fade_scale, leds[NUM_LEDS_QUARTER+i].g/fade_scale, leds[NUM_LEDS_QUARTER+i].b/fade_scale); 727 | leds[NUM_LEDS_HALF+i] = CRGB(leds[NUM_LEDS_HALF+i].r/fade_scale, leds[NUM_LEDS_HALF+i].g/fade_scale, leds[NUM_LEDS_HALF+i].b/fade_scale); 728 | leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i] = CRGB(leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i].r/fade_scale, leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i].g/fade_scale, leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i].b/fade_scale); 729 | } 730 | 731 | //peak for small LED array 732 | //keep peak at top 733 | if(height > peak) peak = height; // Keep 'peak' dot at top 734 | if(peak > 0 && peak < NUM_LEDS_QUARTER) { 735 | leds[peak] = CHSV(200, 200, 200); // set peak dot 736 | leds[NUM_LEDS_QUARTER+peak] = CHSV(200, 200, 200); // set peak dot 737 | leds[NUM_LEDS_HALF+peak] = CHSV(200, 200, 200); 738 | leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+peak] = CHSV(200, 200, 200); 739 | } 740 | 741 | 742 | FastLED.show(); 743 | 744 | // Every few frames, make the peak pixel drop by 1: 745 | 746 | if(++dotCount >= PEAK_FALL_split) { //fall rate 747 | if(peak > 0) peak--; 748 | dotCount = 0; 749 | } 750 | 751 | } 752 | 753 | 754 | ///////////////////////////////////////////////////////////////////////////////////// 755 | //outside in spread visualizer 756 | 757 | void visualize_music_4() { 758 | 759 | height_and_condition(); 760 | height = height / 2; 761 | 762 | /*Set the different leds. Control for too high and too low values. 763 | Fun thing to try: Dont account for overflow in one direction, 764 | some interesting light effects appear! */ 765 | // Update Small LED array 766 | for (int i = 0; i < NUM_LEDS_HALF; i++) 767 | //The leds we want to show 768 | if (i < height) { 769 | if (leds[i].r + Color.r > 255) { 770 | leds[i].r = 255; 771 | leds[NUM_LEDS-1-i].r = 255; 772 | } 773 | else if (leds[i].r + Color.r < 0) { 774 | leds[i].r = 0; 775 | leds[NUM_LEDS-1-i].r = 0; 776 | } 777 | else { 778 | leds[i].r = leds[i].r + Color.r; 779 | leds[NUM_LEDS-1-i].r = leds[NUM_LEDS-1-i].r + Color.r; 780 | } 781 | 782 | if (leds[i].g + Color.g > 255) { 783 | leds[i].g = 255; 784 | leds[NUM_LEDS-1-i].g = 255; 785 | } 786 | else if (leds[i].g + Color.g < 0) { 787 | leds[i].g = 0; 788 | leds[NUM_LEDS-1-i].g = 0; 789 | } 790 | else { 791 | leds[i].g = leds[i].g + Color.g; 792 | leds[NUM_LEDS-1-i].g = leds[NUM_LEDS-1-i].g + Color.g; 793 | } 794 | 795 | 796 | if (leds[i].b + Color.b > 255) { 797 | leds[i].b = 255; 798 | leds[NUM_LEDS-1-i].b = 255; 799 | } 800 | else if (leds[i].b + Color.b < 0) { 801 | leds[i].b = 0; 802 | leds[NUM_LEDS-1-i].b = 0; 803 | } 804 | else { 805 | leds[i].b = leds[i].b + Color.b; 806 | leds[NUM_LEDS-1-i].b = leds[NUM_LEDS-1-i].b + Color.b; 807 | } 808 | 809 | //All the other LEDs begin their fading journey to eventual total darkness 810 | } else { 811 | leds[i] = CRGB(leds[i].r/fade_scale, leds[i].g/fade_scale, leds[i].b/fade_scale); 812 | leds[NUM_LEDS-1-i] = CRGB(leds[NUM_LEDS-1-i].r/fade_scale, leds[NUM_LEDS-1-i].g/fade_scale, leds[NUM_LEDS-1-i].b/fade_scale); 813 | 814 | } 815 | 816 | //keep peak at top for small LED array 817 | if(height > peak) peak = height; // Keep 'peak' dot at top 818 | if(peak > 0 && peak < NUM_LEDS_HALF) { 819 | leds[peak] = CHSV(gHue, 200, 200); // set peak dot 820 | leds[NUM_LEDS-1-peak] = CHSV(gHue, 200, 200); // set peak dot 821 | } 822 | 823 | FastLED.show(); 824 | 825 | // Every few frames, make the peak pixel drop by 1: 826 | 827 | if(++dotCount >= PEAK_FALL_split) { //fall rate 828 | 829 | if(peak > 0) peak--; 830 | dotCount = 0; 831 | } 832 | EVERY_N_MILLISECONDS(20) {gHue++;} 833 | 834 | } 835 | 836 | 837 | //Compute average of a int array, given the starting pointer and the length 838 | int compute_average(int *avgs, int len) { 839 | int sum = 0; 840 | for (int i = 0; i < len; i++) 841 | sum += avgs[i]; 842 | 843 | return (int)(sum / len); 844 | 845 | } 846 | 847 | //Insert a value into an array, and shift it down removing 848 | //the first value if array already full 849 | void insert(int val, int *avgs, int len) { 850 | for (int i = 0; i < len; i++) { 851 | if (avgs[i] == -1) { 852 | avgs[i] = val; 853 | return; 854 | } 855 | } 856 | 857 | for (int i = 1; i < len; i++) { 858 | avgs[i - 1] = avgs[i]; 859 | } 860 | avgs[len - 1] = val; 861 | } 862 | 863 | //Function imported from the arduino website. 864 | //Basically map, but with a curve on the scale (can be non-uniform). 865 | float fscale( float originalMin, float originalMax, float newBegin, float 866 | newEnd, float inputValue, float curve){ 867 | 868 | float OriginalRange = 0; 869 | float NewRange = 0; 870 | float zeroRefCurVal = 0; 871 | float normalizedCurVal = 0; 872 | float rangedValue = 0; 873 | boolean invFlag = 0; 874 | 875 | 876 | // condition curve parameter 877 | // limit range 878 | 879 | if (curve > 10) curve = 10; 880 | if (curve < -10) curve = -10; 881 | 882 | curve = (curve * -.1) ; // - invert and scale - this seems more intuitive - postive numbers give more weight to high end on output 883 | curve = pow(10, curve); // convert linear scale into lograthimic exponent for other pow function 884 | 885 | // Check for out of range inputValues 886 | if (inputValue < originalMin) { 887 | inputValue = originalMin; 888 | } 889 | if (inputValue > originalMax) { 890 | inputValue = originalMax; 891 | } 892 | 893 | // Zero Refference the values 894 | OriginalRange = originalMax - originalMin; 895 | 896 | if (newEnd > newBegin){ 897 | NewRange = newEnd - newBegin; 898 | } 899 | else 900 | { 901 | NewRange = newBegin - newEnd; 902 | invFlag = 1; 903 | } 904 | 905 | zeroRefCurVal = inputValue - originalMin; 906 | normalizedCurVal = zeroRefCurVal / OriginalRange; // normalize to 0 - 1 float 907 | 908 | // Check for originalMin > originalMax - the math for all other cases i.e. negative numbers seems to work out fine 909 | if (originalMin > originalMax ) { 910 | return 0; 911 | } 912 | 913 | if (invFlag == 0){ 914 | rangedValue = (pow(normalizedCurVal, curve) * NewRange) + newBegin; 915 | 916 | } 917 | else // invert the ranges 918 | { 919 | rangedValue = newBegin - (pow(normalizedCurVal, curve) * NewRange); 920 | } 921 | 922 | return rangedValue; 923 | } 924 | 925 | 926 | ////////////////////////////////////////////////////////////////////////// 927 | //FASTLED MATRIX FUNCTIONS 928 | ////////////////////////////////////////////////////////////////////////// 929 | 930 | void blobby_flow_gaps() { 931 | // fill the led array 2/16-bit noise values 932 | fill_2dnoise16(LEDS.leds(), kMatrixWidth, kMatrixHeight, kMatrixSerpentineLayout, 933 | octaves,x,xscale,y,yscale,v_time, 934 | hue_octaves,hxy,hue_scale,hxy,hue_scale,hue_time, false); 935 | 936 | LEDS.show(); 937 | 938 | // adjust the intra-frame time values 939 | x += x_speed; 940 | y += y_speed; 941 | v_time += time_speed; 942 | hue_time += hue_speed; 943 | // delay(50); 944 | } 945 | 946 | 947 | void blobby_flow() { 948 | 949 | 950 | if (newborn ==1) { 951 | SetupBlackAndWhiteStripedPalette(); 952 | ChangeSettingsPeriodically(); 953 | } else { 954 | // Periodically choose a new palette, speed, and scale 955 | ChangePaletteAndSettingsPeriodically(); 956 | } 957 | 958 | 959 | // generate noise data 960 | fillnoise8(); 961 | 962 | // convert the noise data to colors in the LED array 963 | // using the current palette 964 | mapNoiseToLEDsUsingPalette(); 965 | 966 | LEDS.show(); 967 | // delay(10); 968 | } 969 | 970 | 971 | 972 | // Fill the x/y array of 8-bit noise values using the inoise8 function. 973 | void fillnoise8() { 974 | // If we're runing at a low "speed", some 8-bit artifacts become visible 975 | // from frame-to-frame. In order to reduce this, we can do some fast data-smoothing. 976 | // The amount of data smoothing we're doing depends on "speed". 977 | uint8_t dataSmoothing = 0; 978 | if( speed < 50) { 979 | dataSmoothing = 200 - (speed * 4); 980 | } 981 | 982 | for(int i = 0; i < MAX_DIMENSION; i++) { 983 | int ioffset = scale * i; 984 | for(int j = 0; j < MAX_DIMENSION; j++) { 985 | int joffset = scale * j; 986 | 987 | uint8_t data = inoise8(x + ioffset,y + joffset,z); 988 | 989 | // The range of the inoise8 function is roughly 16-238. 990 | // These two operations expand those values out to roughly 0..255 991 | // You can comment them out if you want the raw noise data. 992 | data = qsub8(data,16); 993 | data = qadd8(data,scale8(data,39)); 994 | 995 | if( dataSmoothing ) { 996 | uint8_t olddata = noise[i][j]; 997 | uint8_t newdata = scale8( olddata, dataSmoothing) + scale8( data, 256 - dataSmoothing); 998 | data = newdata; 999 | } 1000 | 1001 | noise[i][j] = data; 1002 | } 1003 | } 1004 | 1005 | z += speed; 1006 | 1007 | // apply slow drift to X and Y, just for visual variation. 1008 | x += speed / 8; 1009 | y -= speed / 16; 1010 | } 1011 | 1012 | void mapNoiseToLEDsUsingPalette() 1013 | { 1014 | static uint8_t ihue=0; 1015 | 1016 | for(int i = 0; i < kMatrixWidth; i++) { 1017 | for(int j = 0; j < kMatrixHeight; j++) { 1018 | // We use the value at the (i,j) coordinate in the noise 1019 | // array for our brightness, and the flipped value from (j,i) 1020 | // for our pixel's index into the color palette. 1021 | 1022 | uint8_t index = noise[j][i]; 1023 | uint8_t bri = noise[i][j]; 1024 | 1025 | // if this palette is a 'loop', add a slowly-changing base value 1026 | if( colorLoop) { 1027 | index += ihue; 1028 | } 1029 | 1030 | // brighten up, as the color palette itself often contains the 1031 | // light/dark dynamic range desired 1032 | if( bri > 127 ) { 1033 | bri = 255; 1034 | } else { 1035 | bri = dim8_raw( bri * 2); 1036 | } 1037 | 1038 | CRGB color = ColorFromPalette( currentPalette, index, bri); 1039 | leds[XY(i,j)] = color; 1040 | } 1041 | } 1042 | 1043 | ihue+=1; 1044 | } 1045 | 1046 | 1047 | 1048 | // There are several different palettes of colors demonstrated here. 1049 | // 1050 | // FastLED provides several 'preset' palettes: RainbowColors_p, RainbowStripeColors_p, 1051 | // OceanColors_p, CloudColors_p, LavaColors_p, ForestColors_p, and PartyColors_p. 1052 | // 1053 | // Additionally, you can manually define your own color palettes, or you can write 1054 | // code that creates color palettes on the fly. 1055 | 1056 | // 1 = 5 sec per palette 1057 | // 2 = 10 sec per palette 1058 | // etc 1059 | #define HOLD_PALETTES_X_TIMES_AS_LONG 1 1060 | 1061 | void ChangePaletteAndSettingsPeriodically() 1062 | { 1063 | EVERY_N_MILLISECONDS(100) { 1064 | uint8_t secondHand = ((millis() / 1000) / HOLD_PALETTES_X_TIMES_AS_LONG) % 60; 1065 | static uint8_t lastSecond = 99; 1066 | 1067 | if( lastSecond != secondHand) { 1068 | lastSecond = secondHand; 1069 | if( secondHand == 0) { 1070 | currentPalette = RainbowColors_p; 1071 | speed = 6; 1072 | // speed = 20; 1073 | scale = 30; 1074 | colorLoop = 1; } 1075 | if( secondHand == 5) { 1076 | SetupPurpleAndGreenPalette(); 1077 | speed = 4; 1078 | // speed = 10; 1079 | scale = 50; 1080 | colorLoop = 1; } 1081 | if( secondHand == 10) { 1082 | SetupBlackAndWhiteStripedPalette(); 1083 | speed = 4; 1084 | // speed = 20; 1085 | scale = 30; 1086 | colorLoop = 1; } 1087 | if( secondHand == 15) { 1088 | currentPalette = ForestColors_p; 1089 | speed = 12; 1090 | scale =120; 1091 | colorLoop = 0; } 1092 | if( secondHand == 20) { 1093 | currentPalette = CloudColors_p; 1094 | speed = 6; 1095 | scale = 30; 1096 | colorLoop = 0; } 1097 | if( secondHand == 25) { 1098 | currentPalette = LavaColors_p; 1099 | speed = 8; 1100 | scale = 50; 1101 | colorLoop = 0; } 1102 | if( secondHand == 30) { 1103 | currentPalette = OceanColors_p; 1104 | speed = 8; 1105 | // speed = 20; 1106 | scale = 90; 1107 | colorLoop = 0; } 1108 | if( secondHand == 35) { 1109 | currentPalette = PartyColors_p; 1110 | speed = 8; 1111 | // speed = 20; 1112 | scale = 30; 1113 | colorLoop = 1; } 1114 | if( secondHand == 40) { 1115 | SetupRandomPalette(); 1116 | speed = 8; 1117 | // speed = 20; 1118 | scale = 20; 1119 | colorLoop = 1; } 1120 | if( secondHand == 45) { 1121 | SetupRandomPalette(); 1122 | speed = 8; 1123 | // speed = 50; 1124 | scale = 50; 1125 | colorLoop = 1; } 1126 | if( secondHand == 50) { 1127 | SetupRandomPalette(); 1128 | speed = 8; 1129 | // speed = 90; 1130 | scale = 90; 1131 | colorLoop = 1; } 1132 | if( secondHand == 55) { 1133 | currentPalette = RainbowStripeColors_p; 1134 | speed = 8; 1135 | // speed = 30; 1136 | scale = 20; 1137 | colorLoop = 1; } 1138 | } 1139 | } 1140 | } 1141 | 1142 | void ChangeSettingsPeriodically() 1143 | { 1144 | EVERY_N_MILLISECONDS(100) { 1145 | uint8_t secondHand = ((millis() / 1000) / HOLD_PALETTES_X_TIMES_AS_LONG) % 60; 1146 | static uint8_t lastSecond = 99; 1147 | 1148 | if( lastSecond != secondHand) { 1149 | lastSecond = secondHand; 1150 | if( secondHand == 0) { 1151 | speed = 3; 1152 | // speed = 20; 1153 | scale = 30; 1154 | colorLoop = 1; } 1155 | if( secondHand == 5) { 1156 | speed = 2; 1157 | // speed = 10; 1158 | scale = 50; 1159 | colorLoop = 1; } 1160 | if( secondHand == 10) { 1161 | speed = 2; 1162 | // speed = 20; 1163 | scale = 30; 1164 | colorLoop = 1; } 1165 | if( secondHand == 15) { 1166 | speed = 6; 1167 | scale =120; 1168 | colorLoop = 0; } 1169 | if( secondHand == 20) { 1170 | speed = 3; 1171 | scale = 30; 1172 | colorLoop = 0; } 1173 | if( secondHand == 25) { 1174 | currentPalette = LavaColors_p; 1175 | speed = 4; 1176 | scale = 50; 1177 | colorLoop = 0; } 1178 | if( secondHand == 30) { 1179 | speed = 4; 1180 | // speed = 20; 1181 | scale = 90; 1182 | colorLoop = 0; } 1183 | if( secondHand == 35) { 1184 | speed = 4; 1185 | // speed = 20; 1186 | scale = 30; 1187 | colorLoop = 1; } 1188 | if( secondHand == 40) { 1189 | speed = 4; 1190 | // speed = 20; 1191 | scale = 20; 1192 | colorLoop = 1; } 1193 | if( secondHand == 45) { 1194 | speed = 4; 1195 | // speed = 50; 1196 | scale = 50; 1197 | colorLoop = 1; } 1198 | if( secondHand == 50) { 1199 | speed = 8; 1200 | // speed = 90; 1201 | scale = 90; 1202 | colorLoop = 1; } 1203 | if( secondHand == 55) { 1204 | speed = 4; 1205 | // speed = 30; 1206 | scale = 20; 1207 | colorLoop = 1; } 1208 | } 1209 | } 1210 | } 1211 | 1212 | // This function generates a random palette that's a gradient 1213 | // between four different colors. The first is a dim hue, the second is 1214 | // a bright hue, the third is a bright pastel, and the last is 1215 | // another bright hue. This gives some visual bright/dark variation 1216 | // which is more interesting than just a gradient of different hues. 1217 | void SetupRandomPalette() 1218 | { 1219 | currentPalette = CRGBPalette16( 1220 | CHSV( random8(), 255, 32), 1221 | CHSV( random8(), 255, 255), 1222 | CHSV( random8(), 128, 255), 1223 | CHSV( random8(), 255, 255)); 1224 | } 1225 | 1226 | // This function sets up a palette of black and white stripes, 1227 | // using code. Since the palette is effectively an array of 1228 | // sixteen CRGB colors, the various fill_* functions can be used 1229 | // to set them up. 1230 | void SetupBlackAndWhiteStripedPalette() 1231 | { 1232 | // 'black out' all 16 palette entries... 1233 | fill_solid( currentPalette, 16, CRGB::Black); 1234 | // and set every fourth one to white. 1235 | currentPalette[0] = CRGB::White; 1236 | currentPalette[4] = CRGB::White; 1237 | currentPalette[8] = CRGB::White; 1238 | currentPalette[12] = CRGB::White; 1239 | 1240 | } 1241 | 1242 | // This function sets up a palette of purple and green stripes. 1243 | void SetupPurpleAndGreenPalette() 1244 | { 1245 | CRGB purple = CHSV( HUE_PURPLE, 255, 255); 1246 | CRGB green = CHSV( HUE_GREEN, 255, 255); 1247 | CRGB black = CRGB::Black; 1248 | 1249 | currentPalette = CRGBPalette16( 1250 | green, green, black, black, 1251 | purple, purple, black, black, 1252 | green, green, black, black, 1253 | purple, purple, black, black ); 1254 | } 1255 | 1256 | 1257 | // 1258 | // Mark's xy coordinate mapping code. See the XYMatrix for more information on it. 1259 | // 1260 | uint16_t XY( uint8_t x, uint8_t y) 1261 | { 1262 | uint16_t i; 1263 | if( kMatrixSerpentineLayout == false) { 1264 | i = (y * kMatrixWidth) + x; 1265 | } 1266 | if( kMatrixSerpentineLayout == true) { 1267 | if( y & 0x01) { 1268 | // Odd rows run backwards 1269 | uint8_t reverseX = (kMatrixWidth - 1) - x; 1270 | i = (y * kMatrixWidth) + reverseX; 1271 | } else { 1272 | // Even rows run forwards 1273 | i = (y * kMatrixWidth) + x; 1274 | } 1275 | } 1276 | return i; 1277 | } 1278 | 1279 | 1280 | 1281 | 1282 | ///////////////////////////////////////////////////////////////////////////// 1283 | //flash ripple and background pulse visualizer 1284 | 1285 | void vu7() { 1286 | 1287 | EVERY_N_MILLISECONDS(1000) { 1288 | peakspersec = peakcount; // Count the peaks per second. This value will become the foreground hue. 1289 | peakcount = 0; // Reset the counter every second. 1290 | } 1291 | 1292 | soundmems(); 1293 | 1294 | EVERY_N_MILLISECONDS(20) { 1295 | ripple3(); 1296 | } 1297 | 1298 | // show_at_max_brightness_for_power(); 1299 | FastLED.show(); 1300 | delay(3); 1301 | } // loop() 1302 | 1303 | 1304 | void soundmems() { // Rolling average counter - means we don't have to go through an array each time. 1305 | newtime = millis(); 1306 | int tmp = analogRead(MIC_PIN) - 512; 1307 | sample = abs(tmp); 1308 | 1309 | //int potin = map(analogRead(POT_PIN), 0, 1023, 0, 90); 1310 | 1311 | samplesum = samplesum + sample - samplearray[samplecount]; // Add the new sample and remove the oldest sample in the array 1312 | sampleavg = samplesum / NSAMPLES; // Get an average 1313 | samplearray[samplecount] = sample; // Update oldest sample in the array with new sample 1314 | samplecount = (samplecount + 1) % NSAMPLES; // Update the counter for the array 1315 | 1316 | //if (newtime > (oldtime + 200)) digitalWrite(13, LOW); // Turn the LED off 200ms after the last peak. 1317 | 1318 | if ((sample > (sampleavg + 80)) && (newtime > (oldtime + 80)) ) { // Check for a peak, which is 30 > the average, but wait at least 60ms for another. 1319 | //note: hardcoded 30 instead of potin in above line 1320 | step = -1; 1321 | peakcount++; 1322 | //digitalWrite(13, HIGH); 1323 | oldtime = newtime; 1324 | } 1325 | } // soundmems() 1326 | 1327 | 1328 | 1329 | void ripple3() { 1330 | for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(bgcol, 255, sampleavg*2); // Set the background colour. 1331 | 1332 | switch (step) { 1333 | 1334 | case -1: // Initialize ripple variables. 1335 | center = random(NUM_LEDS); 1336 | colour = (peakspersec*10) % 255; // More peaks/s = higher the hue colour. 1337 | step = 0; 1338 | bgcol = bgcol+8; 1339 | break; 1340 | 1341 | case 0: 1342 | leds[center] = CHSV(colour, 255, 255); // Display the first pixel of the ripple. 1343 | step ++; 1344 | break; 1345 | 1346 | case maxsteps: // At the end of the ripples. 1347 | // step = -1; 1348 | break; 1349 | 1350 | default: // Middle of the ripples. 1351 | leds[(center + step + NUM_LEDS) % NUM_LEDS] += CHSV(colour, 255, myfade/step*2); // Simple wrap from Marc Miller. 1352 | leds[(center - step + NUM_LEDS) % NUM_LEDS] += CHSV(colour, 255, myfade/step*2); 1353 | step ++; // Next step. 1354 | break; 1355 | } // switch step 1356 | 1357 | } 1358 | 1359 | 1360 | //////////////////////////////////// 1361 | ///Blur Visualize 1362 | 1363 | void blur() { 1364 | 1365 | 1366 | EVERY_N_MILLISECONDS(40) { 1367 | uint8_t blurAmount = dim8_raw( beatsin8(3,64, 192) ); // A sinewave at 3 Hz with values ranging from 64 to 192. 1368 | blur1d( leds, NUM_LEDS, blurAmount); // Apply some blurring to whatever's already on the strip, which will eventually go black. 1369 | 1370 | uint8_t i = beatsin8( 9, 0, NUM_LEDS-1); 1371 | uint8_t j = beatsin8( 7, 0, NUM_LEDS-1); 1372 | uint8_t k = beatsin8( 5, 0, NUM_LEDS-1); 1373 | 1374 | 1375 | // The color of each point shifts over time, each at a different speed. 1376 | uint16_t ms = millis(); 1377 | leds[(i+j)/2] = CHSV( ms / 29, 200, 255); 1378 | leds[(j+k)/2] = CHSV( ms / 41, 200, 255); 1379 | leds[(k+i)/2] = CHSV( ms / 73, 200, 255); 1380 | leds[(k+i+j)/3] = CHSV( ms / 53, 200, 255); 1381 | 1382 | FastLED.show(); 1383 | } 1384 | 1385 | } // loop() 1386 | 1387 | 1388 | ////////////////////////////////////////////////////////////////////////////////////////////////////////// 1389 | // Slow blending change of hue with VU meter dot over it, combine with vu10() to make work 1390 | 1391 | ///Need to figure out what is making, all lights go on periodically and fix 1392 | 1393 | void blur_and_beat() { 1394 | 1395 | height_and_condition(); 1396 | height = height / 4; 1397 | 1398 | for (int i = 0; i < NUM_LEDS; i++) 1399 | leds[i] = CRGB(leds[i].r/fade_scale, leds[i].g/fade_scale, leds[i].b/fade_scale); 1400 | 1401 | uint8_t blurAmount = dim8_raw( beatsin8(3,64, 192) ); // A sinewave at 3 Hz with values ranging from 64 to 192. 1402 | blur1d( leds, NUM_LEDS, blurAmount); // Apply some blurring to whatever's already on the strip, which will eventually go black. 1403 | 1404 | uint8_t i = beatsin8( 9, 0, NUM_LEDS-1); 1405 | uint8_t j = beatsin8( 7, 0, NUM_LEDS-1); 1406 | uint8_t k = beatsin8( 5, 0, NUM_LEDS-1); 1407 | 1408 | 1409 | // The color of each point shifts over time, each at a different speed. 1410 | uint16_t ms = millis(); 1411 | leds[(i+j)/2] = CHSV( ms / 29, 200, 255); 1412 | leds[(j+k)/2] = CHSV( ms / 41, 200, 255); 1413 | leds[(k+i)/2] = CHSV( ms / 73, 200, 255); 1414 | leds[(k+i+j)/3] = CHSV( ms / 53, 200, 255); 1415 | 1416 | 1417 | //VU Dot overlay on blur 1418 | if(height > peak) peak = height; // Keep 'peak' dot at top 1419 | if(peak > 2 && peak < NUM_LEDS_QUARTER) { 1420 | 1421 | for (int j = 0; j < 3; j++) { 1422 | leds[peak-j] = CHSV(200, 200, 200); // set peak dot 1423 | leds[NUM_LEDS_QUARTER+peak-j] = CHSV(200, 200, 200); // set peak dot 1424 | leds[NUM_LEDS_HALF+peak-j] = CHSV(200, 200, 200); 1425 | leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+peak-j] = CHSV(200, 200, 200); 1426 | } 1427 | } 1428 | 1429 | 1430 | FastLED.show(); 1431 | 1432 | if(++dotCount >= PEAK_FALL_split-5) { //fall rate 1433 | if(peak > 0) peak--; 1434 | dotCount = 0; 1435 | } 1436 | 1437 | 1438 | //delay(2); 1439 | } // loop() 1440 | 1441 | 1442 | 1443 | ////////////////////////////////////////////////////////////////////////////////////////////////////////// 1444 | // blur with ripple spark overlay 1445 | 1446 | void blur_and_spark() { 1447 | 1448 | height_and_condition(); 1449 | height = height / 4; 1450 | 1451 | EVERY_N_MILLISECONDS(1000) { 1452 | peakspersec = peakcount; // Count the peaks per second. This value will become the foreground hue. 1453 | peakcount = 0; // Reset the counter every second. 1454 | } 1455 | 1456 | for (int i = 0; i < NUM_LEDS; i++) 1457 | leds[i] = CRGB(leds[i].r/fade_scale, leds[i].g/fade_scale, leds[i].b/fade_scale); 1458 | 1459 | 1460 | uint8_t blurAmount = dim8_raw( beatsin8(3,64, 192) ); // A sinewave at 3 Hz with values ranging from 64 to 192. 1461 | blur1d( leds, NUM_LEDS, blurAmount); // Apply some blurring to whatever's already on the strip, which will eventually go black. 1462 | 1463 | uint8_t i = beatsin8( 9, 0, NUM_LEDS-1); 1464 | uint8_t j = beatsin8( 7, 0, NUM_LEDS-1); 1465 | uint8_t k = beatsin8( 5, 0, NUM_LEDS-1); 1466 | 1467 | // The color of each point shifts over time, each at a different speed. 1468 | uint16_t ms = millis(); 1469 | leds[(i+j)/2] = CHSV( ms / 29, 200, 255); 1470 | leds[(j+k)/2] = CHSV( ms / 41, 200, 255); 1471 | leds[(k+i)/2] = CHSV( ms / 73, 200, 255); 1472 | leds[(k+i+j)/3] = CHSV( ms / 53, 200, 255); 1473 | 1474 | 1475 | soundrip_2(); 1476 | 1477 | EVERY_N_MILLISECONDS(30) { 1478 | rippled_2(); 1479 | } 1480 | 1481 | 1482 | FastLED.show(); 1483 | 1484 | } // loop() 1485 | 1486 | 1487 | void soundrip_2() { // Rolling average counter - means we don't have to go through an array each time. 1488 | 1489 | newtime = millis(); 1490 | int tmp = analogRead(MIC_PIN) - 512; 1491 | sample = abs(tmp); 1492 | 1493 | //int potin = map(analogRead(POT_PIN), 0, 1023, 0, 60) + 20; 1494 | 1495 | samplesum = samplesum + sample - samplearray[samplecount]; // Add the new sample and remove the oldest sample in the array 1496 | sampleavg = samplesum / NSAMPLES; // Get an average 1497 | samplearray[samplecount] = sample; // Update oldest sample in the array with new sample 1498 | samplecount = (samplecount + 1) % NSAMPLES; // Update the counter for the array 1499 | 1500 | if (newtime > (oldtime + 200)) digitalWrite(13, LOW); // Turn the LED off 200ms after the last peak. 1501 | 1502 | if ((sample > (sampleavg + 60)) && (newtime > (oldtime + 60)) ) { // Check for a peak, which is 30 > the average, but wait at least 60ms for another. 1503 | step = -1; 1504 | peakcount++; 1505 | digitalWrite(13, HIGH); 1506 | oldtime = newtime; 1507 | } 1508 | 1509 | } // soundmems() 1510 | 1511 | 1512 | 1513 | void rippled_2() { 1514 | 1515 | fadeToBlackBy(leds, NUM_LEDS, 44); // 8 bit, 1 = slow, 255 = fast 1516 | 1517 | switch (step) { 1518 | 1519 | case -1: // Initialize ripple variables. 1520 | center = random(NUM_LEDS); 1521 | colour = (peakspersec*10) % 255; // More peaks/s = higher the hue colour. 1522 | step = 0; 1523 | break; 1524 | 1525 | case 0: 1526 | leds[center] = CHSV(colour, 255, 255); // Display the first pixel of the ripple. 1527 | step ++; 1528 | break; 1529 | 1530 | case maxsteps: // At the end of the ripples. 1531 | // step = -1; 1532 | break; 1533 | 1534 | default: // Middle of the ripples. 1535 | leds[(center + step + NUM_LEDS) % NUM_LEDS] += CHSV(colour, 255, myfade/step*2); // Simple wrap from Marc Miller. 1536 | leds[(center - step + NUM_LEDS) % NUM_LEDS] += CHSV(colour, 255, myfade/step*2); 1537 | 1538 | step ++; // Next step. 1539 | break; 1540 | } // switch step 1541 | 1542 | } // ripple_2() 1543 | 1544 | 1545 | /////////////////////////////////////////////////////// 1546 | //Center Burst Visualizer 1547 | 1548 | void center_burst_FHT() { 1549 | 1550 | EVERY_N_MILLISECONDS(100) { // AWESOME palette blending capability. 1551 | 1552 | nblendPaletteTowardPalette(currentPalette, targetPalette, maxChanges); 1553 | } 1554 | 1555 | 1556 | EVERY_N_SECONDS(5) { // Change the palette every 5 seconds. 1557 | for (int i = 0; i < 16; i++) { 1558 | targetPalette[i] = CHSV(random8(), 255, 255); 1559 | } 1560 | } 1561 | 1562 | EVERY_N_MILLISECONDS(25) { 1563 | fadeToBlackBy(leds, NUM_LEDS, 5); // 8 bit, 1 = slow, 255 = fast 1564 | sndwave(); 1565 | soundmems(); 1566 | } 1567 | 1568 | FastLED.show(); 1569 | } 1570 | 1571 | void sndwave() { 1572 | 1573 | leds[NUM_LEDS/2] = ColorFromPalette(currentPalette, sample, sample*2, currentBlending); 1574 | 1575 | for (int i = NUM_LEDS - 1; i > NUM_LEDS/2; i--) { //move to the left 1576 | leds[i] = leds[i - 1]; 1577 | } 1578 | 1579 | for (int i = 0; i < NUM_LEDS/2; i++) { // move to the right 1580 | leds[i] = leds[i + 1]; 1581 | } 1582 | 1583 | } // sndwave() 1584 | 1585 | 1586 | 1587 | 1588 | /////////////////////////////////////////////////////// 1589 | //Center Burst Visualizer 1590 | 1591 | void center_burst_VU() { 1592 | 1593 | EVERY_N_MILLISECONDS(100) { // AWESOME palette blending capability. 1594 | 1595 | nblendPaletteTowardPalette(currentPalette, targetPalette, maxChanges); 1596 | } 1597 | 1598 | 1599 | EVERY_N_MILLISECONDS(25) { 1600 | fadeToBlackBy(leds, NUM_LEDS, 15); // 8 bit, 1 = slow, 255 = fast 1601 | sndwave(); 1602 | soundmems(); 1603 | } 1604 | 1605 | height_and_condition(); 1606 | height = height / 2; 1607 | 1608 | for (int i = 0; i < NUM_LEDS_HALF-48; i++) 1609 | //The leds we want to show 1610 | if (i < height) { 1611 | if (leds[i].r + Color.r > 255) { 1612 | leds[i].r = 255; 1613 | leds[NUM_LEDS-1-i].r = 255; 1614 | } 1615 | else if (leds[i].r + Color.r < 0) { 1616 | leds[i].r = 0; 1617 | leds[NUM_LEDS-1-i].r = 0; 1618 | } 1619 | else { 1620 | leds[i].r = leds[i].r + Color.r; 1621 | leds[NUM_LEDS-1-i].r = leds[NUM_LEDS-1-i].r + Color.r; 1622 | } 1623 | 1624 | if (leds[i].g + Color.g > 255) { 1625 | leds[i].g = 255; 1626 | leds[NUM_LEDS-1-i].g = 255; 1627 | } 1628 | else if (leds[i].g + Color.g < 0) { 1629 | leds[i].g = 0; 1630 | leds[NUM_LEDS-1-i].g = 0; 1631 | } 1632 | else { 1633 | leds[i].g = leds[i].g + Color.g; 1634 | leds[NUM_LEDS-1-i].g = leds[NUM_LEDS-1-i].g + Color.g; 1635 | } 1636 | 1637 | if (leds[i].b + Color.b > 255) { 1638 | leds[i].b = 255; 1639 | leds[NUM_LEDS-1-i].b = 255; 1640 | } 1641 | else if (leds[i].b + Color.b < 0) { 1642 | leds[i].b = 0; 1643 | leds[NUM_LEDS-1-i].b = 0; 1644 | } 1645 | else { 1646 | leds[i].b = leds[i].b + Color.b; 1647 | leds[NUM_LEDS-1-i].b = leds[NUM_LEDS-1-i].b + Color.b; 1648 | } 1649 | 1650 | //All the other LEDs begin their fading journey to eventual total darkness 1651 | } else { 1652 | leds[i] = CRGB(leds[i].r/fade_scale, leds[i].g/fade_scale, leds[i].b/fade_scale); 1653 | leds[NUM_LEDS-1-i] = CRGB(leds[NUM_LEDS-1-i].r/fade_scale, leds[NUM_LEDS-1-i].g/fade_scale, leds[NUM_LEDS-1-i].b/fade_scale); 1654 | 1655 | } 1656 | 1657 | //keep peak at top for small LED array 1658 | if(height > peak) peak = height; // Keep 'peak' dot at top 1659 | if(peak > 0 && peak < NUM_LEDS_HALF) { 1660 | leds[peak] = CHSV(gHue, 200, 200); // set peak dot 1661 | leds[NUM_LEDS-1-peak] = CHSV(gHue, 200, 200); // set peak dot 1662 | } 1663 | 1664 | EVERY_N_SECONDS(5) { // Change the palette every 5 seconds. 1665 | for (int i = 0; i < 16; i++) { 1666 | targetPalette[i] = CHSV(random8(), 255, 255); 1667 | } 1668 | } 1669 | 1670 | FastLED.show(); 1671 | 1672 | 1673 | if(++dotCount >= PEAK_FALL_split) { //fall rate 1674 | if(peak > 0) peak--; 1675 | dotCount = 0; 1676 | } 1677 | } 1678 | 1679 | /////////////////////////////////////////////////////// 1680 | //Center Burst and quad pulse overlay 1681 | 1682 | 1683 | void center_burst_quad_pulse() { 1684 | 1685 | 1686 | EVERY_N_MILLISECONDS(100) { // AWESOME palette blending capability. 1687 | 1688 | nblendPaletteTowardPalette(currentPalette, targetPalette, maxChanges); 1689 | } 1690 | 1691 | 1692 | EVERY_N_SECONDS(5) { // Change the palette every 5 seconds. 1693 | for (int i = 0; i < 16; i++) { 1694 | targetPalette[i] = CHSV(random8(), 255, 255); 1695 | } 1696 | } 1697 | 1698 | EVERY_N_MILLISECONDS(25) { 1699 | fadeToBlackBy(leds, NUM_LEDS, 10); // 8 bit, 1 = slow, 255 = fast 1700 | sndwave(); 1701 | soundmems(); 1702 | } 1703 | 1704 | height_and_condition(); 1705 | height = height / 2; 1706 | 1707 | 1708 | //keep peak at top for small LED array 1709 | if(height > peak) peak = height; // Keep 'peak' dot at top 1710 | if(peak > 2 && peak < NUM_LEDS_HALF) { 1711 | for (int j = 0; j < 3; j++) { 1712 | leds[peak-j] = CHSV(200, 200, 200); // set peak dot 1713 | leds[NUM_LEDS-1-peak+j] = CHSV(200, 200, 200); // set peak dot 1714 | } 1715 | } 1716 | 1717 | 1718 | FastLED.show(); 1719 | 1720 | // Every few frames, make the peak pixel drop by 1: 1721 | 1722 | if(++dotCount >= PEAK_FALL_split-4) { //fall rate 1723 | 1724 | if(peak > 0) peak--; 1725 | dotCount = 0; 1726 | } 1727 | 1728 | delay(2); 1729 | } 1730 | 1731 | /////////////////////////////////////////////////////////////////// 1732 | // Ripple with Black background and variable width 1733 | 1734 | 1735 | void vu10() { 1736 | 1737 | EVERY_N_MILLISECONDS(1000) { 1738 | peakspersec = peakcount; // Count the peaks per second. This value will become the foreground hue. 1739 | peakcount = 0; // Reset the counter every second. 1740 | } 1741 | 1742 | soundrip(); 1743 | 1744 | EVERY_N_MILLISECONDS(20) { 1745 | rippled(); 1746 | } 1747 | 1748 | FastLED.show(); 1749 | delay(3); 1750 | } // loop() 1751 | 1752 | 1753 | void soundrip() { // Rolling average counter - means we don't have to go through an array each time. 1754 | 1755 | newtime = millis(); 1756 | int tmp = analogRead(MIC_PIN) - 512; 1757 | sample = abs(tmp); 1758 | 1759 | //int potin = map(analogRead(POT_PIN), 0, 1023, 0, 60) + 20; 1760 | 1761 | samplesum = samplesum + sample - samplearray[samplecount]; // Add the new sample and remove the oldest sample in the array 1762 | sampleavg = samplesum / NSAMPLES; // Get an average 1763 | samplearray[samplecount] = sample; // Update oldest sample in the array with new sample 1764 | samplecount = (samplecount + 1) % NSAMPLES; // Update the counter for the array 1765 | 1766 | if (newtime > (oldtime + 400)) digitalWrite(13, LOW); // Turn the LED off 200ms after the last peak. 1767 | 1768 | 1769 | 1770 | EVERY_N_MILLISECONDS(1000) { 1771 | uint8_t width_adj = random8(15); 1772 | width = 30 + (width_adj * 10); 1773 | } 1774 | if ((sample > (sampleavg + width)) && (newtime > (oldtime + 60)) ) { // Check for a peak, which is 30 > the average, but wait at least 60ms for another. 1775 | step = -1; 1776 | peakcount++; 1777 | oldtime = newtime; 1778 | } 1779 | 1780 | } // soundmems() 1781 | 1782 | 1783 | 1784 | void rippled() { 1785 | 1786 | fadeToBlackBy(leds, NUM_LEDS, 44); // 8 bit, 1 = slow, 255 = fast 1787 | 1788 | switch (step) { 1789 | 1790 | case -1: // Initialize ripple variables. 1791 | center = random(NUM_LEDS); 1792 | colour = (peakspersec*10) % 255; // More peaks/s = higher the hue colour. 1793 | step = 0; 1794 | break; 1795 | 1796 | case 0: 1797 | leds[center] = CHSV(colour, 255, 255); // Display the first pixel of the ripple. 1798 | step ++; 1799 | break; 1800 | 1801 | case maxsteps: // At the end of the ripples. 1802 | // step = -1; 1803 | break; 1804 | 1805 | default: // Middle of the ripples. 1806 | leds[(center + step + NUM_LEDS) % NUM_LEDS] += CHSV(colour, 255, myfade/step*2); // Simple wrap from Marc Miller. 1807 | leds[(center - step + NUM_LEDS) % NUM_LEDS] += CHSV(colour, 255, myfade/step*2); 1808 | step ++; // Next step. 1809 | break; 1810 | } // switch step 1811 | 1812 | } // ripple() 1813 | 1814 | 1815 | 1816 | 1817 | 1818 | ///////////////////NEW PATTERNS////////// 1819 | 1820 | //////Matrix Sinelon 1821 | void matrix_sinelon() { 1822 | fadeToBlackBy( leds, NUM_LEDS, 25); 1823 | int pos = beatsin16( 19, 0, kMatrixWidth-1 ); 1824 | 1825 | for(int i = 0; i < kMatrixWidth; i++) { 1826 | leds[XY(i, pos)] += CHSV( gHue, 240, 140); 1827 | } 1828 | 1829 | for(int i = 0; i < kMatrixHeight; i++) { 1830 | leds[XY(pos, i)] += CHSV( gHue+100, 240, 140); 1831 | } 1832 | FastLED.show(); 1833 | EVERY_N_MILLISECONDS( 50 ) { gHue++; } // slowly cycle the "base color" through the rainbow 1834 | 1835 | } 1836 | 1837 | 1838 | 1839 | ////////////////////////////////////////////////////// 1840 | //////////////////Rotate Non-Reactive Visualizers 1841 | 1842 | void rotate_all_patterns() { 1843 | 1844 | gPatterns[gCurrentPatternNumber](); 1845 | 1846 | // send the 'leds' array out to the actual LED strip 1847 | FastLED.show(); 1848 | // insert a delay to keep the framerate modest 1849 | FastLED.delay(1000/FRAMES_PER_SECOND); 1850 | 1851 | // do some periodic updates 1852 | EVERY_N_MILLISECONDS( 20 ) { gHue++; } // slowly cycle the "base color" through the rainbow 1853 | EVERY_N_SECONDS( 20 ) { nextPattern(); } // change patterns periodically 1854 | 1855 | } 1856 | 1857 | #define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0])) 1858 | 1859 | void nextPattern() 1860 | { 1861 | // add one to the current pattern number, and wrap around at the end 1862 | gCurrentPatternNumber = (gCurrentPatternNumber + 1) % ARRAY_SIZE( gPatterns); 1863 | } 1864 | 1865 | void rainbow() 1866 | { 1867 | // FastLED's built-in rainbow generator 1868 | fill_rainbow( leds, NUM_LEDS, gHue, 7); 1869 | } 1870 | 1871 | void rainbowWithGlitter() 1872 | { 1873 | // built-in FastLED rainbow, plus some random sparkly glitter 1874 | rainbow(); 1875 | addGlitter(80); 1876 | } 1877 | 1878 | void addGlitter( fract8 chanceOfGlitter) 1879 | { 1880 | if( random8() < chanceOfGlitter) { 1881 | leds[ random16(NUM_LEDS) ] += CRGB::White; 1882 | } 1883 | } 1884 | 1885 | void confetti() 1886 | { 1887 | // random colored speckles that blink in and fade smoothly 1888 | fadeToBlackBy( leds, NUM_LEDS, 10); 1889 | int pos = random16(NUM_LEDS); 1890 | leds[pos] += CHSV( gHue + random8(64), 200, 255); 1891 | } 1892 | 1893 | void sinelon() 1894 | { 1895 | // a colored dot sweeping back and forth, with fading trails 1896 | fadeToBlackBy( leds, NUM_LEDS, 20); 1897 | int pos = beatsin16( 13, 0, NUM_LEDS-1 ); 1898 | leds[pos] += CHSV( gHue, 255, 192); 1899 | } 1900 | 1901 | void bpm() 1902 | { 1903 | // colored stripes pulsing at a defined Beats-Per-Minute (BPM) 1904 | uint8_t BeatsPerMinute = 62; 1905 | CRGBPalette16 palette = PartyColors_p; 1906 | uint8_t beat = beatsin8( BeatsPerMinute, 64, 255); 1907 | for( int i = 0; i < NUM_LEDS; i++) { //9948 1908 | leds[i] = ColorFromPalette(palette, gHue+(i*2), beat-gHue+(i*10)); 1909 | } 1910 | } 1911 | 1912 | void juggle() { 1913 | // eight colored dots, weaving in and out of sync with each other 1914 | fadeToBlackBy( leds, NUM_LEDS, 20); 1915 | byte dothue = 0; 1916 | for( int i = 0; i < 8; i++) { 1917 | leds[beatsin16( i+7, 0, NUM_LEDS-1 )] |= CHSV(dothue, 200, 255); 1918 | dothue += 32; 1919 | } 1920 | } 1921 | 1922 | /////////////////////////////////////////////////////////////////// 1923 | //FASTLED XYMATRIX PATTERN EXAMPLE 1924 | 1925 | void XYmatrix() 1926 | { 1927 | uint32_t ms = millis(); 1928 | int32_t yHueDelta32 = ((int32_t)cos16( ms * (27/1) ) * (350 / kMatrixWidth)); 1929 | int32_t xHueDelta32 = ((int32_t)cos16( ms * (39/1) ) * (310 / kMatrixHeight)); 1930 | DrawOneFrame( ms / 65536, yHueDelta32 / 32768, xHueDelta32 / 32768); 1931 | if( ms < 5000 ) { 1932 | FastLED.setBrightness( scale8( BRIGHTNESS, (ms * 256) / 5000)); 1933 | } else { 1934 | FastLED.setBrightness(BRIGHTNESS); 1935 | } 1936 | FastLED.show(); 1937 | } 1938 | 1939 | void DrawOneFrame( byte startHue8, int8_t yHueDelta8, int8_t xHueDelta8) 1940 | { 1941 | byte lineStartHue = startHue8; 1942 | for( byte y = 0; y < kMatrixHeight; y++) { 1943 | lineStartHue += yHueDelta8; 1944 | byte pixelHue = lineStartHue; 1945 | for( byte x = 0; x < kMatrixWidth; x++) { 1946 | pixelHue += xHueDelta8; 1947 | leds[ XY(x, y)] = CHSV( pixelHue, 255, 255); 1948 | } 1949 | } 1950 | } 1951 | 1952 | ///////////////////////////////////////////////// 1953 | ///////////////////////////////////////////////// 1954 | //Put in black and white for newborn baby mode 1955 | 1956 | void newborn_mode() { 1957 | SetupBlackAndWhiteStripedPalette(); 1958 | } 1959 | 1960 | 1961 | ///////////////////////////////////////////////// 1962 | ///////////////////////////////////////////////// 1963 | //Fireplace visualizer 1964 | 1965 | void Fireplace () { 1966 | 1967 | random16_add_entropy( random() ); // We chew a lot of entropy 1968 | 1969 | static unsigned int spark[kMatrixHeight]; // base heat 1970 | CRGB stack[kMatrixHeight][kMatrixWidth]; // stacks that are cooler 1971 | 1972 | // 1. Generate sparks to re-heat 1973 | for( int i = 0; i < kMatrixHeight; i++) { 1974 | if (spark[i] < HOT ) { 1975 | int base = HOT * 2; 1976 | spark[i] = random16( base, MAXHOT ); 1977 | } 1978 | } 1979 | 1980 | // 2. Cool all the sparks 1981 | for( int i = 0; i < kMatrixHeight; i++) { 1982 | spark[i] = qsub8( spark[i], random8(0, COOLING) ); 1983 | } 1984 | 1985 | // 3. Build the stack 1986 | /* This works on the idea that pixels are "cooler" 1987 | as they get further from the spark at the bottom */ 1988 | for( int i = 0; i < kMatrixHeight; i++) { 1989 | unsigned int heat = constrain(spark[i], HOT, MAXHOT); 1990 | for( int j = kMatrixWidth-1; j >= 0; j--) { 1991 | /* Calculate the color on the palette from how hot this 1992 | pixel is */ 1993 | byte index = constrain(heat, 0, HOT); 1994 | stack[i][j] = ColorFromPalette( gPal, index ); 1995 | 1996 | /* The next higher pixel will be "cooler", so calculate 1997 | the drop */ 1998 | unsigned int drop = random8(0,HOT); 1999 | if (drop > heat) heat = 0; // avoid wrap-arounds from going "negative" 2000 | else heat -= drop; 2001 | 2002 | heat = constrain(heat, 0, MAXHOT); 2003 | } 2004 | } 2005 | 2006 | // 4. map stacks to led array 2007 | for( int i = 0; i < kMatrixHeight; i++) { 2008 | for( int j = 0; j < kMatrixWidth; j++) { 2009 | leds[ XY(j, i) ] = stack[i][j]; 2010 | } 2011 | } 2012 | FastLED.show(); 2013 | FastLED.delay(FPS_DELAY); 2014 | } 2015 | 2016 | //////////////////////////////////////////////////// 2017 | //FastLED Matrix Code Pattern 2018 | 2019 | void matrix_code() { 2020 | EVERY_N_MILLIS(75) // falling speed 2021 | { 2022 | // move code downward 2023 | // start with lowest row to allow proper overlapping on each column 2024 | for (int8_t row=kMatrixHeight-1; row>=0; row--) 2025 | { 2026 | for (int8_t col=0; col 2 | #include 3 | 4 | /** BASIC CONFIGURATION **/ 5 | #define BRIGHTNESS 160 6 | #define FRAMES_PER_SECOND 120 7 | 8 | //The pin that controls the LEDs 9 | #define LED_PIN 2 10 | //The pin that we read sensor values form 11 | #define MIC_PIN A0 12 | #define switchPin 5 13 | 14 | uint8_t led_volts = 5; 15 | uint32_t max_milliamps = 2400; 16 | 17 | int newborn = 0; //indicates if in newborn mode, so color palette can be black and white 18 | 19 | //////////////////////////////////////////////////////////////////////////////// 20 | ////////////////MATRIX PATTERN SETUP 21 | 22 | const uint8_t kMatrixWidth = 16; 23 | const uint8_t kMatrixHeight = 16; 24 | const bool kMatrixSerpentineLayout = true; 25 | 26 | //The amount of LEDs in the setup 27 | #define NUM_LEDS (kMatrixWidth * kMatrixHeight) 28 | #define NUM_LEDS_HALF (NUM_LEDS / 2) 29 | #define NUM_LEDS_QUARTER (NUM_LEDS / 4) 30 | #define MAX_DIMENSION ((kMatrixWidth>kMatrixHeight) ? kMatrixWidth : kMatrixHeight) 31 | 32 | 33 | // The 16 bit version of our coordinates 34 | static uint16_t x; 35 | static uint16_t y; 36 | static uint16_t z; 37 | 38 | // We're using the x/y dimensions to map to the x/y pixels on the matrix. We'll 39 | // use the z-axis for "time". speed determines how fast time moves forward. Try 40 | // 1 for a very slow moving effect, or 60 for something that ends up looking like 41 | // water. 42 | uint16_t speed = 6; // speed is set dynamically once we've started up 43 | 44 | // Scale determines how far apart the pixels in our noise matrix are. Try 45 | // changing these values around to see how it affects the motion of the display. The 46 | // higher the value of scale, the more "zoomed out" the noise iwll be. A value 47 | // of 1 will be so zoomed in, you'll mostly see solid colors. 48 | uint16_t scale = 30; // scale is set dynamically once we've started up 49 | 50 | // This is the array that we keep our computed noise values in 51 | uint8_t noise[MAX_DIMENSION][MAX_DIMENSION]; 52 | 53 | 54 | CRGBPalette16 currentPalette( PartyColors_p ); 55 | uint8_t colorLoop = 1; 56 | 57 | // x,y, & time values 58 | uint32_t v_time,hue_time,hxy; 59 | 60 | // how many octaves to use for the brightness and hue functions 61 | uint8_t octaves=1; 62 | uint8_t hue_octaves=3; 63 | 64 | // the 'distance' between x/y points for the hue noise 65 | int hue_scale=1; 66 | 67 | // how fast we move through time & hue noise 68 | int time_speed=100; 69 | int hue_speed=10; 70 | 71 | // adjust these values to move along the x or y axis between frames 72 | int x_speed=331; 73 | int y_speed=1111; 74 | 75 | // the 'distance' between points on the x and y axis 76 | int xscale=57771; 77 | int yscale=57771; 78 | 79 | 80 | //////////////////////////////////////////////////////////////////////////////// 81 | ////////////////VISUALIZER SETUP 82 | 83 | //Confirmed microphone low value, and max value 84 | #define MIC_LOW 380.0 85 | #define MIC_HIGH 460.0 86 | /** Other macros */ 87 | //How many previous sensor values effects the operating average? 88 | #define AVGLEN 5 89 | //How many previous sensor values decides if we are on a peak/HIGH (e.g. in a song) 90 | #define LONG_SECTOR 20 91 | 92 | //Mneumonics 93 | #define HIGH 3 94 | #define NORMAL 2 95 | 96 | //How long do we keep the "current average" sound, before restarting the measuring 97 | #define MSECS 30 * 1000 98 | #define CYCLES MSECS / DELAY 99 | 100 | /*Sometimes readings are wrong or strange. How much is a reading allowed 101 | to deviate from the average to not be discarded? **/ 102 | #define DEV_THRESH 0.8 103 | 104 | //Arduino loop delay 105 | #define DELAY 1 106 | 107 | float fscale( float originalMin, float originalMax, float newBegin, float newEnd, float inputValue, float curve); 108 | void insert(int val, int *avgs, int len); 109 | int compute_average(int *avgs, int len); 110 | void visualize_music(); 111 | void led_mode2(); 112 | void led_mode3(); 113 | void led_mode4(); 114 | void led_mode5(); 115 | void led_off(); 116 | int oldMode = 0; // assume switch closed because of pull-down resistor 117 | const unsigned long debounceTime = 1000; // milliseconds 118 | 119 | //How many LEDs to we display 120 | int height = NUM_LEDS; 121 | 122 | /*Not really used yet. Thought to be able to switch between sound reactive 123 | mode, and general gradient pulsing/static color*/ 124 | int mode = 0; 125 | 126 | //Showing different colors based on the mode. 127 | int songmode = NORMAL; 128 | 129 | //Average sound measurement the last CYCLES 130 | unsigned long song_avg; 131 | 132 | //The amount of iterations since the song_avg was reset 133 | int iter = 0; 134 | 135 | //The speed the LEDs fade to black if not relit 136 | float fade_scale = 1.2; 137 | 138 | //Led array 139 | CRGB leds[NUM_LEDS]; 140 | 141 | /*Short sound avg used to "normalize" the input values. 142 | We use the short average instead of using the sensor input directly */ 143 | int avgs[AVGLEN] = {-1}; 144 | 145 | //Longer sound avg 146 | int long_avg[LONG_SECTOR] = {-1}; 147 | 148 | //Keeping track how often, and how long times we hit a certain mode 149 | struct time_keeping { 150 | unsigned long times_start; 151 | short times; 152 | }; 153 | 154 | //How much to increment or decrement each color every cycle 155 | struct color { 156 | int r; 157 | int g; 158 | int b; 159 | }; 160 | 161 | struct time_keeping high; 162 | struct color Color; 163 | 164 | //heigh_and_condition variables; 165 | int sensor_value, mapped, avg, longavg; 166 | 167 | //peak dot parameters 168 | byte 169 | peak = 0, // Used for falling dot 170 | dotCount = 0; // Frame counter for delaying dot-falling speed 171 | #define PEAK_FALL 1 // Rate of peak falling dot 172 | #define PEAK_FALL_split 0 // Rate of peak falling dot 173 | 174 | //Vu7 Parameters 175 | #define NSAMPLES 64 176 | unsigned int samplearray[NSAMPLES]; 177 | unsigned long samplesum = 0; 178 | unsigned int sampleavg = 0; 179 | int samplecount = 0; 180 | unsigned int sample = 0; 181 | unsigned long oldtime = 0; 182 | unsigned long newtime = 0; 183 | 184 | //vu ripple 185 | uint8_t colour; 186 | uint8_t myfade = 255; // Starting brightness. 187 | #define maxsteps 24 // Case statement wouldn't allow a variable. 188 | int peakspersec = 0; 189 | int peakcount = 0; 190 | uint8_t bgcol = 0; 191 | int thisdelay = 20; 192 | int color; 193 | int center = 0; 194 | int center_2 = 0; 195 | int step = -1; 196 | float fadeRate = 0.80; 197 | int diff; 198 | int width=45; 199 | 200 | //center burst FHT parameters 201 | CRGBPalette16 targetPalette; 202 | TBlendType currentBlending; // NOBLEND or LINEARBLEND 203 | uint8_t maxChanges = 48; 204 | 205 | 206 | 207 | // FOR SYLON ETC 208 | uint8_t thisbeat = 23; 209 | uint8_t thatbeat = 28; 210 | uint8_t thisfade = 2; // How quickly does it fade? Lower = slower fade rate. 211 | uint8_t thissat = 255; // The saturation, where 255 = brilliant colours. 212 | uint8_t thisbri = 255; 213 | int myhue = 0; 214 | 215 | //FOR JUGGLE 216 | uint8_t numdots = 4; // Number of dots in use. 217 | uint8_t faderate = 2; // How long should the trails be. Very low value = longer trails. 218 | uint8_t hueinc = 16; // Incremental change in hue between each dot. 219 | uint8_t thishue = 0; // Starting hue. 220 | uint8_t curhue = 0; 221 | uint8_t thisbright = 255; // How bright should the LED/display be. 222 | uint8_t basebeat = 5; 223 | uint8_t max_bright = 255; 224 | 225 | // Twinkle 226 | float redStates[NUM_LEDS]; 227 | float blueStates[NUM_LEDS]; 228 | float greenStates[NUM_LEDS]; 229 | float Fade = 0.96; 230 | //unsigned int sample; 231 | 232 | ////For Fire 233 | //#define SPARKING 50 234 | //#define COOLING 55 235 | //bool gReverseDirection = false; 236 | //#define FRAMES_PER_SECOND 60 237 | 238 | //For Fireplace 239 | CRGBPalette16 gPal; 240 | #define FPS 48 241 | #define FPS_DELAY 1000/FPS 242 | #define COOLING 20 243 | #define HOT 100 244 | #define MAXHOT HOT*kMatrixHeight 245 | 246 | 247 | uint8_t gHue = 0; // rotating "base color" used by many of the patterns 248 | 249 | 250 | 251 | ///Cine-lights fireplace / torch setup 252 | ///not working now -- go back and fix later 253 | 254 | //uint16_t cycle_wait = 1; // 0..255 255 | // 256 | //byte flame_min = 100; // 0..255 257 | //byte flame_max = 220; // 0..255 258 | // 259 | //byte random_spark_probability = 2; // 0..100 260 | //byte spark_min = 200; // 0..255 261 | //byte spark_max = 255; // 0..255 262 | // 263 | //byte spark_tfr = 40; // 0..256 how much energy is transferred up for a spark per cycle 264 | //uint16_t spark_cap = 200; // 0..255: spark cells: how much energy is retained from previous cycle 265 | // 266 | //uint16_t up_rad = 40; // up radiation 267 | //uint16_t side_rad = 35; // sidewards radiation 268 | //uint16_t heat_cap = 0; // 0..255: passive cells: how much energy is retained from previous cycle 269 | // 270 | //byte red_bg = 0; 271 | //byte green_bg = 0; 272 | //byte blue_bg = 0; 273 | //byte red_bias = 10; 274 | //byte green_bias = 0; 275 | //byte blue_bias = 0; 276 | //int red_energy = 180; 277 | //int green_energy = 20; // 145; 278 | //int blue_energy = 0; 279 | //byte upside_down = 0; // if set, flame (or rather: drop) animation is upside down. Text remains as-is 280 | // 281 | //#define ledsPerLevel kMatrixWidth 282 | //#define levels kMatrixHeight 283 | // 284 | //byte currentEnergy[NUM_LEDS]; // current energy level 285 | //byte nextEnergy[NUM_LEDS]; // next energy level 286 | //byte energyMode[NUM_LEDS]; // mode how energy is calculated for this point 287 | // 288 | //enum { 289 | // torch_passive = 0, // just environment, glow from nearby radiation 290 | // torch_nop = 1, // no processing 291 | // torch_spark = 2, // slowly looses energy, moves up 292 | // torch_spark_temp = 3, // a spark still getting energy from the level below 293 | //}; 294 | 295 | 296 | //soundmems setup 297 | #define qsuba(x, b) ((x>b)?x-b:0) // Analog Unsigned subtraction macro. if result <0, then => 0 298 | int wavebright = 20; 299 | 300 | 301 | ///////Setup Function run when turned on 302 | 303 | void setup() { 304 | analogReference(EXTERNAL); // Connect 3.3V to AREF pin for any microphones using 3.3V 305 | 306 | Serial.begin(9600); 307 | pinMode (switchPin, INPUT); 308 | //Set all lights to make sure all are working as expected 309 | FastLED.addLeds(leds, NUM_LEDS); 310 | set_max_power_in_volts_and_milliamps (led_volts, max_milliamps); 311 | 312 | for (int i = 0; i < NUM_LEDS; i++) 313 | leds[i] = CRGB(70, 70, 70); 314 | FastLED.show(); 315 | delay(1000); 316 | 317 | //bootstrap average with some low values 318 | for (int i = 0; i < AVGLEN; i++) { 319 | insert(250, avgs, AVGLEN); 320 | } 321 | 322 | //Initial values 323 | high.times = 0; 324 | high.times_start = millis(); 325 | Color.r = 0; 326 | Color.g = 0; 327 | Color.b = 1; 328 | 329 | // Initialize our coordinates to some random values 330 | x = random16(); 331 | y = random16(); 332 | z = random16(); 333 | 334 | //pallette for fireplace 335 | gPal = HeatColors_p; 336 | 337 | 338 | 339 | } 340 | 341 | // Lists of patterns to cycle through. Each is defined as a separate function below. 342 | typedef void (*SimplePatternList[])(); 343 | SimplePatternList gPatterns = { blobby_flow, blobby_flow, blobby_flow, XYmatrix, rainbow, rainbowWithGlitter, confetti, blobby_flow_gaps, blobby_flow, blobby_flow, blobby_flow, blobby_flow, sinelon, juggle, bpm, matrix_code, blobby_flow }; //non-reactive patterns 344 | SimplePatternList musicPatterns = { visualize_music_4, visualize_music_2, center_burst_matrix, center_burst_FHT, vu10, center_burst_VU, blur_and_beat, visualize_music_4, visualize_music_2, center_burst_FHT, visualize_music_3, blur_and_spark, center_burst_matrix, vu7, center_burst_quad_pulse}; //music-reactive patterns 345 | 346 | 347 | 348 | uint8_t gCurrentPatternNumber = 0; // Index number of which pattern is current 349 | uint8_t musicCurrentPatternNumber = 0; // Index number of which pattern is current 350 | 351 | 352 | void loop () 353 | { 354 | // see if switch is open or closed 355 | int switchState = digitalRead (switchPin); 356 | 357 | // has it changed since last time? 358 | if (switchState == 0) 359 | { 360 | delay(300); 361 | if (oldMode == 4) 362 | { 363 | oldMode = 0; 364 | // Serial.print("oldMode is "); 365 | // Serial.println(oldMode); 366 | 367 | } // end if switchState is LOW 368 | else { 369 | oldMode++; 370 | if (oldMode == 1) 371 | { newborn = 1;} 372 | else newborn = 0; 373 | // Serial.print("oldMode is "); 374 | // Serial.println(oldMode); 375 | 376 | } 377 | } // end of state change 378 | 379 | switch(oldMode) { 380 | case 0: 381 | rotate_all_patterns(); 382 | break; 383 | 384 | case 1: 385 | rotate_music_patterns(); 386 | break; 387 | 388 | case 2: 389 | Fireplace(); 390 | //matrix_code(); 391 | //center_burst_quad_pulse(); 392 | //matrix_sinelon(); 393 | break; 394 | 395 | case 3: 396 | matrix_code(); 397 | //Fireplace(); 398 | //matrix_sinelon(); 399 | break; 400 | 401 | case 4: 402 | nightlight(); 403 | //all2(); 404 | break; 405 | 406 | // case 5: 407 | // center_burst_FHT(); 408 | // break; 409 | // 410 | // case 6: 411 | // vu10(); 412 | // break; 413 | // 414 | // case 7: 415 | // visualize_music_4(); 416 | // break; 417 | // 418 | // case 8: 419 | // led_off(); 420 | // break; 421 | // 422 | // case 9: 423 | // rotate_all_patterns(); 424 | // break; 425 | // 426 | // 427 | default: 428 | break; 429 | } 430 | delay(DELAY); // delay in between reads for stability 431 | } 432 | 433 | 434 | ////////////////////////////////////////////// 435 | //All red nightlight mode 436 | 437 | void nightlight() { 438 | Serial.println("running led_mode3"); 439 | 440 | for (int i =0; i < NUM_LEDS; i++) 441 | leds[i] = CHSV (0, 250, 200); 442 | 443 | 444 | FastLED.show(); 445 | delay(5); 446 | } 447 | 448 | 449 | //void led_mode3() { 450 | // Serial.println("running led_mode3"); 451 | // 452 | // for (int i =0; i < NUM_LEDS; i++) 453 | // leds[i] = CRGB(0, 240, 0); 454 | // 455 | // 456 | //FastLED.show(); 457 | //delay(5); 458 | //} 459 | // 460 | //void led_mode4() { 461 | // 462 | // Serial.println("running led_mode4"); 463 | // 464 | // for (int i =0; i < NUM_LEDS; i++) 465 | // leds[i] = CRGB(0, 0, 240); 466 | // 467 | // 468 | //FastLED.show(); 469 | //delay(5); 470 | //} 471 | // 472 | //void led_mode5() { 473 | // Serial.println("running led_mode5"); 474 | // 475 | // for (int i =0; i < NUM_LEDS; i++) 476 | // leds[i] = CRGB(240, 0, 0); 477 | // 478 | // 479 | //FastLED.show(); 480 | //delay(5); 481 | //} 482 | // 483 | 484 | void led_off() { 485 | Serial.println("turning off LEDs"); 486 | 487 | for (int i =0; i < NUM_LEDS; i++) 488 | leds[i] = CRGB(0, 0, 0); 489 | 490 | 491 | FastLED.show(); 492 | delay(5); 493 | } 494 | 495 | 496 | 497 | /////////////////////////////////////////////// 498 | //Begin Music Reactive patterns and functions 499 | 500 | void rotate_music_patterns() { 501 | 502 | musicPatterns[musicCurrentPatternNumber](); 503 | 504 | // send the 'leds' array out to the actual LED strip 505 | FastLED.show(); 506 | // insert a delay to keep the framerate modest 507 | FastLED.delay(1000/FRAMES_PER_SECOND); 508 | 509 | // do some periodic updates 510 | EVERY_N_MILLISECONDS( 20 ) { gHue++; } // slowly cycle the "base color" through the rainbow 511 | EVERY_N_SECONDS( 15 ) { nextMusicPattern(); } // change patterns periodically 512 | 513 | } 514 | 515 | #define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0])) 516 | 517 | void nextMusicPattern() { 518 | 519 | reset_variables(); 520 | // add one to the current pattern number, and wrap around at the end 521 | musicCurrentPatternNumber = (musicCurrentPatternNumber + 1) % ARRAY_SIZE( musicPatterns); 522 | } 523 | 524 | 525 | /**Funtion to check if the lamp should either enter a HIGH mode, 526 | or revert to NORMAL if already in HIGH. If the sensors report values 527 | that are higher than 1.1 times the average values, and this has happened 528 | more than 30 times the last few milliseconds, it will enter HIGH mode. 529 | TODO: Not very well written, remove hardcoded values, and make it more 530 | reusable and configurable. */ 531 | void check_high(int avg) { 532 | if (avg > (song_avg/iter * 1.1)) { 533 | if (high.times != 0) { 534 | if (millis() - high.times_start > 200.0) { 535 | high.times = 0; 536 | songmode = NORMAL; 537 | } else { 538 | high.times_start = millis(); 539 | high.times++; 540 | } 541 | } else { 542 | high.times++; 543 | high.times_start = millis(); 544 | 545 | } 546 | } 547 | if (high.times > 30 && millis() - high.times_start < 50.0) 548 | songmode = HIGH; 549 | else if (millis() - high.times_start > 200) { 550 | high.times = 0; 551 | songmode = NORMAL; 552 | } 553 | } 554 | 555 | void height_and_condition () { 556 | 557 | //Actual sensor value 558 | sensor_value = analogRead(MIC_PIN); 559 | 560 | //If 0, discard immediately. Probably not right and save CPU. 561 | if (sensor_value == 0) 562 | return; 563 | 564 | //Discard readings that deviates too much from the past avg. 565 | mapped = (float)fscale(MIC_LOW, MIC_HIGH, MIC_LOW, (float)MIC_HIGH, (float)sensor_value, 2.0); 566 | avg = compute_average(avgs, AVGLEN); 567 | 568 | if (((avg - mapped) > avg*DEV_THRESH)) //|| ((avg - mapped) < -avg*DEV_THRESH)) 569 | return; 570 | 571 | //Insert new avg. values 572 | insert(mapped, avgs, AVGLEN); 573 | insert(avg, long_avg, LONG_SECTOR); 574 | 575 | //Compute the "song average" sensor value 576 | song_avg += avg; 577 | iter++; 578 | if (iter > CYCLES) { 579 | song_avg = song_avg / iter; 580 | iter = 1; 581 | } 582 | 583 | longavg = compute_average(long_avg, LONG_SECTOR); 584 | 585 | //Check if we enter HIGH mode 586 | check_high(longavg); 587 | 588 | if (songmode == HIGH) { 589 | fade_scale = 3; 590 | Color.r = 5; 591 | Color.g = 3; 592 | Color.b = -1; 593 | } 594 | else if (songmode == NORMAL) { 595 | fade_scale = 2; 596 | Color.r = -1; 597 | Color.b = 2; 598 | Color.g = 1; 599 | } 600 | 601 | //Decides how many of the LEDs will be lit 602 | height = fscale(MIC_LOW, MIC_HIGH, 0.0, (float)NUM_LEDS, (float)avg, -1); 603 | //height_2 = fscale(MIC_LOW, MIC_HIGH, 0.0, (float)NUM_LEDS_2, (float)avg, -1); 604 | } 605 | 606 | 607 | 608 | 609 | //void visualize_music() { 610 | // 611 | // height_and_condition(); 612 | // 613 | // /*Set the different leds. Control for too high and too low values. 614 | // Fun thing to try: Dont account for overflow in one direction, 615 | // some interesting light effects appear! */ 616 | // for (int i = 0; i < NUM_LEDS; i++) 617 | // //The leds we want to show 618 | // if (i < height) { 619 | // if (leds[i].r + Color.r > 255) 620 | // leds[i].r = 255; 621 | // else if (leds[i].r + Color.r < 0) 622 | // leds[i].r = 0; 623 | // else 624 | // leds[i].r = leds[i].r + Color.r; 625 | // 626 | // if (leds[i].g + Color.g > 255) 627 | // leds[i].g = 255; 628 | // else if (leds[i].g + Color.g < 0) 629 | // leds[i].g = 0; 630 | // else 631 | // leds[i].g = leds[i].g + Color.g; 632 | // 633 | // if (leds[i].b + Color.b > 255) 634 | // leds[i].b = 255; 635 | // else if (leds[i].b + Color.b < 0) 636 | // leds[i].b = 0; 637 | // else 638 | // leds[i].b = leds[i].b + Color.b; 639 | // 640 | // //All the other LEDs begin their fading journey to eventual total darkness 641 | // } else { 642 | // leds[i] = CRGB(leds[i].r/fade_scale, leds[i].g/fade_scale, leds[i].b/fade_scale); 643 | // } 644 | // 645 | // //keep peak at top 646 | // if(height > peak) peak = height; // Keep 'peak' dot at top 647 | // if(peak > 0 && peak < NUM_LEDS) leds[peak] = CHSV(200, 200, 200); // set peak dot 648 | // FastLED.show(); 649 | // 650 | // if(++dotCount >= PEAK_FALL) { //fall rate 651 | // 652 | // if(peak > 0) peak--; 653 | // dotCount = 0; 654 | // } 655 | //} 656 | 657 | 658 | 659 | 660 | ///////////////////////////////////////////////////////////////////////////////////// 661 | //Center out spread visualizer 662 | 663 | void visualize_music_2() { 664 | 665 | height_and_condition(); 666 | height = height / 2; 667 | 668 | /*Set the different leds. Control for too high and too low values. 669 | Fun thing to try: Dont account for overflow in one direction, 670 | some interesting light effects appear! */ 671 | for (int i = 0; i < NUM_LEDS_HALF; i++) 672 | //The leds we want to show 673 | if (i < height) { 674 | if (leds[NUM_LEDS_HALF-i-1].r + Color.r > 255) { 675 | leds[NUM_LEDS_HALF-i-1].r = 255; 676 | leds[NUM_LEDS_HALF+i].r = 255; 677 | } 678 | else if (leds[NUM_LEDS_HALF-i-1].r + Color.r < 0) { 679 | leds[NUM_LEDS_HALF-i-1].r = 0; 680 | leds[NUM_LEDS_HALF+i].r = 0; 681 | } 682 | else { 683 | leds[NUM_LEDS_HALF-i-1].r = leds[NUM_LEDS_HALF-i-1].r + Color.r; 684 | leds[NUM_LEDS_HALF+i].r = leds[NUM_LEDS_HALF+i].r + Color.r; 685 | } 686 | 687 | if (leds[NUM_LEDS_HALF-i-1].g + Color.g > 255) { 688 | leds[NUM_LEDS_HALF-i-1].g = 255; 689 | leds[NUM_LEDS_HALF+i].g = 255; 690 | } 691 | else if (leds[NUM_LEDS_HALF-i-1].g + Color.g < 0) { 692 | leds[NUM_LEDS_HALF-i-1].g = 0; 693 | leds[NUM_LEDS_HALF+i].g = 0; 694 | } 695 | else { 696 | leds[NUM_LEDS_HALF-i-1].g = leds[NUM_LEDS_HALF-i-1].g + Color.g; 697 | leds[NUM_LEDS_HALF+i].g = leds[NUM_LEDS_HALF+i].g + Color.g; 698 | } 699 | 700 | 701 | if (leds[NUM_LEDS_HALF-i-1].b + Color.b > 255) { 702 | leds[NUM_LEDS_HALF-i-1].b = 255; 703 | leds[NUM_LEDS_HALF+i].b = 255; 704 | } 705 | else if (leds[NUM_LEDS_HALF-i-1].b + Color.b < 0) { 706 | leds[NUM_LEDS_HALF-i-1].b = 0; 707 | leds[NUM_LEDS_HALF+i].b = 0; 708 | } 709 | else { 710 | leds[NUM_LEDS_HALF-i-1].b = leds[NUM_LEDS_HALF-i-1].b + Color.b; 711 | leds[NUM_LEDS_HALF+i].b = leds[NUM_LEDS_HALF+i].b + Color.b; 712 | } 713 | 714 | //All the other LEDs begin their fading journey to eventual total darkness 715 | } else { 716 | leds[NUM_LEDS_HALF-i-1] = CRGB(leds[NUM_LEDS_HALF-i-1].r/fade_scale, leds[NUM_LEDS_HALF-i-1].g/fade_scale, leds[NUM_LEDS_HALF-i-1].b/fade_scale); 717 | leds[NUM_LEDS_HALF+i] = CRGB(leds[NUM_LEDS_HALF+i].r/fade_scale, leds[NUM_LEDS_HALF+i].g/fade_scale, leds[NUM_LEDS_HALF+i].b/fade_scale); 718 | 719 | } 720 | 721 | //keep peak at top for small LED array 722 | if(height > peak) peak = height; // Keep 'peak' dot at top 723 | if(peak > 0 && peak < NUM_LEDS_HALF) { 724 | leds[NUM_LEDS_HALF-peak] = CHSV(200, 200, 200); // set peak dot 725 | leds[NUM_LEDS_HALF+peak-1] = CHSV(200, 200, 200); // set peak dot 726 | } 727 | 728 | addGlitter(100); 729 | 730 | FastLED.show(); 731 | 732 | // Every few frames, make the peak pixel drop by 1: 733 | 734 | if(++dotCount >= PEAK_FALL_split) { //fall rate 735 | 736 | if(peak > 0) peak--; 737 | dotCount = 0; 738 | } 739 | 740 | } 741 | 742 | 743 | ///////////////////////////////////////////////////////////////////////////////////// 744 | //quadrasect spread out VU w/ falling dot 745 | 746 | void visualize_music_3() { 747 | 748 | height_and_condition(); 749 | height = height / 4; 750 | 751 | 752 | /*Set the different leds. Control for too high and too low values. 753 | Fun thing to try: Dont account for overflow in one direction, 754 | some interesting light effects appear! */ 755 | //Small LED Array 756 | for (int i = 0; i < NUM_LEDS_QUARTER; i++) 757 | //The leds we want to show 758 | if (i < height) { 759 | if (leds[i].r + Color.r > 255) { 760 | leds[i].r = 255; 761 | leds[NUM_LEDS_QUARTER+i].r = 255; 762 | leds[NUM_LEDS_HALF+i].r = 255; 763 | leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i].r = 255; 764 | } 765 | else if (leds[i].r + Color.r < 0) { 766 | leds[i].r = 0; 767 | leds[NUM_LEDS_QUARTER+i].r = 0; 768 | leds[NUM_LEDS_HALF+i].r = 0; 769 | leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i].r = 0; 770 | } 771 | else { 772 | leds[i].r = leds[i].r + Color.r; 773 | leds[NUM_LEDS_QUARTER+i].r = leds[NUM_LEDS_QUARTER+i].r + Color.r; 774 | leds[NUM_LEDS_HALF+i].r = leds[NUM_LEDS_HALF+i].r + Color.r; 775 | leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i].r = leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i].r + Color.r; 776 | } 777 | 778 | if (leds[i].g + Color.g > 255) { 779 | leds[i].g = 255; 780 | leds[NUM_LEDS_QUARTER+i].g = 255; 781 | leds[NUM_LEDS_HALF+i].g = 255; 782 | leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i].g = 255; 783 | } 784 | else if (leds[i].g + Color.g < 0) { 785 | leds[i].g = 0; 786 | leds[NUM_LEDS_QUARTER+i].g = 0; 787 | leds[NUM_LEDS_HALF+i].g = 0; 788 | leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i].g = 0; 789 | } 790 | else { 791 | leds[i].g = leds[i].g + Color.g; 792 | leds[NUM_LEDS_QUARTER+i].g = leds[NUM_LEDS_QUARTER+i].g + Color.g; 793 | leds[NUM_LEDS_HALF+i].g = leds[NUM_LEDS_HALF+i].g + Color.g; 794 | leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i].g = leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i].g + Color.g; 795 | } 796 | 797 | 798 | if (leds[i].b + Color.b > 255) { 799 | leds[i].b = 255; 800 | leds[NUM_LEDS_QUARTER+i].b = 255; 801 | leds[NUM_LEDS_HALF+i].b = 255; 802 | leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i].b = 255; 803 | } 804 | else if (leds[i].b + Color.b < 0) { 805 | leds[i].b = 0; 806 | leds[NUM_LEDS_QUARTER+i].b = 0; 807 | leds[NUM_LEDS_HALF+i].b = 0; 808 | leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i].b = 0; 809 | } 810 | else { 811 | leds[i].b = leds[i].b + Color.b; 812 | leds[NUM_LEDS_QUARTER+i].b = leds[NUM_LEDS_QUARTER+i].b + Color.b; 813 | leds[NUM_LEDS_HALF+i].b = leds[NUM_LEDS_HALF+i].b + Color.b; 814 | leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i].b = leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i].b + Color.b; 815 | } 816 | 817 | //All the other LEDs begin their fading journey to eventual total darkness 818 | } else { 819 | leds[i] = CRGB(leds[i].r/fade_scale, leds[i].g/fade_scale, leds[i].b/fade_scale); 820 | leds[NUM_LEDS_QUARTER+i] = CRGB(leds[NUM_LEDS_QUARTER+i].r/fade_scale, leds[NUM_LEDS_QUARTER+i].g/fade_scale, leds[NUM_LEDS_QUARTER+i].b/fade_scale); 821 | leds[NUM_LEDS_HALF+i] = CRGB(leds[NUM_LEDS_HALF+i].r/fade_scale, leds[NUM_LEDS_HALF+i].g/fade_scale, leds[NUM_LEDS_HALF+i].b/fade_scale); 822 | leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i] = CRGB(leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i].r/fade_scale, leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i].g/fade_scale, leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+i].b/fade_scale); 823 | } 824 | 825 | //peak for small LED array 826 | //keep peak at top 827 | if(height > peak) peak = height; // Keep 'peak' dot at top 828 | if(peak > 0 && peak < NUM_LEDS_QUARTER) { 829 | leds[peak] = CHSV(200, 200, 200); // set peak dot 830 | leds[NUM_LEDS_QUARTER+peak] = CHSV(200, 200, 200); // set peak dot 831 | leds[NUM_LEDS_HALF+peak] = CHSV(200, 200, 200); 832 | leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+peak] = CHSV(200, 200, 200); 833 | } 834 | 835 | addGlitter(80); 836 | 837 | FastLED.show(); 838 | 839 | // Every few frames, make the peak pixel drop by 1: 840 | 841 | if(++dotCount >= PEAK_FALL_split) { //fall rate 842 | if(peak > 0) peak--; 843 | dotCount = 0; 844 | } 845 | 846 | } 847 | 848 | 849 | ///////////////////////////////////////////////////////////////////////////////////// 850 | //outside in spread visualizer 851 | 852 | void visualize_music_4() { 853 | 854 | height_and_condition(); 855 | height = height / 2; 856 | 857 | /*Set the different leds. Control for too high and too low values. 858 | Fun thing to try: Dont account for overflow in one direction, 859 | some interesting light effects appear! */ 860 | // Update Small LED array 861 | for (int i = 0; i < NUM_LEDS_HALF; i++) 862 | //The leds we want to show 863 | if (i < height) { 864 | if (leds[i].r + Color.r > 255) { 865 | leds[i].r = 255; 866 | leds[NUM_LEDS-1-i].r = 255; 867 | } 868 | else if (leds[i].r + Color.r < 0) { 869 | leds[i].r = 0; 870 | leds[NUM_LEDS-1-i].r = 0; 871 | } 872 | else { 873 | leds[i].r = leds[i].r + Color.r; 874 | leds[NUM_LEDS-1-i].r = leds[NUM_LEDS-1-i].r + Color.r; 875 | } 876 | 877 | if (leds[i].g + Color.g > 255) { 878 | leds[i].g = 255; 879 | leds[NUM_LEDS-1-i].g = 255; 880 | } 881 | else if (leds[i].g + Color.g < 0) { 882 | leds[i].g = 0; 883 | leds[NUM_LEDS-1-i].g = 0; 884 | } 885 | else { 886 | leds[i].g = leds[i].g + Color.g; 887 | leds[NUM_LEDS-1-i].g = leds[NUM_LEDS-1-i].g + Color.g; 888 | } 889 | 890 | 891 | if (leds[i].b + Color.b > 255) { 892 | leds[i].b = 255; 893 | leds[NUM_LEDS-1-i].b = 255; 894 | } 895 | else if (leds[i].b + Color.b < 0) { 896 | leds[i].b = 0; 897 | leds[NUM_LEDS-1-i].b = 0; 898 | } 899 | else { 900 | leds[i].b = leds[i].b + Color.b; 901 | leds[NUM_LEDS-1-i].b = leds[NUM_LEDS-1-i].b + Color.b; 902 | } 903 | 904 | //All the other LEDs begin their fading journey to eventual total darkness 905 | } else { 906 | leds[i] = CRGB(leds[i].r/fade_scale, leds[i].g/fade_scale, leds[i].b/fade_scale); 907 | leds[NUM_LEDS-1-i] = CRGB(leds[NUM_LEDS-1-i].r/fade_scale, leds[NUM_LEDS-1-i].g/fade_scale, leds[NUM_LEDS-1-i].b/fade_scale); 908 | 909 | } 910 | 911 | //keep peak at top for small LED array 912 | if(height > peak) peak = height; // Keep 'peak' dot at top 913 | if(peak > 0 && peak < NUM_LEDS_HALF) { 914 | leds[peak] = CHSV(gHue, 200, 200); // set peak dot 915 | leds[NUM_LEDS-1-peak] = CHSV(gHue, 200, 200); // set peak dot 916 | } 917 | 918 | addGlitter(80); 919 | FastLED.show(); 920 | 921 | // Every few frames, make the peak pixel drop by 1: 922 | 923 | if(++dotCount >= PEAK_FALL_split) { //fall rate 924 | 925 | if(peak > 0) peak--; 926 | dotCount = 0; 927 | } 928 | EVERY_N_MILLISECONDS(20) {gHue++;} 929 | 930 | } 931 | 932 | 933 | 934 | ///////////////////////////////////////////////////////////////////////////// 935 | //flash ripple and background pulse visualizer 936 | 937 | void vu7() { 938 | 939 | EVERY_N_MILLISECONDS(1000) { 940 | peakspersec = peakcount; // Count the peaks per second. This value will become the foreground hue. 941 | peakcount = 0; // Reset the counter every second. 942 | } 943 | 944 | //soundmems(); 945 | soundrip(); 946 | 947 | EVERY_N_MILLISECONDS(20) { 948 | ripple3(); 949 | } 950 | 951 | // show_at_max_brightness_for_power(); 952 | FastLED.show(); 953 | delay(3); 954 | } // loop() 955 | 956 | 957 | //void soundmems() { // Rolling average counter - means we don't have to go through an array each time. 958 | // newtime = millis(); 959 | // int tmp = analogRead(MIC_PIN); 960 | // sample = abs(tmp); 961 | // 962 | // //int potin = map(analogRead(POT_PIN), 0, 1023, 0, 90); 963 | // 964 | // samplesum = samplesum + sample - samplearray[samplecount]; // Add the new sample and remove the oldest sample in the array 965 | // sampleavg = samplesum / NSAMPLES; // Get an average 966 | // samplearray[samplecount] = sample; // Update oldest sample in the array with new sample 967 | // samplecount = (samplecount + 1) % NSAMPLES; // Update the counter for the array 968 | // 969 | // //if (newtime > (oldtime + 200)) digitalWrite(13, LOW); // Turn the LED off 200ms after the last peak. 970 | // 971 | // if ((sample > (sampleavg + 30)) && (newtime > (oldtime + 50)) ) { // Check for a peak, which is 30 > the average, but wait at least 60ms for another. 972 | // //note: hardcoded 30 instead of potin in above line 973 | // step = -1; 974 | // peakcount++; 975 | // //digitalWrite(13, HIGH); 976 | // oldtime = newtime; 977 | // } 978 | //} // soundmems() 979 | 980 | void soundmems() { 981 | 982 | int tmp = analogRead(MIC_PIN) - 512; 983 | sample = abs(tmp); 984 | 985 | } // soundmems() 986 | 987 | 988 | void ripple3() { 989 | for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(bgcol, 255, sampleavg*2); // Set the background colour. 990 | 991 | switch (step) { 992 | 993 | case -1: // Initialize ripple variables. 994 | center = random(NUM_LEDS); 995 | colour = (peakspersec*10) % 255; // More peaks/s = higher the hue colour. 996 | step = 0; 997 | bgcol = bgcol+8; 998 | break; 999 | 1000 | case 0: 1001 | leds[center] = CHSV(colour, 255, 255); // Display the first pixel of the ripple. 1002 | step ++; 1003 | break; 1004 | 1005 | case maxsteps: // At the end of the ripples. 1006 | // step = -1; 1007 | break; 1008 | 1009 | default: // Middle of the ripples. 1010 | leds[(center + step + NUM_LEDS) % NUM_LEDS] += CHSV(colour, 255, myfade/step*2); // Simple wrap from Marc Miller. 1011 | leds[(center - step + NUM_LEDS) % NUM_LEDS] += CHSV(colour, 255, myfade/step*2); 1012 | step ++; // Next step. 1013 | break; 1014 | } // switch step 1015 | 1016 | } 1017 | 1018 | 1019 | ////////////////////////////////////////////////////////////////////////////////////////////////////////// 1020 | // Slow blending change of hue with VU meter dot over it, combine with vu10() to make work 1021 | 1022 | ///Need to figure out what is making, all lights go on periodically and fix 1023 | 1024 | void blur_and_beat() { 1025 | 1026 | height_and_condition(); 1027 | height = height / 4; 1028 | 1029 | for (int i = 0; i < NUM_LEDS; i++) 1030 | leds[i] = CRGB(leds[i].r/fade_scale, leds[i].g/fade_scale, leds[i].b/fade_scale); 1031 | 1032 | uint8_t blurAmount = dim8_raw( beatsin8(3,64, 192) ); // A sinewave at 3 Hz with values ranging from 64 to 192. 1033 | blur1d( leds, NUM_LEDS, blurAmount); // Apply some blurring to whatever's already on the strip, which will eventually go black. 1034 | 1035 | uint8_t i = beatsin8( 9, 0, NUM_LEDS-1); 1036 | uint8_t j = beatsin8( 7, 0, NUM_LEDS-1); 1037 | uint8_t k = beatsin8( 5, 0, NUM_LEDS-1); 1038 | 1039 | 1040 | // The color of each point shifts over time, each at a different speed. 1041 | uint16_t ms = millis(); 1042 | leds[(i+j)/2] = CHSV( ms / 29, 200, 255); 1043 | leds[(j+k)/2] = CHSV( ms / 41, 200, 255); 1044 | leds[(k+i)/2] = CHSV( ms / 73, 200, 255); 1045 | leds[(k+i+j)/3] = CHSV( ms / 53, 200, 255); 1046 | 1047 | 1048 | //VU Dot overlay on blur 1049 | if(height > peak) peak = height; // Keep 'peak' dot at top 1050 | if(peak > 2 && peak < NUM_LEDS_QUARTER) { 1051 | 1052 | for (int j = 0; j < 3; j++) { 1053 | leds[peak-j] = CHSV(200, 200, 200); // set peak dot 1054 | leds[NUM_LEDS_QUARTER+peak-j] = CHSV(200, 200, 200); // set peak dot 1055 | leds[NUM_LEDS_HALF+peak-j] = CHSV(200, 200, 200); 1056 | leds[NUM_LEDS_HALF+NUM_LEDS_QUARTER+peak-j] = CHSV(200, 200, 200); 1057 | } 1058 | } 1059 | 1060 | 1061 | FastLED.show(); 1062 | 1063 | if(++dotCount >= PEAK_FALL_split-5) { //fall rate 1064 | if(peak > 0) peak--; 1065 | dotCount = 0; 1066 | } 1067 | 1068 | 1069 | //delay(2); 1070 | } // loop() 1071 | 1072 | 1073 | 1074 | ////////////////////////////////////////////////////////////////////////////////////////////////////////// 1075 | // blur with ripple spark overlay 1076 | 1077 | void blur_and_spark() { 1078 | 1079 | height_and_condition(); 1080 | height = height / 4; 1081 | 1082 | EVERY_N_MILLISECONDS(1000) { 1083 | peakspersec = peakcount; // Count the peaks per second. This value will become the foreground hue. 1084 | peakcount = 0; // Reset the counter every second. 1085 | } 1086 | 1087 | for (int i = 0; i < NUM_LEDS; i++) 1088 | leds[i] = CRGB(leds[i].r/fade_scale, leds[i].g/fade_scale, leds[i].b/fade_scale); 1089 | 1090 | 1091 | uint8_t blurAmount = dim8_raw( beatsin8(3,64, 192) ); // A sinewave at 3 Hz with values ranging from 64 to 192. 1092 | blur1d( leds, NUM_LEDS, blurAmount); // Apply some blurring to whatever's already on the strip, which will eventually go black. 1093 | 1094 | uint8_t i = beatsin8( 9, 0, NUM_LEDS-1); 1095 | uint8_t j = beatsin8( 7, 0, NUM_LEDS-1); 1096 | uint8_t k = beatsin8( 5, 0, NUM_LEDS-1); 1097 | 1098 | // The color of each point shifts over time, each at a different speed. 1099 | uint16_t ms = millis(); 1100 | leds[(i+j)/2] = CHSV( ms / 29, 200, 255); 1101 | leds[(j+k)/2] = CHSV( ms / 41, 200, 255); 1102 | leds[(k+i)/2] = CHSV( ms / 73, 200, 255); 1103 | leds[(k+i+j)/3] = CHSV( ms / 53, 200, 255); 1104 | 1105 | 1106 | soundrip_2(); 1107 | 1108 | EVERY_N_MILLISECONDS(30) { 1109 | rippled_2(); 1110 | } 1111 | 1112 | 1113 | FastLED.show(); 1114 | 1115 | } // loop() 1116 | 1117 | 1118 | void soundrip_2() { // Rolling average counter - means we don't have to go through an array each time. 1119 | 1120 | newtime = millis(); 1121 | int tmp = analogRead(MIC_PIN); 1122 | sample = abs(tmp); 1123 | 1124 | //int potin = map(analogRead(POT_PIN), 0, 1023, 0, 60) + 20; 1125 | 1126 | samplesum = samplesum + sample - samplearray[samplecount]; // Add the new sample and remove the oldest sample in the array 1127 | sampleavg = samplesum / NSAMPLES; // Get an average 1128 | samplearray[samplecount] = sample; // Update oldest sample in the array with new sample 1129 | samplecount = (samplecount + 1) % NSAMPLES; // Update the counter for the array 1130 | 1131 | if (newtime > (oldtime + 200)) digitalWrite(13, LOW); // Turn the LED off 200ms after the last peak. 1132 | EVERY_N_MILLISECONDS(1000) { 1133 | uint8_t width_adj = random8(15); 1134 | width = 12 + (width_adj * 8); 1135 | } 1136 | 1137 | if ((sample > (sampleavg + width)) && (newtime > (oldtime + 30)) ) { // Check for a peak, which is 30 > the average, but wait at least 60ms for another. 1138 | step = -1; 1139 | peakcount++; 1140 | //digitalWrite(13, HIGH); 1141 | oldtime = newtime; 1142 | } 1143 | 1144 | } // soundmems() 1145 | 1146 | 1147 | 1148 | void rippled_2() { 1149 | 1150 | fadeToBlackBy(leds, NUM_LEDS, 44); // 8 bit, 1 = slow, 255 = fast 1151 | 1152 | switch (step) { 1153 | 1154 | case -1: // Initialize ripple variables. 1155 | center = random(NUM_LEDS); 1156 | colour = (peakspersec*10) % 255; // More peaks/s = higher the hue colour. 1157 | step = 0; 1158 | break; 1159 | 1160 | case 0: 1161 | leds[center] = CHSV(colour, 255, 255); // Display the first pixel of the ripple. 1162 | step ++; 1163 | break; 1164 | 1165 | case maxsteps: // At the end of the ripples. 1166 | // step = -1; 1167 | break; 1168 | 1169 | default: // Middle of the ripples. 1170 | leds[(center + step + NUM_LEDS) % NUM_LEDS] += CHSV(colour, 255, myfade/step*2); // Simple wrap from Marc Miller. 1171 | leds[(center - step + NUM_LEDS) % NUM_LEDS] += CHSV(colour, 255, myfade/step*2); 1172 | 1173 | step ++; // Next step. 1174 | break; 1175 | } // switch step 1176 | 1177 | } // ripple_2() 1178 | 1179 | 1180 | /////////////////////////////////////////////////////// 1181 | //Center Burst Visualizer 1182 | 1183 | void center_burst_FHT() { 1184 | 1185 | EVERY_N_MILLISECONDS(100) { // AWESOME palette blending capability. 1186 | 1187 | nblendPaletteTowardPalette(currentPalette, targetPalette, maxChanges); 1188 | } 1189 | 1190 | 1191 | EVERY_N_SECONDS(5) { // Change the palette every 5 seconds. 1192 | for (int i = 0; i < 16; i++) { 1193 | targetPalette[i] = CHSV(random8(), 255, 255); 1194 | } 1195 | } 1196 | 1197 | EVERY_N_MILLISECONDS(18) { 1198 | fadeToBlackBy(leds, NUM_LEDS, 4); // 8 bit, 1 = slow, 255 = fast 1199 | sndwave(); 1200 | soundmems(); 1201 | } 1202 | 1203 | FastLED.show(); 1204 | } 1205 | 1206 | void sndwave() { 1207 | 1208 | leds[NUM_LEDS/2] = ColorFromPalette(currentPalette, sample, sample*2, currentBlending); 1209 | 1210 | for (int i = NUM_LEDS - 1; i > NUM_LEDS/2; i--) { //move to the left 1211 | leds[i] = leds[i - 1]; 1212 | } 1213 | 1214 | for (int i = 0; i < NUM_LEDS/2; i++) { // move to the right 1215 | leds[i] = leds[i + 1]; 1216 | } 1217 | 1218 | } // sndwave() 1219 | 1220 | 1221 | 1222 | 1223 | /////////////////////////////////////////////////////// 1224 | 1225 | void center_burst_VU() { 1226 | 1227 | EVERY_N_MILLISECONDS(100) { // AWESOME palette blending capability. 1228 | 1229 | nblendPaletteTowardPalette(currentPalette, targetPalette, maxChanges); 1230 | } 1231 | 1232 | 1233 | EVERY_N_MILLISECONDS(25) { 1234 | fadeToBlackBy(leds, NUM_LEDS, 15); // 8 bit, 1 = slow, 255 = fast 1235 | sndwave(); 1236 | soundmems(); 1237 | } 1238 | 1239 | height_and_condition(); 1240 | height = height / 2; 1241 | 1242 | for (int i = 0; i < NUM_LEDS_HALF-48; i++) 1243 | //The leds we want to show 1244 | if (i < height) { 1245 | if (leds[i].r + Color.r > 255) { 1246 | leds[i].r = 255; 1247 | leds[NUM_LEDS-1-i].r = 255; 1248 | } 1249 | else if (leds[i].r + Color.r < 0) { 1250 | leds[i].r = 0; 1251 | leds[NUM_LEDS-1-i].r = 0; 1252 | } 1253 | else { 1254 | leds[i].r = leds[i].r + Color.r; 1255 | leds[NUM_LEDS-1-i].r = leds[NUM_LEDS-1-i].r + Color.r; 1256 | } 1257 | 1258 | if (leds[i].g + Color.g > 255) { 1259 | leds[i].g = 255; 1260 | leds[NUM_LEDS-1-i].g = 255; 1261 | } 1262 | else if (leds[i].g + Color.g < 0) { 1263 | leds[i].g = 0; 1264 | leds[NUM_LEDS-1-i].g = 0; 1265 | } 1266 | else { 1267 | leds[i].g = leds[i].g + Color.g; 1268 | leds[NUM_LEDS-1-i].g = leds[NUM_LEDS-1-i].g + Color.g; 1269 | } 1270 | 1271 | if (leds[i].b + Color.b > 255) { 1272 | leds[i].b = 255; 1273 | leds[NUM_LEDS-1-i].b = 255; 1274 | } 1275 | else if (leds[i].b + Color.b < 0) { 1276 | leds[i].b = 0; 1277 | leds[NUM_LEDS-1-i].b = 0; 1278 | } 1279 | else { 1280 | leds[i].b = leds[i].b + Color.b; 1281 | leds[NUM_LEDS-1-i].b = leds[NUM_LEDS-1-i].b + Color.b; 1282 | } 1283 | 1284 | //All the other LEDs begin their fading journey to eventual total darkness 1285 | } else { 1286 | leds[i] = CRGB(leds[i].r/fade_scale, leds[i].g/fade_scale, leds[i].b/fade_scale); 1287 | leds[NUM_LEDS-1-i] = CRGB(leds[NUM_LEDS-1-i].r/fade_scale, leds[NUM_LEDS-1-i].g/fade_scale, leds[NUM_LEDS-1-i].b/fade_scale); 1288 | 1289 | } 1290 | 1291 | //keep peak at top for small LED array 1292 | if(height > peak) peak = height; // Keep 'peak' dot at top 1293 | if(peak > 0 && peak < NUM_LEDS_HALF) { 1294 | leds[peak] = CHSV(gHue, 200, 200); // set peak dot 1295 | leds[NUM_LEDS-1-peak] = CHSV(gHue, 200, 200); // set peak dot 1296 | } 1297 | 1298 | EVERY_N_SECONDS(5) { // Change the palette every 5 seconds. 1299 | for (int i = 0; i < 16; i++) { 1300 | targetPalette[i] = CHSV(random8(), 255, 255); 1301 | } 1302 | } 1303 | 1304 | FastLED.show(); 1305 | 1306 | 1307 | if(++dotCount >= PEAK_FALL_split) { //fall rate 1308 | if(peak > 0) peak--; 1309 | dotCount = 0; 1310 | } 1311 | } 1312 | 1313 | /////////////////////////////////////////////////////// 1314 | //Center Burst and quad pulse overlay 1315 | 1316 | 1317 | void center_burst_quad_pulse() { 1318 | 1319 | 1320 | EVERY_N_MILLISECONDS(100) { // AWESOME palette blending capability. 1321 | 1322 | nblendPaletteTowardPalette(currentPalette, targetPalette, maxChanges); 1323 | } 1324 | 1325 | 1326 | EVERY_N_SECONDS(5) { // Change the palette every 5 seconds. 1327 | for (int i = 0; i < 16; i++) { 1328 | targetPalette[i] = CHSV(random8(), 255, 255); 1329 | } 1330 | } 1331 | 1332 | EVERY_N_MILLISECONDS(25) { 1333 | fadeToBlackBy(leds, NUM_LEDS, 10); // 8 bit, 1 = slow, 255 = fast 1334 | sndwave(); 1335 | soundmems(); 1336 | } 1337 | 1338 | height_and_condition(); 1339 | height = height / 2; 1340 | 1341 | 1342 | //keep peak at top for small LED array 1343 | if(height > peak) peak = height; // Keep 'peak' dot at top 1344 | if(peak > 2 && peak < NUM_LEDS_HALF) { 1345 | for (int j = 0; j < 3; j++) { 1346 | leds[peak-j] = CHSV(200, 200, 200); // set peak dot 1347 | leds[NUM_LEDS-1-peak+j] = CHSV(200, 200, 200); // set peak dot 1348 | } 1349 | } 1350 | 1351 | 1352 | FastLED.show(); 1353 | 1354 | // Every few frames, make the peak pixel drop by 1: 1355 | 1356 | if(++dotCount >= PEAK_FALL_split-4) { //fall rate 1357 | 1358 | if(peak > 0) peak--; 1359 | dotCount = 0; 1360 | } 1361 | 1362 | delay(2); 1363 | } 1364 | 1365 | 1366 | 1367 | /////////////////////////////////////////////////////////////////// 1368 | //whole matrix center burst 1369 | 1370 | void center_burst_matrix() { 1371 | 1372 | EVERY_N_MILLISECONDS(100) { // AWESOME palette blending capability. 1373 | 1374 | nblendPaletteTowardPalette(currentPalette, targetPalette, maxChanges); 1375 | } 1376 | 1377 | 1378 | EVERY_N_SECONDS(5) { // Change the palette every 5 seconds. 1379 | for (int i = 0; i < 16; i++) { 1380 | targetPalette[i] = CHSV(random8(), 255, 255); 1381 | } 1382 | } 1383 | 1384 | EVERY_N_MILLISECONDS(25) { 1385 | fadeToBlackBy(leds, NUM_LEDS, 50); // 8 bit, 1 = slow, 255 = fast 1386 | sndwave_matrix(); 1387 | soundmems(); 1388 | } 1389 | 1390 | addGlitter(60); 1391 | FastLED.show(); 1392 | } 1393 | 1394 | void sndwave_matrix() { 1395 | 1396 | for (int i = 0; i < kMatrixWidth; i++) { 1397 | 1398 | leds[XY(i, kMatrixHeight/2)] = ColorFromPalette(currentPalette, sample, sample*2, currentBlending); 1399 | 1400 | for(int j = kMatrixHeight - 1; j > kMatrixHeight/2; j--) { 1401 | leds[XY(i,j)] = leds[XY(i,j-1)]; //move to the left 1402 | } 1403 | 1404 | for(int j = 0 ; j < kMatrixHeight/2; j++) { 1405 | leds[XY(i,j)] = leds[XY(i,j+1)]; // move to the right; 1406 | } 1407 | } 1408 | 1409 | } // sndwave_matrix() 1410 | 1411 | /////////////////////////////////////////////////////////////////// 1412 | // Ripple with Black background and variable width 1413 | 1414 | 1415 | void vu10() { 1416 | 1417 | EVERY_N_MILLISECONDS(1000) { 1418 | peakspersec = peakcount; // Count the peaks per second. This value will become the foreground hue. 1419 | peakcount = 0; // Reset the counter every second. 1420 | } 1421 | 1422 | soundrip(); 1423 | 1424 | EVERY_N_MILLISECONDS(20) { 1425 | rippled(); 1426 | } 1427 | 1428 | FastLED.show(); 1429 | delay(3); 1430 | } // loop() 1431 | 1432 | 1433 | void soundrip() { // Rolling average counter - means we don't have to go through an array each time. 1434 | 1435 | newtime = millis(); 1436 | int tmp = analogRead(MIC_PIN); 1437 | sample = abs(tmp); 1438 | 1439 | //int potin = map(analogRead(POT_PIN), 0, 1023, 0, 60) + 20; 1440 | 1441 | samplesum = samplesum + sample - samplearray[samplecount]; // Add the new sample and remove the oldest sample in the array 1442 | sampleavg = samplesum / NSAMPLES; // Get an average 1443 | samplearray[samplecount] = sample; // Update oldest sample in the array with new sample 1444 | samplecount = (samplecount + 1) % NSAMPLES; // Update the counter for the array 1445 | 1446 | // if (newtime > (oldtime + 400)) digitalWrite(13, LOW); // Turn the LED off 400ms after the last peak. 1447 | 1448 | 1449 | 1450 | EVERY_N_MILLISECONDS(1000) { 1451 | uint8_t width_adj = random8(15); 1452 | width = 12 + (width_adj * 8); 1453 | } 1454 | if ((sample > (sampleavg + width)) && (newtime > (oldtime + 30)) ) { // Check for a peak, which is 30 > the average, but wait at least 60ms for another. 1455 | step = -1; 1456 | peakcount++; 1457 | oldtime = newtime; 1458 | } 1459 | 1460 | } // soundmems() 1461 | 1462 | 1463 | 1464 | void rippled() { 1465 | 1466 | fadeToBlackBy(leds, NUM_LEDS, 44); // 8 bit, 1 = slow, 255 = fast 1467 | 1468 | switch (step) { 1469 | 1470 | case -1: // Initialize ripple variables. 1471 | center = random(NUM_LEDS); 1472 | colour = (peakspersec*10) % 255; // More peaks/s = higher the hue colour. 1473 | step = 0; 1474 | break; 1475 | 1476 | case 0: 1477 | leds[center] = CHSV(colour, 255, 255); // Display the first pixel of the ripple. 1478 | step ++; 1479 | break; 1480 | 1481 | case maxsteps: // At the end of the ripples. 1482 | // step = -1; 1483 | break; 1484 | 1485 | default: // Middle of the ripples. 1486 | leds[(center + step + NUM_LEDS) % NUM_LEDS] += CHSV(colour, 255, myfade/step*2); // Simple wrap from Marc Miller. 1487 | leds[(center - step + NUM_LEDS) % NUM_LEDS] += CHSV(colour, 255, myfade/step*2); 1488 | step ++; // Next step. 1489 | break; 1490 | } // switch step 1491 | 1492 | } // ripple() 1493 | 1494 | 1495 | 1496 | 1497 | 1498 | //Compute average of a int array, given the starting pointer and the length 1499 | int compute_average(int *avgs, int len) { 1500 | int sum = 0; 1501 | for (int i = 0; i < len; i++) 1502 | sum += avgs[i]; 1503 | 1504 | return (int)(sum / len); 1505 | 1506 | } 1507 | 1508 | //Insert a value into an array, and shift it down removing 1509 | //the first value if array already full 1510 | void insert(int val, int *avgs, int len) { 1511 | for (int i = 0; i < len; i++) { 1512 | if (avgs[i] == -1) { 1513 | avgs[i] = val; 1514 | return; 1515 | } 1516 | } 1517 | 1518 | for (int i = 1; i < len; i++) { 1519 | avgs[i - 1] = avgs[i]; 1520 | } 1521 | avgs[len - 1] = val; 1522 | } 1523 | 1524 | //Function imported from the arduino website. 1525 | //Basically map, but with a curve on the scale (can be non-uniform). 1526 | float fscale( float originalMin, float originalMax, float newBegin, float 1527 | newEnd, float inputValue, float curve){ 1528 | 1529 | float OriginalRange = 0; 1530 | float NewRange = 0; 1531 | float zeroRefCurVal = 0; 1532 | float normalizedCurVal = 0; 1533 | float rangedValue = 0; 1534 | boolean invFlag = 0; 1535 | 1536 | 1537 | // condition curve parameter 1538 | // limit range 1539 | 1540 | if (curve > 10) curve = 10; 1541 | if (curve < -10) curve = -10; 1542 | 1543 | curve = (curve * -.1) ; // - invert and scale - this seems more intuitive - postive numbers give more weight to high end on output 1544 | curve = pow(10, curve); // convert linear scale into lograthimic exponent for other pow function 1545 | 1546 | // Check for out of range inputValues 1547 | if (inputValue < originalMin) { 1548 | inputValue = originalMin; 1549 | } 1550 | if (inputValue > originalMax) { 1551 | inputValue = originalMax; 1552 | } 1553 | 1554 | // Zero Refference the values 1555 | OriginalRange = originalMax - originalMin; 1556 | 1557 | if (newEnd > newBegin){ 1558 | NewRange = newEnd - newBegin; 1559 | } 1560 | else 1561 | { 1562 | NewRange = newBegin - newEnd; 1563 | invFlag = 1; 1564 | } 1565 | 1566 | zeroRefCurVal = inputValue - originalMin; 1567 | normalizedCurVal = zeroRefCurVal / OriginalRange; // normalize to 0 - 1 float 1568 | 1569 | // Check for originalMin > originalMax - the math for all other cases i.e. negative numbers seems to work out fine 1570 | if (originalMin > originalMax ) { 1571 | return 0; 1572 | } 1573 | 1574 | if (invFlag == 0){ 1575 | rangedValue = (pow(normalizedCurVal, curve) * NewRange) + newBegin; 1576 | 1577 | } 1578 | else // invert the ranges 1579 | { 1580 | rangedValue = newBegin - (pow(normalizedCurVal, curve) * NewRange); 1581 | } 1582 | 1583 | return rangedValue; 1584 | } 1585 | 1586 | 1587 | //End Music Reactive Functions 1588 | ////////////////////////////////////////////////////// 1589 | 1590 | 1591 | 1592 | ////////////////////////////////////////////////////////////////////////// 1593 | //FASTLED MATRIX FUNCTIONS 1594 | ////////////////////////////////////////////////////////////////////////// 1595 | 1596 | void blobby_flow_gaps() { 1597 | // fill the led array 2/16-bit noise values 1598 | fill_2dnoise16(LEDS.leds(), kMatrixWidth, kMatrixHeight, kMatrixSerpentineLayout, 1599 | octaves,x,xscale,y,yscale,v_time, 1600 | hue_octaves,hxy,hue_scale,hxy,hue_scale,hue_time, false); 1601 | 1602 | LEDS.show(); 1603 | 1604 | // adjust the intra-frame time values 1605 | x += x_speed; 1606 | y += y_speed; 1607 | v_time += time_speed; 1608 | hue_time += hue_speed; 1609 | delay(50); 1610 | } 1611 | 1612 | 1613 | void blobby_flow() { 1614 | 1615 | 1616 | if (newborn ==1) { 1617 | SetupBlackAndWhiteStripedPalette(); 1618 | ChangeSettingsPeriodically(); 1619 | } else { 1620 | // Periodically choose a new palette, speed, and scale 1621 | ChangePaletteAndSettingsPeriodically(); 1622 | } 1623 | 1624 | 1625 | // generate noise data 1626 | fillnoise8(); 1627 | 1628 | // convert the noise data to colors in the LED array 1629 | // using the current palette 1630 | mapNoiseToLEDsUsingPalette(); 1631 | 1632 | LEDS.show(); 1633 | // delay(10); 1634 | } 1635 | 1636 | 1637 | 1638 | // Fill the x/y array of 8-bit noise values using the inoise8 function. 1639 | void fillnoise8() { 1640 | // If we're runing at a low "speed", some 8-bit artifacts become visible 1641 | // from frame-to-frame. In order to reduce this, we can do some fast data-smoothing. 1642 | // The amount of data smoothing we're doing depends on "speed". 1643 | uint8_t dataSmoothing = 0; 1644 | if( speed < 50) { 1645 | dataSmoothing = 200 - (speed * 4); 1646 | } 1647 | 1648 | for(int i = 0; i < MAX_DIMENSION; i++) { 1649 | int ioffset = scale * i; 1650 | for(int j = 0; j < MAX_DIMENSION; j++) { 1651 | int joffset = scale * j; 1652 | 1653 | uint8_t data = inoise8(x + ioffset,y + joffset,z); 1654 | 1655 | // The range of the inoise8 function is roughly 16-238. 1656 | // These two operations expand those values out to roughly 0..255 1657 | // You can comment them out if you want the raw noise data. 1658 | data = qsub8(data,16); 1659 | data = qadd8(data,scale8(data,39)); 1660 | 1661 | if( dataSmoothing ) { 1662 | uint8_t olddata = noise[i][j]; 1663 | uint8_t newdata = scale8( olddata, dataSmoothing) + scale8( data, 256 - dataSmoothing); 1664 | data = newdata; 1665 | } 1666 | 1667 | noise[i][j] = data; 1668 | } 1669 | } 1670 | 1671 | z += speed; 1672 | 1673 | // apply slow drift to X and Y, just for visual variation. 1674 | x += speed / 8; 1675 | y -= speed / 16; 1676 | } 1677 | 1678 | void mapNoiseToLEDsUsingPalette() 1679 | { 1680 | static uint8_t ihue=0; 1681 | 1682 | for(int i = 0; i < kMatrixWidth; i++) { 1683 | for(int j = 0; j < kMatrixHeight; j++) { 1684 | // We use the value at the (i,j) coordinate in the noise 1685 | // array for our brightness, and the flipped value from (j,i) 1686 | // for our pixel's index into the color palette. 1687 | 1688 | uint8_t index = noise[j][i]; 1689 | uint8_t bri = noise[i][j]; 1690 | 1691 | // if this palette is a 'loop', add a slowly-changing base value 1692 | if( colorLoop) { 1693 | index += ihue; 1694 | } 1695 | 1696 | // brighten up, as the color palette itself often contains the 1697 | // light/dark dynamic range desired 1698 | if( bri > 127 ) { 1699 | bri = 255; 1700 | } else { 1701 | bri = dim8_raw( bri * 2); 1702 | } 1703 | 1704 | CRGB color = ColorFromPalette( currentPalette, index, bri); 1705 | leds[XY(i,j)] = color; 1706 | } 1707 | } 1708 | 1709 | ihue+=1; 1710 | } 1711 | 1712 | 1713 | 1714 | // There are several different palettes of colors demonstrated here. 1715 | // 1716 | // FastLED provides several 'preset' palettes: RainbowColors_p, RainbowStripeColors_p, 1717 | // OceanColors_p, CloudColors_p, LavaColors_p, ForestColors_p, and PartyColors_p. 1718 | // 1719 | // Additionally, you can manually define your own color palettes, or you can write 1720 | // code that creates color palettes on the fly. 1721 | 1722 | // 1 = 5 sec per palette 1723 | // 2 = 10 sec per palette 1724 | // etc 1725 | #define HOLD_PALETTES_X_TIMES_AS_LONG 1 1726 | 1727 | void ChangePaletteAndSettingsPeriodically() 1728 | { 1729 | EVERY_N_MILLISECONDS(100) { 1730 | uint8_t secondHand = ((millis() / 1000) / HOLD_PALETTES_X_TIMES_AS_LONG) % 60; 1731 | static uint8_t lastSecond = 99; 1732 | 1733 | if( lastSecond != secondHand) { 1734 | lastSecond = secondHand; 1735 | if( secondHand == 0) { 1736 | currentPalette = RainbowColors_p; 1737 | speed = 6; 1738 | // speed = 20; 1739 | scale = 30; 1740 | colorLoop = 1; } 1741 | if( secondHand == 5) { 1742 | SetupPurpleAndGreenPalette(); 1743 | speed = 4; 1744 | // speed = 10; 1745 | scale = 50; 1746 | colorLoop = 1; } 1747 | if( secondHand == 10) { 1748 | SetupRandomPalette(); 1749 | speed = 4; 1750 | // speed = 20; 1751 | scale = 30; 1752 | colorLoop = 1; } 1753 | if( secondHand == 15) { 1754 | currentPalette = ForestColors_p; 1755 | speed = 12; 1756 | scale =120; 1757 | colorLoop = 0; } 1758 | if( secondHand == 20) { 1759 | SetupRandomPalette(); 1760 | speed = 6; 1761 | scale = 30; 1762 | colorLoop = 1; } 1763 | if( secondHand == 25) { 1764 | currentPalette = LavaColors_p; 1765 | speed = 8; 1766 | scale = 50; 1767 | colorLoop = 0; } 1768 | if( secondHand == 30) { 1769 | SetupRandomPalette(); 1770 | speed = 4; 1771 | // speed = 20; 1772 | scale = 40; 1773 | colorLoop = 0; } 1774 | if( secondHand == 35) { 1775 | currentPalette = PartyColors_p; 1776 | speed = 8; 1777 | // speed = 20; 1778 | scale = 30; 1779 | colorLoop = 1; } 1780 | if( secondHand == 40) { 1781 | SetupBlackAndWhiteStripedPalette(); 1782 | speed = 8; 1783 | // speed = 20; 1784 | scale = 20; 1785 | colorLoop = 1; } 1786 | if( secondHand == 45) { 1787 | SetupRandomPalette(); 1788 | speed = 5; 1789 | // speed = 50; 1790 | scale = 25; 1791 | colorLoop = 1; } 1792 | if( secondHand == 50) { 1793 | currentPalette = CloudColors_p; 1794 | speed = 8; 1795 | // speed = 90; 1796 | scale = 90; 1797 | colorLoop = 1; } 1798 | if( secondHand == 55) { 1799 | currentPalette = OceanColors_p; 1800 | speed = 8; 1801 | // speed = 30; 1802 | scale = 20; 1803 | colorLoop = 1; } 1804 | } 1805 | } 1806 | } 1807 | 1808 | void ChangeSettingsPeriodically() 1809 | { 1810 | EVERY_N_MILLISECONDS(100) { 1811 | uint8_t secondHand = ((millis() / 1000) / HOLD_PALETTES_X_TIMES_AS_LONG) % 60; 1812 | static uint8_t lastSecond = 99; 1813 | 1814 | if( lastSecond != secondHand) { 1815 | lastSecond = secondHand; 1816 | if( secondHand == 0) { 1817 | speed = 3; 1818 | // speed = 20; 1819 | scale = 30; 1820 | colorLoop = 1; } 1821 | if( secondHand == 5) { 1822 | speed = 2; 1823 | // speed = 10; 1824 | scale = 50; 1825 | colorLoop = 1; } 1826 | if( secondHand == 10) { 1827 | speed = 2; 1828 | // speed = 20; 1829 | scale = 30; 1830 | colorLoop = 1; } 1831 | if( secondHand == 15) { 1832 | speed = 6; 1833 | scale =120; 1834 | colorLoop = 0; } 1835 | if( secondHand == 20) { 1836 | speed = 3; 1837 | scale = 30; 1838 | colorLoop = 0; } 1839 | if( secondHand == 25) { 1840 | currentPalette = LavaColors_p; 1841 | speed = 4; 1842 | scale = 50; 1843 | colorLoop = 0; } 1844 | if( secondHand == 30) { 1845 | speed = 4; 1846 | // speed = 20; 1847 | scale = 90; 1848 | colorLoop = 0; } 1849 | if( secondHand == 35) { 1850 | speed = 4; 1851 | // speed = 20; 1852 | scale = 30; 1853 | colorLoop = 1; } 1854 | if( secondHand == 40) { 1855 | speed = 4; 1856 | // speed = 20; 1857 | scale = 20; 1858 | colorLoop = 1; } 1859 | if( secondHand == 45) { 1860 | speed = 4; 1861 | // speed = 50; 1862 | scale = 50; 1863 | colorLoop = 1; } 1864 | if( secondHand == 50) { 1865 | speed = 8; 1866 | // speed = 90; 1867 | scale = 90; 1868 | colorLoop = 1; } 1869 | if( secondHand == 55) { 1870 | speed = 4; 1871 | // speed = 30; 1872 | scale = 20; 1873 | colorLoop = 1; } 1874 | } 1875 | } 1876 | } 1877 | 1878 | // This function generates a random palette that's a gradient 1879 | // between four different colors. The first is a dim hue, the second is 1880 | // a bright hue, the third is a bright pastel, and the last is 1881 | // another bright hue. This gives some visual bright/dark variation 1882 | // which is more interesting than just a gradient of different hues. 1883 | void SetupRandomPalette() 1884 | { 1885 | currentPalette = CRGBPalette16( 1886 | CHSV( random8(), 255, 32), 1887 | CHSV( random8(), 255, 255), 1888 | CHSV( random8(), 128, 255), 1889 | CHSV( random8(), 255, 255)); 1890 | } 1891 | 1892 | // This function sets up a palette of black and white stripes, 1893 | // using code. Since the palette is effectively an array of 1894 | // sixteen CRGB colors, the various fill_* functions can be used 1895 | // to set them up. 1896 | void SetupBlackAndWhiteStripedPalette() 1897 | { 1898 | // 'black out' all 16 palette entries... 1899 | fill_solid( currentPalette, 16, CRGB::Black); 1900 | // and set every fourth one to white. 1901 | currentPalette[0] = CRGB::White; 1902 | currentPalette[4] = CRGB::White; 1903 | currentPalette[8] = CRGB::White; 1904 | currentPalette[12] = CRGB::White; 1905 | 1906 | } 1907 | 1908 | // This function sets up a palette of purple and green stripes. 1909 | void SetupPurpleAndGreenPalette() 1910 | { 1911 | CRGB purple = CHSV( HUE_PURPLE, 255, 255); 1912 | CRGB green = CHSV( HUE_GREEN, 255, 255); 1913 | CRGB black = CRGB::Black; 1914 | 1915 | currentPalette = CRGBPalette16( 1916 | green, green, black, black, 1917 | purple, purple, black, black, 1918 | green, green, black, black, 1919 | purple, purple, black, black ); 1920 | } 1921 | 1922 | 1923 | // 1924 | // Mark's xy coordinate mapping code. See the XYMatrix for more information on it. 1925 | // 1926 | uint16_t XY( uint8_t x, uint8_t y) 1927 | { 1928 | uint16_t i; 1929 | if( kMatrixSerpentineLayout == false) { 1930 | i = (y * kMatrixWidth) + x; 1931 | } 1932 | if( kMatrixSerpentineLayout == true) { 1933 | if( y & 0x01) { 1934 | // Odd rows run backwards 1935 | uint8_t reverseX = (kMatrixWidth - 1) - x; 1936 | i = (y * kMatrixWidth) + reverseX; 1937 | } else { 1938 | // Even rows run forwards 1939 | i = (y * kMatrixWidth) + x; 1940 | } 1941 | } 1942 | return i; 1943 | } 1944 | 1945 | 1946 | 1947 | //////////////////////////////////// 1948 | ///Blur Visualize 1949 | 1950 | void blur() { 1951 | 1952 | 1953 | EVERY_N_MILLISECONDS(40) { 1954 | uint8_t blurAmount = dim8_raw( beatsin8(3,64, 192) ); // A sinewave at 3 Hz with values ranging from 64 to 192. 1955 | blur1d( leds, NUM_LEDS, blurAmount); // Apply some blurring to whatever's already on the strip, which will eventually go black. 1956 | 1957 | uint8_t i = beatsin8( 9, 0, NUM_LEDS-1); 1958 | uint8_t j = beatsin8( 7, 0, NUM_LEDS-1); 1959 | uint8_t k = beatsin8( 5, 0, NUM_LEDS-1); 1960 | 1961 | 1962 | // The color of each point shifts over time, each at a different speed. 1963 | uint16_t ms = millis(); 1964 | leds[(i+j)/2] = CHSV( ms / 29, 200, 255); 1965 | leds[(j+k)/2] = CHSV( ms / 41, 200, 255); 1966 | leds[(k+i)/2] = CHSV( ms / 73, 200, 255); 1967 | leds[(k+i+j)/3] = CHSV( ms / 53, 200, 255); 1968 | 1969 | FastLED.show(); 1970 | } 1971 | 1972 | } // loop() 1973 | 1974 | 1975 | 1976 | //////Matrix Sinelon 1977 | void matrix_sinelon() { 1978 | fadeToBlackBy( leds, NUM_LEDS, 25); 1979 | int pos = beatsin16( 19, 0, kMatrixWidth-1 ); 1980 | 1981 | for(int i = 0; i < kMatrixWidth; i++) { 1982 | leds[XY(i, pos)] += CHSV( gHue, 240, 140); 1983 | } 1984 | 1985 | for(int i = 0; i < kMatrixHeight; i++) { 1986 | leds[XY(pos, i)] += CHSV( gHue+100, 240, 140); 1987 | } 1988 | FastLED.show(); 1989 | EVERY_N_MILLISECONDS( 50 ) { gHue++; } // slowly cycle the "base color" through the rainbow 1990 | 1991 | } 1992 | 1993 | 1994 | 1995 | ////////////////////////////////////////////////////// 1996 | //////////////////Rotate Non-Reactive Visualizers 1997 | 1998 | void rotate_all_patterns() { 1999 | 2000 | gPatterns[gCurrentPatternNumber](); 2001 | 2002 | // send the 'leds' array out to the actual LED strip 2003 | FastLED.show(); 2004 | // insert a delay to keep the framerate modest 2005 | FastLED.delay(1000/FRAMES_PER_SECOND); 2006 | 2007 | // do some periodic updates 2008 | EVERY_N_MILLISECONDS( 20 ) { gHue++; } // slowly cycle the "base color" through the rainbow 2009 | EVERY_N_SECONDS( 20 ) { nextPattern(); } // change patterns periodically 2010 | 2011 | } 2012 | 2013 | 2014 | void nextPattern() 2015 | { 2016 | // add one to the current pattern number, and wrap around at the end 2017 | gCurrentPatternNumber = (gCurrentPatternNumber + 1) % ARRAY_SIZE( gPatterns); 2018 | } 2019 | 2020 | void rainbow() 2021 | { 2022 | // FastLED's built-in rainbow generator 2023 | fill_rainbow( leds, NUM_LEDS, gHue, 7); 2024 | } 2025 | 2026 | void rainbowWithGlitter() 2027 | { 2028 | // built-in FastLED rainbow, plus some random sparkly glitter 2029 | rainbow(); 2030 | addGlitter(80); 2031 | } 2032 | 2033 | void addGlitter( fract8 chanceOfGlitter) 2034 | { 2035 | if( random8() < chanceOfGlitter) { 2036 | leds[ random16(NUM_LEDS) ] += CRGB::White; 2037 | } 2038 | } 2039 | 2040 | void confetti() 2041 | { 2042 | // random colored speckles that blink in and fade smoothly 2043 | fadeToBlackBy( leds, NUM_LEDS, 10); 2044 | int pos = random16(NUM_LEDS); 2045 | leds[pos] += CHSV( gHue + random8(64), 200, 255); 2046 | } 2047 | 2048 | void sinelon() 2049 | { 2050 | // a colored dot sweeping back and forth, with fading trails 2051 | fadeToBlackBy( leds, NUM_LEDS, 20); 2052 | int pos = beatsin16( 13, 0, NUM_LEDS-1 ); 2053 | leds[pos] += CHSV( gHue, 255, 192); 2054 | } 2055 | 2056 | void bpm() 2057 | { 2058 | // colored stripes pulsing at a defined Beats-Per-Minute (BPM) 2059 | uint8_t BeatsPerMinute = 62; 2060 | CRGBPalette16 palette = PartyColors_p; 2061 | uint8_t beat = beatsin8( BeatsPerMinute, 64, 255); 2062 | for( int i = 0; i < NUM_LEDS; i++) { //9948 2063 | leds[i] = ColorFromPalette(palette, gHue+(i*2), beat-gHue+(i*10)); 2064 | } 2065 | } 2066 | 2067 | void juggle() { 2068 | // eight colored dots, weaving in and out of sync with each other 2069 | fadeToBlackBy( leds, NUM_LEDS, 20); 2070 | byte dothue = 0; 2071 | for( int i = 0; i < 8; i++) { 2072 | leds[beatsin16( i+7, 0, NUM_LEDS-1 )] |= CHSV(dothue, 200, 255); 2073 | dothue += 32; 2074 | } 2075 | } 2076 | 2077 | /////////////////////////////////////////////////////////////////// 2078 | //FASTLED XYMATRIX PATTERN EXAMPLE 2079 | 2080 | void XYmatrix() 2081 | { 2082 | uint32_t ms = millis(); 2083 | int32_t yHueDelta32 = ((int32_t)cos16( ms * (27/1) ) * (350 / kMatrixWidth)); 2084 | int32_t xHueDelta32 = ((int32_t)cos16( ms * (39/1) ) * (310 / kMatrixHeight)); 2085 | DrawOneFrame( ms / 65536, yHueDelta32 / 32768, xHueDelta32 / 32768); 2086 | if( ms < 5000 ) { 2087 | FastLED.setBrightness( scale8( BRIGHTNESS, (ms * 256) / 5000)); 2088 | } else { 2089 | FastLED.setBrightness(BRIGHTNESS); 2090 | } 2091 | FastLED.show(); 2092 | } 2093 | 2094 | void DrawOneFrame( byte startHue8, int8_t yHueDelta8, int8_t xHueDelta8) 2095 | { 2096 | byte lineStartHue = startHue8; 2097 | for( byte y = 0; y < kMatrixHeight; y++) { 2098 | lineStartHue += yHueDelta8; 2099 | byte pixelHue = lineStartHue; 2100 | for( byte x = 0; x < kMatrixWidth; x++) { 2101 | pixelHue += xHueDelta8; 2102 | leds[ XY(x, y)] = CHSV( pixelHue, 255, 255); 2103 | } 2104 | } 2105 | } 2106 | 2107 | ///////////////////////////////////////////////// 2108 | ///////////////////////////////////////////////// 2109 | //Put in black and white for newborn baby mode 2110 | 2111 | void newborn_mode() { 2112 | SetupBlackAndWhiteStripedPalette(); 2113 | } 2114 | 2115 | 2116 | ///////////////////////////////////////////////// 2117 | ///////////////////////////////////////////////// 2118 | //Fireplace visualizer 2119 | 2120 | void Fireplace () { 2121 | 2122 | random16_add_entropy( random() ); // We chew a lot of entropy 2123 | 2124 | static unsigned int spark[kMatrixHeight]; // base heat 2125 | CRGB stack[kMatrixHeight][kMatrixWidth]; // stacks that are cooler 2126 | 2127 | // 1. Generate sparks to re-heat 2128 | for( int i = 0; i < kMatrixHeight; i++) { 2129 | if (spark[i] < HOT ) { 2130 | int base = HOT * 2; 2131 | spark[i] = random16( base, MAXHOT ); 2132 | } 2133 | } 2134 | 2135 | // 2. Cool all the sparks 2136 | for( int i = 0; i < kMatrixHeight; i++) { 2137 | spark[i] = qsub8( spark[i], random8(0, COOLING) ); 2138 | } 2139 | 2140 | // 3. Build the stack 2141 | /* This works on the idea that pixels are "cooler" 2142 | as they get further from the spark at the bottom */ 2143 | for( int i = 0; i < kMatrixHeight; i++) { 2144 | unsigned int heat = constrain(spark[i], HOT, MAXHOT); 2145 | for( int j = kMatrixWidth-1; j >= 0; j--) { 2146 | /* Calculate the color on the palette from how hot this 2147 | pixel is */ 2148 | byte index = constrain(heat, 0, HOT); 2149 | stack[i][j] = ColorFromPalette( gPal, index ); 2150 | 2151 | /* The next higher pixel will be "cooler", so calculate 2152 | the drop */ 2153 | unsigned int drop = random8(0,HOT); 2154 | if (drop > heat) heat = 0; // avoid wrap-arounds from going "negative" 2155 | else heat -= drop; 2156 | 2157 | heat = constrain(heat, 0, MAXHOT); 2158 | } 2159 | } 2160 | 2161 | // 4. map stacks to led array 2162 | for( int i = 0; i < kMatrixHeight; i++) { 2163 | for( int j = 0; j < kMatrixWidth; j++) { 2164 | leds[ XY(j, i) ] = stack[i][j]; 2165 | } 2166 | } 2167 | FastLED.show(); 2168 | FastLED.delay(FPS_DELAY); 2169 | } 2170 | 2171 | //////////////////////////////////////////////////// 2172 | //FastLED Matrix Code Pattern 2173 | 2174 | void matrix_code() { 2175 | EVERY_N_MILLIS(75) // falling speed 2176 | { 2177 | // move code downward 2178 | // start with lowest row to allow proper overlapping on each column 2179 | for (int8_t row=kMatrixHeight-1; row>=0; row--) 2180 | { 2181 | for (int8_t col=0; colaMax) 2257 | // aByte = aMax; 2258 | // else 2259 | // aByte = (byte)r; 2260 | //} 2261 | // 2262 | //uint16_t random2(uint16_t aMinOrMax, uint16_t aMax = 0) 2263 | //{ 2264 | // if (aMax==0) { 2265 | // aMax = aMinOrMax; 2266 | // aMinOrMax = 0; 2267 | // } 2268 | // uint32_t r = aMinOrMax; 2269 | // aMax = aMax - aMinOrMax + 1; 2270 | // r += rand() % aMax; 2271 | // return r; 2272 | //} 2273 | // 2274 | //void resetEnergy() 2275 | //{ 2276 | // for (int i=0; i>8; 2310 | // // this cell becomes active spark 2311 | // energyMode[i] = torch_spark; 2312 | // } 2313 | // else { 2314 | // increase(e, spark_tfr); 2315 | // } 2316 | // break; 2317 | // } 2318 | // case torch_passive: { 2319 | // e = ((int)e*heat_cap)>>8; 2320 | // increase(e, ((((int)currentEnergy[i-1]+(int)currentEnergy[i+1])*side_rad)>>9) + (((int)currentEnergy[i-ledsPerLevel]*up_rad)>>8)); 2321 | // } 2322 | // default: 2323 | // break; 2324 | // } 2325 | // nextEnergy[i++] = e; 2326 | // } 2327 | // } 2328 | //} 2329 | // 2330 | //const uint8_t energymap[32] = {0, 64, 96, 112, 128, 144, 152, 160, 168, 176, 184, 184, 192, 200, 200, 208, 208, 216, 216, 224, 224, 224, 232, 232, 232, 240, 240, 240, 240, 248, 248, 248}; 2331 | // 2332 | //void calcNextColors() 2333 | //{ 2334 | // for (int i=0; i250) 2343 | // leds[i] = CRGB(170, 170, e); // blueish extra-bright spark 2344 | // else { 2345 | // if (e>0) { 2346 | // // energy to brightness is non-linear 2347 | // byte eb = energymap[e>>3]; 2348 | // byte r = red_bias; 2349 | // byte g = green_bias; 2350 | // byte b = blue_bias; 2351 | // increase(r, (eb*red_energy)>>8); 2352 | // increase(g, (eb*green_energy)>>8); 2353 | // increase(b, (eb*blue_energy)>>8); 2354 | // leds[i] = CRGB(r, g, b); 2355 | // } 2356 | // else { 2357 | // // background, no energy 2358 | // leds[i] = CRGB(red_bg, green_bg, blue_bg); 2359 | // } 2360 | // } 2361 | // } 2362 | //} 2363 | // 2364 | //void injectRandom() 2365 | //{ 2366 | // // random flame energy at bottom row 2367 | // for (int i=0; i