Make Your Own Wireless RGB VU Meter With Nice Light Effects
Hi friends, This is new and very compact DIY Wireless RGB VU meter with multiple color effects for when not using as a vu meter. This is totally wireless, no need to connect any device with this also this is rechargeable. You can control brightness and sensitivity using potentiometer. This very cool idea for your home decoration.
Diagram:
Components:
1) ws2812B led strip 60led/m : https://roboman.in/qtch
2) ws2812B led strip 30led/m : https://roboman.in/6r9a
3) TP-4056 Module : https://roboman.in/oa0m
4) Arduino Nano: https://roboman.in/59h4
5) Arduino Nano Type C : https://roboman.in/xkfu
6) Sound Sensor : Sound Sensor :https://roboman.in/vs1e
7) 18650 Lithium Battery 2500mah 3C :https://roboman.in/utwc
8) 18650 Lithium Battery 2600mah 3C :https://roboman.in/mmab
9) 18650 Lithium Battery 2200mah 1C :https://roboman.in/70b5
10) 18650 Lithium Battery 2000mah 1C :https://roboman.in/7em9
11) 18650 Lithium Battery 1800mah 1C :https://roboman.in/ywss
12) SPST Switch : https://roboman.in/74he
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 |
#include <Adafruit_NeoPixel.h> #include <FastLED.h> #include <EEPROM.h> #define PIN 6 #define N_PIXELS 29 #define BG 0 #define COLOR_ORDER GRB // Try mixing up the letters (RGB, GBR, BRG, etc) for a whole new world of color combinations #define BRIGHTNESS 255 // 0-255, higher number is brighter. #define LED_TYPE WS2812B #define MIC_PIN A4 // Microphone is attached to this analog pin #define DC_OFFSET 0 // DC offset in mic signal - if unusure, leave 0 #define NOISE 10 // Noise/hum/interference in mic signal #define SAMPLES 60 // Length of buffer for dynamic level adjustment #define TOP (N_PIXELS + 2) // Allow dot to go slightly off scale #define PEAK_FALL 20 // Rate of peak falling dot #define N_PIXELS_HALF (N_PIXELS/2) #define GRAVITY -9.81 // Downward (negative) acceleration of gravity in m/s^2 #define h0 1 // Starting height, in meters, of the ball (strip length) #define NUM_BALLS 3 // Number of bouncing balls you want (recommend < 7, but 20 is fun in its own way) #define SPEED .20 // Amount to increment RGB color by each cycle int brightnessPin = A0, potPin = A1; //config for balls float h[NUM_BALLS] ; // An array of heights float vImpact0 = sqrt( -2 * GRAVITY * h0 ); // Impact velocity of the ball when it hits the ground if "dropped" from the top of the strip float vImpact[NUM_BALLS] ; // As time goes on the impact velocity will change, so make an array to store those values float tCycle[NUM_BALLS] ; // The time since the last time the ball struck the ground int pos[NUM_BALLS] ; // The integer position of the dot on the strip (LED index) long tLast[NUM_BALLS] ; // The clock time of the last ground strike float COR[NUM_BALLS] ; // Coefficient of Restitution (bounce damping) float greenOffset = 30, blueOffset = 150; byte peak = 0, // Used for falling dot dotCount = 0, // Frame counter for delaying dot-falling speed volCount = 0; // Frame counter for storing past volume data int vol[SAMPLES], // Collection of prior volume samples lvl = 10, // Current "dampened" audio level minLvlAvg = 0, // For dynamic adjustment of graph low & high maxLvlAvg = 512; int brightnessValue, prevBrightnessValue; int sensorDeviationBrightness = 1; int sensitivityValue = 128; // 0 - 255, initial value (value read from the potentiometer if useSensorValues = true) int maxSensitivity = 2 * 255; // let the 'volume' go up to 200%! int ledBrightness = 255; // 0 - 255, initial value (value read from the potentiometer if useSensorValues = true) int val; Adafruit_NeoPixel strip = Adafruit_NeoPixel(N_PIXELS, PIN, NEO_GRB + NEO_KHZ800); // FOR SYLON ETC uint8_t thisbeat = 23; uint8_t thatbeat = 28; uint8_t thisfade = 2; // How quickly does it fade? Lower = slower fade rate. uint8_t thissat = 255; // The saturation, where 255 = brilliant colours. uint8_t thisbri = 255; //FOR JUGGLE uint8_t numdots = 4; // Number of dots in use. uint8_t faderate = 2; // How long should the trails be. Very low value = longer trails. uint8_t hueinc = 16; // Incremental change in hue between each dot. uint8_t thishue = 0; // Starting hue. uint8_t curhue = 0; uint8_t thisbright = 255; // How bright should the LED/display be. uint8_t basebeat = 5; uint8_t max_bright = 255; // Twinkle float redStates[N_PIXELS]; float blueStates[N_PIXELS]; float greenStates[N_PIXELS]; float Fade = 0.96; // Vu meter 4 const uint32_t Red = strip.Color(255, 0, 0); const uint32_t Yellow = strip.Color(255, 255, 0); const uint32_t Green = strip.Color(0, 255, 0); const uint32_t Blue = strip.Color(0, 0, 255); const uint32_t White = strip.Color(255, 255, 255); const uint32_t Dark = strip.Color(0, 0, 0); unsigned int sample; CRGB leds[N_PIXELS]; int myhue = 0; // constants used here to set pin numbers: const int buttonPin = 3; // the number of the pushbutton pin // Variables will change: int buttonPushCounter = 0; // counter for the number of button presses int buttonState = 0; // current state of the button int lastButtonState = 0; //Ripple variables int color; int center = 0; int step = -1; int maxSteps = 8; float fadeRate = 0.80; int diff; //background color uint32_t currentBg = random(256); uint32_t nextBg = currentBg; void setup() { delay( 2000 ); // power-up safety delay FastLED.addLeds<WS2812B, PIN, COLOR_ORDER>(leds, N_PIXELS).setCorrection( TypicalLEDStrip ); FastLED.setBrightness( BRIGHTNESS ); analogReference(EXTERNAL); memset(vol, 0, sizeof(vol)); LEDS.addLeds<LED_TYPE, PIN, COLOR_ORDER>(leds, N_PIXELS); strip.begin(); strip.show(); // Initialize all pixels to 'off' //initialize the serial port Serial.begin(115200); pinMode(buttonPin, INPUT); pinMode(2, OUTPUT); //initialize the buttonPin as output digitalWrite(buttonPin, HIGH); digitalWrite(2, HIGH); for (int i = 0 ; i < NUM_BALLS ; i++) { // Initialize variables tLast[i] = millis(); h[i] = h0; pos[i] = 0; // Balls start on the ground vImpact[i] = vImpact0; // And "pop" up at vImpact0 tCycle[i] = 0; COR[i] = 0.90 - float(i)/pow(NUM_BALLS,2); } } void loop() { brightnessValue = analogRead(brightnessPin); brightnessValue = map(brightnessValue, 0, 1023, 0, 255); if (abs(brightnessValue - prevBrightnessValue) > sensorDeviationBrightness) { ledBrightness = brightnessValue; strip.setBrightness(ledBrightness); prevBrightnessValue = brightnessValue; } //for mic uint8_t i; uint16_t minLvl, maxLvl; int n, height; // end mic buttonPushCounter=EEPROM.read(0); // read the pushbutton input pin: buttonState = digitalRead(buttonPin); // compare the buttonState to its previous state if (buttonState != lastButtonState) { // if the state has changed, increment the counter if (buttonState == HIGH) { // if the current state is HIGH then the button // wend from off to on: buttonPushCounter++; Serial.println("on"); Serial.print("number of button pushes: "); Serial.println(buttonPushCounter); if(buttonPushCounter>=14) { buttonPushCounter=1;} EEPROM.write(0,buttonPushCounter); } else { // if the current state is LOW then the button // wend from on to off: Serial.println("off"); } } // save the current state as the last state, //for next time through the loop lastButtonState = buttonState; switch (buttonPushCounter){ case 1: buttonPushCounter==1; { Serial.println("1"); vu(); // Red break;} case 2: buttonPushCounter==2; { Serial.println("2"); vu2(); // Red break;} case 3: buttonPushCounter==3; { Serial.println("3"); Vu3(); // break;} case 4: buttonPushCounter==4; { Serial.println("4"); Vu4(); // break;} case 5: buttonPushCounter==5; { Serial.println("5"); rainbow(150); break;} case 6: buttonPushCounter==6; { Serial.println("6"); rainbow(20); break;} case 7: buttonPushCounter==7; { Serial.println("7"); ripple(); break;} case 8: buttonPushCounter==8; { Serial.println("8"); ripple2(); break;} case 9: buttonPushCounter==9; { Serial.println("10"); Twinkle(); break;} case 10: buttonPushCounter==10; { Serial.println("10"); pattern2(); break;} case 11: buttonPushCounter==11; { Serial.println("11"); pattern3(); break;} case 12: buttonPushCounter==12; { Serial.println("12"); Balls(); // break;} case 13: buttonPushCounter==13; { Serial.println("13"); colorWipe(strip.Color(0, 0, 0), 10); // A Black break;} } } void colorWipe(uint32_t c, uint8_t wait) { for(uint16_t i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, c); strip.show(); if (digitalRead(buttonPin) != lastButtonState) // <------------- add this return; // <------------ and this delay(wait); } } void Vu4() { uint8_t i; uint16_t minLvl, maxLvl; int n, height; val = (analogRead(potPin)); val= map(val, 0, 1023, -10, 6); n = analogRead(MIC_PIN); // Raw reading from mic n = abs(n - 0 - DC_OFFSET); // Center on zero n = (n <= NOISE) ? 0 : (n - NOISE); // Remove noise/hum if(val<0){ n=n/(val*(-1)); } if(val>0){ n=n*val; } lvl = ((lvl * 7) + n) >> 3; // "Dampened" reading (else looks twitchy) // Calculate bar height based on dynamic min/max levels (fixed point): height = TOP * (lvl - minLvlAvg) / (long)(maxLvlAvg - minLvlAvg); if(height < 0L) height = 0; // Clip output else if(height > TOP) height = TOP; if(height > peak) peak = height; // Keep 'peak' dot at top greenOffset += SPEED; blueOffset += SPEED; if (greenOffset >= 255) greenOffset = 0; if (blueOffset >= 255) blueOffset = 0; // Color pixels based on rainbow gradient for(i=0; i<N_PIXELS_HALF; i++) { if(i >= height) { strip.setPixelColor(N_PIXELS_HALF-i-1, 0, 0, 0); strip.setPixelColor(N_PIXELS_HALF+i, 0, 0, 0); } else { uint32_t color = Wheel(map(i,0,N_PIXELS_HALF-1,(int)greenOffset, (int)blueOffset)); strip.setPixelColor(N_PIXELS_HALF-i-1,color); strip.setPixelColor(N_PIXELS_HALF+i,color); } } // Draw peak dot if(peak > 0 && peak <= N_PIXELS_HALF-1) { uint32_t color = Wheel(map(peak,0,N_PIXELS_HALF-1,30,150)); strip.setPixelColor(N_PIXELS_HALF-peak-1,color); strip.setPixelColor(N_PIXELS_HALF+peak,color); } strip.show(); // Update strip // Every few frames, make the peak pixel drop by 1: if(++dotCount >= PEAK_FALL) { //fall rate if(peak > 0) peak--; dotCount = 0; } vol[volCount] = n; // Save sample for dynamic leveling if(++volCount >= SAMPLES) volCount = 0; // Advance/rollover sample counter // Get volume range of prior frames minLvl = maxLvl = vol[0]; for(i=1; i<SAMPLES; i++) { if(vol[i] < minLvl) minLvl = vol[i]; else if(vol[i] > maxLvl) maxLvl = vol[i]; } // minLvl and maxLvl indicate the volume range over prior frames, used // for vertically scaling the output graph (so it looks interesting // regardless of volume level). If they're too close together though // (e.g. at very low volume levels) the graph becomes super coarse // and 'jumpy'...so keep some minimum distance between them (this // also lets the graph go to zero when no sound is playing): if((maxLvl - minLvl) < TOP) maxLvl = minLvl + TOP; minLvlAvg = (minLvlAvg * 63 + minLvl) >> 6; // Dampen min/max levels maxLvlAvg = (maxLvlAvg * 63 + maxLvl) >> 6; // (fake rolling average) } void Vu3() { uint8_t i; uint16_t minLvl, maxLvl; int n, height; val = (analogRead(potPin)); val= map(val, 0, 1023, -10, 6); n = analogRead(MIC_PIN); // Raw reading from mic n = abs(n - 0 - DC_OFFSET); // Center on zero n = (n <= NOISE) ? 0 : (n - NOISE); // Remove noise/hum if(val<0){ n=n/(val*(-1)); } if(val>0){ n=n*val; } lvl = ((lvl * 7) + n) >> 3; // "Dampened" reading (else looks twitchy) // Calculate bar height based on dynamic min/max levels (fixed point): height = TOP * (lvl - minLvlAvg) / (long)(maxLvlAvg - minLvlAvg); if (height < 0L) height = 0; // Clip output else if (height > TOP) height = TOP; if (height > peak) peak = height; // Keep 'peak' dot at top greenOffset += SPEED; blueOffset += SPEED; if (greenOffset >= 255) greenOffset = 0; if (blueOffset >= 255) blueOffset = 0; // Color pixels based on rainbow gradient for (i = 0; i < N_PIXELS; i++) { if (i >= height) { strip.setPixelColor(i, 0, 0, 0); } else { strip.setPixelColor(i, Wheel( map(i, 0, strip.numPixels() - 1, (int)greenOffset, (int)blueOffset) )); } } // Draw peak dot if(peak > 0 && peak <= N_PIXELS-1) strip.setPixelColor(peak,Wheel(map(peak,0,strip.numPixels()-1,30,150))); strip.show(); // Update strip // Every few frames, make the peak pixel drop by 1: if(++dotCount >= PEAK_FALL) { //fall rate if(peak > 0) peak--; dotCount = 0; } strip.show(); // Update strip vol[volCount] = n; if (++volCount >= SAMPLES) { volCount = 0; } // Get volume range of prior frames minLvl = maxLvl = vol[0]; for (i = 1; i < SAMPLES; i++) { if (vol[i] < minLvl) { minLvl = vol[i]; } else if (vol[i] > maxLvl) { maxLvl = vol[i]; } } // minLvl and maxLvl indicate the volume range over prior frames, used // for vertically scaling the output graph (so it looks interesting // regardless of volume level). If they're too close together though // (e.g. at very low volume levels) the graph becomes super coarse // and 'jumpy'...so keep some minimum distance between them (this // also lets the graph go to zero when no sound is playing): if ((maxLvl - minLvl) < TOP) { maxLvl = minLvl + TOP; } minLvlAvg = (minLvlAvg * 63 + minLvl) >> 6; // Dampen min/max levels maxLvlAvg = (maxLvlAvg * 63 + maxLvl) >> 6; // (fake rolling average) } void Balls() { for (int i = 0 ; i < NUM_BALLS ; i++) { tCycle[i] = millis() - tLast[i] ; // Calculate the time since the last time the ball was on the ground // A little kinematics equation calculates positon as a function of time, acceleration (gravity) and intial velocity h[i] = 0.5 * GRAVITY * pow( tCycle[i]/1000 , 2.0 ) + vImpact[i] * tCycle[i]/1000; if ( h[i] < 0 ) { h[i] = 0; // If the ball crossed the threshold of the "ground," put it back on the ground vImpact[i] = COR[i] * vImpact[i] ; // and recalculate its new upward velocity as it's old velocity * COR tLast[i] = millis(); if ( vImpact[i] < 0.01 ) vImpact[i] = vImpact0; // If the ball is barely moving, "pop" it back up at vImpact0 } pos[i] = round( h[i] * (N_PIXELS - 1) / h0); // Map "h" to a "pos" integer index position on the LED strip } //Choose color of LEDs, then the "pos" LED on for (int i = 0 ; i < NUM_BALLS ; i++) leds[pos[i]] = CHSV( uint8_t (i * 40) , 255, 255); FastLED.show(); //Then off for the next loop around for (int i = 0 ; i < NUM_BALLS ; i++) { leds[pos[i]] = CRGB::Black; } } // Slightly different, this makes the rainbow equally distributed throughout void rainbowCycle(uint8_t wait) { uint16_t i, j; for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel for(i=0; i< strip.numPixels(); i++) { strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255)); } strip.show(); if (digitalRead(buttonPin) != lastButtonState) // <------------- add this return; // <------------ and this delay(wait); } } // HERE void vu() { uint8_t i; uint16_t minLvl, maxLvl; int n, height; val = (analogRead(potPin)); val= map(val, 0, 1023, -10, 6); n = analogRead(MIC_PIN); // Raw reading from mic n = abs(n - 0 - DC_OFFSET); // Center on zero n = (n <= NOISE) ? 0 : (n - NOISE); // Remove noise/hum if(val<0){ n=n/(val*(-1)); } if(val>0){ n=n*val; } lvl = ((lvl * 7) + n) >> 3; // "Dampened" reading (else looks twitchy) // Calculate bar height based on dynamic min/max levels (fixed point): height = TOP * (lvl - minLvlAvg) / (long)(maxLvlAvg - minLvlAvg); if(height < 0L) height = 0; // Clip output else if(height > TOP) height = TOP; if(height > peak) peak = height; // Keep 'peak' dot at top // Color pixels based on rainbow gradient for(i=0; i<N_PIXELS; i++) { if(i >= height) strip.setPixelColor(i, 0, 0, 0); else strip.setPixelColor(i,Wheel(map(i,0,strip.numPixels()-1,30,150))); } // Draw peak dot if(peak > 0 && peak <= N_PIXELS-1) strip.setPixelColor(peak,Wheel(map(peak,0,strip.numPixels()-1,30,150))); strip.show(); // Update strip // Every few frames, make the peak pixel drop by 1: if(++dotCount >= PEAK_FALL) { //fall rate if(peak > 0) peak--; dotCount = 0; } vol[volCount] = n; // Save sample for dynamic leveling if(++volCount >= SAMPLES) volCount = 0; // Advance/rollover sample counter // Get volume range of prior frames minLvl = maxLvl = vol[0]; for(i=1; i<SAMPLES; i++) { if(vol[i] < minLvl) minLvl = vol[i]; else if(vol[i] > maxLvl) maxLvl = vol[i]; } // minLvl and maxLvl indicate the volume range over prior frames, used // for vertically scaling the output graph (so it looks interesting // regardless of volume level). If they're too close together though // (e.g. at very low volume levels) the graph becomes super coarse // and 'jumpy'...so keep some minimum distance between them (this // also lets the graph go to zero when no sound is playing): if((maxLvl - minLvl) < TOP) maxLvl = minLvl + TOP; minLvlAvg = (minLvlAvg * 63 + minLvl) >> 6; // Dampen min/max levels maxLvlAvg = (maxLvlAvg * 63 + maxLvl) >> 6; // (fake rolling average) } // Input a value 0 to 255 to get a color value. // The colors are a transition r - g - b - back to r. uint32_t Wheel(byte WheelPos) { if(WheelPos < 85) { return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0); } else if(WheelPos < 170) { WheelPos -= 85; return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3); } else { WheelPos -= 170; return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3); } } void vu2() { uint8_t i; uint16_t minLvl, maxLvl; int n, height; val = (analogRead(potPin)); val= map(val, 0, 1023, -10, 6); n = analogRead(MIC_PIN); // Raw reading from mic n = abs(n - 0 - DC_OFFSET); // Center on zero n = (n <= NOISE) ? 0 : (n - NOISE); // Remove noise/hum if(val<0){ n=n/(val*(-1)); } if(val>0){ n=n*val; } lvl = ((lvl * 7) + n) >> 3; // "Dampened" reading (else looks twitchy) // Calculate bar height based on dynamic min/max levels (fixed point): height = TOP * (lvl - minLvlAvg) / (long)(maxLvlAvg - minLvlAvg); if(height < 0L) height = 0; // Clip output else if(height > TOP) height = TOP; if(height > peak) peak = height; // Keep 'peak' dot at top // Color pixels based on rainbow gradient for(i=0; i<N_PIXELS_HALF; i++) { if(i >= height) { strip.setPixelColor(N_PIXELS_HALF-i-1, 0, 0, 0); strip.setPixelColor(N_PIXELS_HALF+i, 0, 0, 0); } else { uint32_t color = Wheel(map(i,0,N_PIXELS_HALF-1,30,150)); strip.setPixelColor(N_PIXELS_HALF-i-1,color); strip.setPixelColor(N_PIXELS_HALF+i,color); } } // Draw peak dot if(peak > 0 && peak <= N_PIXELS_HALF-1) { uint32_t color = Wheel(map(peak,0,N_PIXELS_HALF-1,30,150)); strip.setPixelColor(N_PIXELS_HALF-peak-1,color); strip.setPixelColor(N_PIXELS_HALF+peak,color); } strip.show(); // Update strip // Every few frames, make the peak pixel drop by 1: if(++dotCount >= PEAK_FALL) { //fall rate if(peak > 0) peak--; dotCount = 0; } vol[volCount] = n; // Save sample for dynamic leveling if(++volCount >= SAMPLES) volCount = 0; // Advance/rollover sample counter // Get volume range of prior frames minLvl = maxLvl = vol[0]; for(i=1; i<SAMPLES; i++) { if(vol[i] < minLvl) minLvl = vol[i]; else if(vol[i] > maxLvl) maxLvl = vol[i]; } // minLvl and maxLvl indicate the volume range over prior frames, used // for vertically scaling the output graph (so it looks interesting // regardless of volume level). If they're too close together though // (e.g. at very low volume levels) the graph becomes super coarse // and 'jumpy'...so keep some minimum distance between them (this // also lets the graph go to zero when no sound is playing): if((maxLvl - minLvl) < TOP) maxLvl = minLvl + TOP; minLvlAvg = (minLvlAvg * 63 + minLvl) >> 6; // Dampen min/max levels maxLvlAvg = (maxLvlAvg * 63 + maxLvl) >> 6; // (fake rolling average) } //here................ void ripple() { if (currentBg == nextBg) { nextBg = random(256); } else if (nextBg > currentBg) { currentBg++; } else { currentBg--; } for(uint16_t l = 0; l < N_PIXELS; l++) { leds[l] = CHSV(currentBg, 255, 50); // strip.setPixelColor(l, Wheel(currentBg, 0.1)); } if (step == -1) { center = random(N_PIXELS); color = random(256); step = 0; } if (step == 0) { leds[center] = CHSV(color, 255, 255); // strip.setPixelColor(center, Wheel(color, 1)); step ++; } else { if (step < maxSteps) { Serial.println(pow(fadeRate,step)); leds[wrap(center + step)] = CHSV(color, 255, pow(fadeRate, step)*255); // strip.setPixelColor(wrap(center + step), Wheel(color, pow(fadeRate, step))); leds[wrap(center - step)] = CHSV(color, 255, pow(fadeRate, step)*255); // strip.setPixelColor(wrap(center - step), Wheel(color, pow(fadeRate, step))); if (step > 3) { leds[wrap(center + step - 3)] = CHSV(color, 255, pow(fadeRate, step - 2)*255); // strip.setPixelColor(wrap(center + step - 3), Wheel(color, pow(fadeRate, step - 2))); leds[wrap(center - step + 3)] = CHSV(color, 255, pow(fadeRate, step - 2)*255); // strip.setPixelColor(wrap(center - step + 3), Wheel(color, pow(fadeRate, step - 2))); } step ++; } else { step = -1; } } LEDS.show(); delay(50); } int wrap(int step) { if(step < 0) return N_PIXELS + step; if(step > N_PIXELS - 1) return step - N_PIXELS; return step; } void one_color_allHSV(int ahue, int abright) { // SET ALL LEDS TO ONE COLOR (HSV) for (int i = 0 ; i < N_PIXELS; i++ ) { leds[i] = CHSV(ahue, 255, abright); } } void ripple2() { if (BG){ if (currentBg == nextBg) { nextBg = random(256); } else if (nextBg > currentBg) { currentBg++; } else { currentBg--; } for(uint16_t l = 0; l < N_PIXELS; l++) { strip.setPixelColor(l, Wheel(currentBg, 0.1)); } } else { for(uint16_t l = 0; l < N_PIXELS; l++) { strip.setPixelColor(l, 0, 0, 0); } } if (step == -1) { center = random(N_PIXELS); color = random(256); step = 0; } if (step == 0) { strip.setPixelColor(center, Wheel(color, 1)); step ++; } else { if (step < maxSteps) { strip.setPixelColor(wrap(center + step), Wheel(color, pow(fadeRate, step))); strip.setPixelColor(wrap(center - step), Wheel(color, pow(fadeRate, step))); if (step > 3) { strip.setPixelColor(wrap(center + step - 3), Wheel(color, pow(fadeRate, step - 2))); strip.setPixelColor(wrap(center - step + 3), Wheel(color, pow(fadeRate, step - 2))); } step ++; } else { step = -1; } } strip.show(); delay(50); } //int wrap(int step) { // if(step < 0) return Pixels + step; // if(step > Pixels - 1) return step - Pixels; // return step; //} // Input a value 0 to 255 to get a color value. // The colours are a transition r - g - b - back to r. uint32_t Wheel(byte WheelPos, float opacity) { if(WheelPos < 85) { return strip.Color((WheelPos * 3) * opacity, (255 - WheelPos * 3) * opacity, 0); } else if(WheelPos < 170) { WheelPos -= 85; return strip.Color((255 - WheelPos * 3) * opacity, 0, (WheelPos * 3) * opacity); } else { WheelPos -= 170; return strip.Color(0, (WheelPos * 3) * opacity, (255 - WheelPos * 3) * opacity); } } void pattern2() { sinelon(); // Call our sequence. show_at_max_brightness_for_power(); // Power managed display of LED's. } // loop() void sinelon() { // a colored dot sweeping back and forth, with fading trails fadeToBlackBy( leds, N_PIXELS, thisfade); int pos1 = beatsin16(thisbeat,0,N_PIXELS); int pos2 = beatsin16(thatbeat,0,N_PIXELS); leds[(pos1+pos2)/2] += CHSV( myhue++/64, thissat, thisbri); } // Pattern 3 - JUGGLE void pattern3() { ChangeMe(); juggle(); show_at_max_brightness_for_power(); // Power managed display of LED's. } // loop() void juggle() { // Several colored dots, weaving in and out of sync with each other curhue = thishue; // Reset the hue values. fadeToBlackBy(leds, N_PIXELS, faderate); for( int i = 0; i < numdots; i++) { leds[beatsin16(basebeat+i+numdots,0,N_PIXELS)] += CHSV(curhue, thissat, thisbright); //beat16 is a FastLED 3.1 function curhue += hueinc; } } // juggle() void ChangeMe() { // A time (rather than loop) based demo sequencer. This gives us full control over the length of each sequence. uint8_t secondHand = (millis() / 1000) % 30; // IMPORTANT!!! Change '30' to a different value to change duration of the loop. static uint8_t lastSecond = 99; // Static variable, means it's only defined once. This is our 'debounce' variable. if (lastSecond != secondHand) { // Debounce to make sure we're not repeating an assignment. lastSecond = secondHand; if (secondHand == 0) {numdots=1; faderate=2;} // You can change values here, one at a time , or altogether. if (secondHand == 10) {numdots=4; thishue=128; faderate=8;} if (secondHand == 20) {hueinc=48; thishue=random8();} // Only gets called once, and not continuously for the next several seconds. Therefore, no rainbows. } } // ChangeMe() void Twinkle () { if (random(25) == 1) { uint16_t i = random(N_PIXELS); if (redStates[i] < 1 && greenStates[i] < 1 && blueStates[i] < 1) { redStates[i] = random(256); greenStates[i] = random(256); blueStates[i] = random(256); } } for(uint16_t l = 0; l < N_PIXELS; l++) { if (redStates[l] > 1 || greenStates[l] > 1 || blueStates[l] > 1) { strip.setPixelColor(l, redStates[l], greenStates[l], blueStates[l]); if (redStates[l] > 1) { redStates[l] = redStates[l] * Fade; } else { redStates[l] = 0; } if (greenStates[l] > 1) { greenStates[l] = greenStates[l] * Fade; } else { greenStates[l] = 0; } if (blueStates[l] > 1) { blueStates[l] = blueStates[l] * Fade; } else { blueStates[l] = 0; } } else { strip.setPixelColor(l, 0, 0, 0); } } strip.show(); delay(10); } // TOO HERE void rainbow(uint8_t wait) { uint16_t i, j; for(j=0; j<256; j++) { for(i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, Wheel((i+j) & 255)); } strip.show(); // check if a button pressed if (digitalRead(buttonPin) != lastButtonState) // <------------- add this return; // <------------ and this delay(wait); } } |