terrag42

Flex Radiate (ESP8266)

Nov 25th, 2016
238
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.43 KB | None | 0 0
  1.  
  2. #define msg7RESET  5 //digital pin (no PWM)
  3. #define msg7Strobe 4 //digital pin (no PWM)
  4. #define msg7DCout 0 //voltage output from MSGEQ7 to Analog Pin 0
  5. #include "FastLED.h"                                          // FastLED library.
  6.  
  7. #if FASTLED_VERSION < 3001000
  8. #error "Requires FastLED 3.1 or later; check github for latest code."
  9. #endif
  10.  
  11. #define LED_DT 12                         // Data pin to connect to the strip.
  12. #define LED_CK 13
  13. #define COLOR_ORDER BGR                  // It's GRB for WS2812B and BGR for APA102.
  14. #define LED_TYPE APA102                 // What kind of strip are you using (WS2801, WS2812B or APA102)?
  15. #define NUM_LEDS 360                    // Number of LED's.
  16. #define HALF_NUM_LEDS 180               //Half the number of LEDs
  17. #define value_floor 0
  18. #define value_ceiling 255
  19. // Initialize changeable global variables.
  20. uint8_t max_bright = 200;         // Overall brightness definition. It can be changed on the fly.
  21.  
  22. CRGB leds[NUM_LEDS];  
  23. uint8_t brightness, saturation=255;
  24. float divFactor;
  25. float half_factor = 0.00f;
  26. int kMatrixWidth=25, kMatrixHeight=25;
  27.  
  28. uint16_t left[7], mono[7], mono_volume, half_mapped[7], left_value, right_value, half_MAPPED_AMPLITUDE;  
  29. uint8_t band;
  30.  
  31. int filter_min = 100; // eliminate msgeq7 noise
  32. int filter_max = 1023; //maximum value for analogRead()
  33.  
  34. // higher value for lowPass_audio means the animation is more responsive to audio,
  35. // BUT the brightness is less smooth, naturally. keep it lower to get that silky data goodness
  36. float lowPass_audio = 0.18f; // "f" is to just cut the floating integer off at 2 decimels
  37. // .18 is a good starting point for smoothing, I think. 0.14 starts to get less responsive
  38.  
  39. void setup() {
  40.    // initialize the digital pin as an output.
  41.   // Pin 13 has an LED connected on most Arduino boards:
  42.   LEDS.addLeds<LED_TYPE, LED_DT, LED_CK, COLOR_ORDER>(leds, NUM_LEDS);  // Use this for WS2801 or APA102
  43.   FastLED.setBrightness(max_bright);
  44.   set_max_power_in_volts_and_milliamps(5, 2500);
  45.   pinMode(msg7RESET, OUTPUT);
  46.   pinMode(msg7Strobe, OUTPUT);
  47.   Serial.begin(115200);
  48. }
  49.  
  50. void loop() {
  51.   ReadAudio();
  52.   flex_radiate();
  53. }
  54.  
  55. void ReadAudio() {
  56.  
  57.   half_factor = 0.00f;
  58.   mono_volume  = 0;
  59.  
  60.   digitalWrite(msg7RESET, HIGH); // reset the MSGEQ7
  61.   digitalWrite(msg7RESET, LOW);
  62.   delayMicroseconds(1);
  63.  
  64.   for (band = 0; band < 7; band++)
  65.   {
  66.     digitalWrite(msg7Strobe, LOW);
  67.     delayMicroseconds(35);
  68.  
  69.     uint16_t prev_value  = left[band]; // store what is now the PREVIOUS value for this band as prev_value
  70.     uint16_t left_value  = analogRead(msg7DCout); // store the CURRENT value for this band as a new variable
  71.    
  72.     // Map & constrain that raw value!
  73.     left_value  = constrain(left_value, filter_min, filter_max);
  74.     left_value  = map(left_value, filter_min, filter_max, value_floor, value_ceiling);
  75.  
  76.     //then smooth that thang out
  77.     left[band]  = prev_value + (left_value - prev_value) * lowPass_audio;
  78.  
  79.  
  80.     //If you have enough processing power/two msgeq7 chips like in the [Sparkfun spectrum shield](https://www.sparkfun.com/products/13116), read the other channel
  81.     //I've found that averaging both bands to mono inherently makes an animation smoother
  82. /*    prev_value  = right[band];
  83.     right_value = analogRead(right_in);
  84.     right_value = constrain(right_value, filter_min, filter_max);
  85.     right_value = map(right_value, filter_min, filter_max, value_floor, value_ceiling);
  86.     right[band] = prev_value + (right_value - prev_value) * lowPass_audio;
  87.  
  88.     // average to mono,
  89.     mono[band]  = (left[band] + right[band]) * 0.5;
  90.     // and add each  new mono band value to mono_volume, which is used to calculate the
  91.     // factor to multiply each band by below. this is how the stretching/contracting stuff works
  92.     // be sure to reset half_factor and mono_volume with each iteration
  93.     mono_volume += mono[band];
  94. */
  95.     mono[band] = left[band]; //added for non-stereo version to make the lines below work
  96.     mono_volume += mono[band];
  97.     digitalWrite(msg7Strobe, HIGH);
  98.     delayMicroseconds(1);
  99.   }
  100.  
  101.   // now that we have the sum of each band, average dat
  102.   mono_volume  /= 7;
  103.   //NOW, half_factor is important. Say I have 240 leds in total. Here I'm dividing
  104.   // half of that by mono_volume so that I can mirror the effect on both sides of the lamp
  105.   // say the average volume is 100 in this current cycle, and I have 120 leds on both sides.
  106.   // 120/100 is 1.2
  107.   // in the following loop, I basically multiply each megeq7 band value by 1.2 so that
  108.   // all leds are filled with the msgeq7 data, but the bands that are not as loud don't stretch as far.
  109.   // hope that makes sense
  110.   half_factor = HALF_NUM_LEDS / mono_volume;
  111.  
  112.  
  113.   // here is where the length of each band is calculated by multiplying the band
  114.   // by that "1.2" variable above (which onbiously changes with each iteration)
  115.   // if you were to print these values to the serial monitor, they would all
  116.   // add up to HALF_NUM_LEDS.
  117.   for (band = 0; band < 7; band++){
  118.     half_MAPPED_AMPLITUDE = mono[band] * half_factor;
  119.     half_mapped[band] = half_MAPPED_AMPLITUDE;
  120.  /*   Serial.print("half_mapped[band]  ");
  121.     Serial.println(half_mapped[band]);
  122.     Serial.print("Mono[band]  ");
  123.     Serial.println(mono[band]); */
  124.   }
  125. // print the audio if you want
  126. //#ifdef PRINT_AUDIO
  127. //  printAudio();
  128. //#endif
  129.  
  130. }
  131.  
  132. void flex_radiate() {
  133.   uint16_t segment, ledindex, cnt, hue;
  134.   uint8_t k=0;
  135.  // ReadAudio();
  136.   //ledindex = HALF_POS; //I didn't know what HALF_POS was, it sounded like the halfway point in the LED strip.
  137.   ledindex = HALF_NUM_LEDS;
  138.   for (band = 0; band < 7; band++) {
  139.     k = (band + 1) % 7; // doesn't work perfectly, but serves as a value for the NEXT band number
  140.     half_MAPPED_AMPLITUDE = half_mapped[band];
  141.     // there is a lot of math here that helps smooth brightness values
  142.     // at the EDGES of each band on the led strip, so it doesn't immediately go from one color to another
  143.     // this helps a TON for having it wrapped around a tube
  144.    divFactor = 1.0f / half_MAPPED_AMPLITUDE;
  145.     // segment is a variable (declare it somewhere) for FINAL led number of each band, with ledindex
  146.     // indicating the START of each band. it is incremented after each cycle
  147.     segment = half_MAPPED_AMPLITUDE + ledindex;
  148.     hue = band * 35; // or whatever you want. just determines how much of the hue spectrum fits on the strip
  149.     //hue += mono[0] * 0.01;
  150.  Serial.print(" Segment ");
  151.  Serial.println(segment); //for debugging
  152.     for (uint16_t index = ledindex; index < segment; index++) {
  153.       brightness = (mono[band] * (half_MAPPED_AMPLITUDE - cnt) * divFactor) + (mono[k] * cnt * divFactor);
  154.       //brightness = map(brightness, 0, 255, 100, 255);
  155.       leds[index] = CHSV(hue, saturation, brightness);
  156.       // to mirror to the bottom half of the strip
  157.     //leds[HALF_POS - (index - HALF_POS)] = CHSV(hue, saturation, brightness);
  158.       leds[HALF_NUM_LEDS - (index - HALF_NUM_LEDS)] = CHSV(hue, saturation, brightness);
  159.       cnt++;
  160.     }
  161.     cnt = 0;
  162.     ledindex += half_MAPPED_AMPLITUDE;
  163.   }
  164.   Serial.print(" mono ");
  165.   Serial.print(mono[band]); //for debugging
  166.   Serial.print(" Half_M_A  ");
  167.   Serial.print(half_MAPPED_AMPLITUDE);
  168.   Serial.print(" divF ");
  169.   Serial.println(divFactor);
  170.  
  171.   // ehhh, blur it. why not.
  172.  // blur2d(leds, kMatrixWidth, kMatrixHeight, 100); //couldn't get it to compile with this in. the error was: "undefined reference to `XY(unsigned char, unsigned char)'"
  173.   FastLED.show();
  174. }
Advertisement
Add Comment
Please, Sign In to add comment