Advertisement
atuline

demoreel100_sound.ino

Jan 8th, 2022
1,252
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.43 KB | None | 0 0
  1. /*
  2.   Sound Reactive demoreel100  (no longer 100)
  3.  
  4.   Date: Jan, 2022
  5.  
  6.   Originally by: Mark Kriegsman
  7.  
  8.   Modification by: Andrew Tuline
  9.  
  10.   Running on an Arduino Nano, this sketch demonstrates the ability to add sound reactivity to non-reactive FastLED animations without modifying their code.
  11.   It does so by blending the results of the existing (and unmodified animation) with the results of the sound reactive code prior to calling FastLED.show().
  12.  
  13.   The concept here is to take away brightness instead of adding it.
  14.  
  15.   This version has been developed around an Arduino Nano (old bootloader), with a MAX9814 microphone @40db gain.
  16.  
  17.   I've connected the AREF pin to 3.3V and connected VCC of the microphone to 3.3V as well.
  18.  
  19. */
  20.  
  21.  
  22. #include <FastLED.h>
  23.  
  24.  
  25. // --------- Sound --------------
  26. #define MIC_PIN   A5                                          // Analog port for microphone
  27. uint8_t squelch = 20;                                         // Anything below this is background noise, so we'll make it '0'.
  28. int sample;                                                   // Current sample.
  29. float sampleAvg = 0;                                          // Smoothed Average.
  30. float micLev = 0;                                             // Used to convert returned value to have '0' as minimum.
  31.  
  32. int sampleAgc;                                                // Automatic Gain Controlled value.
  33. int multAgc;                                                  // Multiplier for the AGC.
  34. uint8_t targetAgc = 60;                                       // This is our setPoint at 20% of max for the adjusted output.
  35.  
  36.  
  37.  
  38. // -------- FastLED --------------
  39. #define LED_DT 12
  40. #define COLOR_ORDER GRB
  41. #define LED_TYPE WS2812
  42. #define NUM_LEDS 64
  43.  
  44. struct CRGB leds[NUM_LEDS];
  45.  
  46. uint8_t vals[NUM_LEDS];                                       // Used for sound reactivity blending.
  47.  
  48.  
  49.  
  50. void setup() {
  51.   Serial.begin(115200);
  52.   analogReference(EXTERNAL);                                  // Nano or other 5V AVR when using a 3.3V microphone. Also connect AREF pin to 3.3V.
  53.   LEDS.addLeds<LED_TYPE, LED_DT, COLOR_ORDER>(leds, NUM_LEDS);
  54.   FastLED.setBrightness(128);
  55. } // setup()
  56.  
  57.  
  58. // List of patterns to cycle through.  Each is defined as a separate function below.
  59. typedef void (*SimplePatternList[])();
  60.  
  61. SimplePatternList gPatterns = { rainbow, rainbowWithGlitter, confetti, sinelon, juggle, bpm };
  62.  
  63. uint8_t gCurrentPatternNumber = 0; // Index number of which pattern is current
  64. uint8_t gHue = 0; // rotating "base color" used by many of the patterns
  65.  
  66.  
  67.  
  68. void loop() {
  69.  
  70.   getSample();                        // Sample the microphone.
  71.   agcAvg();                           // Calculated the AGC average.
  72.  
  73.  
  74.   gPatterns[gCurrentPatternNumber]();
  75.  
  76.   EVERY_N_MILLISECONDS( 20 ) {
  77.     gHue++;  // slowly cycle the "base color" through the rainbow
  78.   }
  79.   EVERY_N_SECONDS( 10 ) {
  80.     nextPattern();  // change patterns periodically
  81.   }
  82.  
  83.   soundAdjust();                      // Insert sound reactive modfications before displaying.
  84.  
  85.   FastLED.show();                     // Display.
  86.  
  87. } // loop()
  88.  
  89.  
  90.  
  91. void soundAdjust() {
  92.  
  93.   vals[millis() % NUM_LEDS] = sampleAgc;              // This requires a high refresh rate.
  94.  
  95.   for (int i = 0; i < NUM_LEDS; i++) {                // Modifying the array prior to FastLED.show().
  96.     leds[i] = blend(CRGB::Black, leds[i], vals[i]);   // vals[i] is a uint8_t, which determines the blending between the two colours for the resultant value.
  97.   }
  98.  
  99. } // soundAdjust()
  100.  
  101.  
  102. #define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
  103.  
  104. void nextPattern() {
  105.   gCurrentPatternNumber = (gCurrentPatternNumber + 1) % ARRAY_SIZE( gPatterns);
  106. }
  107.  
  108.  
  109.  
  110. void rainbow()
  111. {
  112.   // FastLED's built-in rainbow generator
  113.   fill_rainbow( leds, NUM_LEDS, gHue, 7);
  114. }
  115.  
  116.  
  117. void rainbowWithGlitter()
  118. {
  119.   // built-in FastLED rainbow, plus some random sparkly glitter
  120.   rainbow();
  121.   addGlitter(80);
  122. }
  123.  
  124.  
  125. void addGlitter( fract8 chanceOfGlitter)
  126. {
  127.   if ( random8() < chanceOfGlitter) {
  128.     leds[ random16(NUM_LEDS) ] += CRGB::White;
  129.   }
  130. }
  131.  
  132.  
  133. void confetti()
  134. {
  135.   // random colored speckles that blink in and fade smoothly
  136.   fadeToBlackBy( leds, NUM_LEDS, 10);
  137.   int pos = random16(NUM_LEDS);
  138.   leds[pos] += CHSV( gHue + random8(64), 200, 255);
  139. }
  140.  
  141.  
  142. void sinelon()
  143. {
  144.   // a colored dot sweeping back and forth, with fading trails
  145.   fadeToBlackBy( leds, NUM_LEDS, 20);
  146.   int pos = beatsin16( 13, 0, NUM_LEDS - 1 );
  147.   leds[pos] += CHSV( gHue, 255, 192);
  148. }
  149.  
  150.  
  151. void bpm()
  152. {
  153.   // colored stripes pulsing at a defined Beats-Per-Minute (BPM)
  154.   uint8_t BeatsPerMinute = 62;
  155.   CRGBPalette16 palette = PartyColors_p;
  156.   uint8_t beat = beatsin8( BeatsPerMinute, 64, 255);
  157.   for ( int i = 0; i < NUM_LEDS; i++) { //9948
  158.     leds[i] = ColorFromPalette(palette, gHue + (i * 2), beat - gHue + (i * 10));
  159.   }
  160. }
  161.  
  162.  
  163. void juggle() {
  164.   // eight colored dots, weaving in and out of sync with each other
  165.   fadeToBlackBy( leds, NUM_LEDS, 20);
  166.   uint8_t dothue = 0;
  167.   for ( int i = 0; i < 8; i++) {
  168.     leds[beatsin16( i + 7, 0, NUM_LEDS - 1 )] |= CHSV(dothue, 200, 255);
  169.     dothue += 32;
  170.   }
  171. }
  172.  
  173.  
  174.  
  175. void getSample() {
  176.  
  177.   int16_t micIn;                                              // Current sample starts with negative values and large values, which is why it's 16 bit signed.
  178.  
  179.   micIn = analogRead(MIC_PIN);                                // Poor man's analog read.
  180.   micLev = ((micLev * 31) + micIn) / 32;                      // Use exponential smoothing over the last 32 samples for automatic centering.
  181.   micIn -= micLev;                                            // Let's center it to 0. This allows us to use ANY microphone without having to worry about offset calculations.
  182.   micIn = abs(micIn);                                         // And get the absolute value of each sample.
  183.  
  184.   sample = (micIn <= squelch) ? 0 : (sample + micIn) / 2;     // Let's filter out the background noise with a ternary operator and more exponential smoothing.
  185.   sampleAvg = ((sampleAvg * 31) + sample) / 32;               // Smooth it out over the last 32 samples. This is a non AGC average.
  186.  
  187. } // getSample()
  188.  
  189.  
  190.  
  191. void agcAvg() {                                                   // A simple averaging multiplier to automatically adjust sound sensitivity.
  192.   multAgc = (sampleAvg < 1) ? targetAgc : targetAgc / sampleAvg;  // Make the multiplier so that sampleAvg * multiplier = setpoint
  193.   sampleAgc = sample * multAgc;
  194.   if (sampleAgc > 255) sampleAgc = 255;
  195. } // agcAvg()
  196.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement