Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define msg7RESET 5 //digital pin (no PWM)
- #define msg7Strobe 4 //digital pin (no PWM)
- #define msg7DCout 0 //voltage output from MSGEQ7 to Analog Pin 0
- #include "FastLED.h" // FastLED library.
- #if FASTLED_VERSION < 3001000
- #error "Requires FastLED 3.1 or later; check github for latest code."
- #endif
- #define LED_DT 12 // Data pin to connect to the strip.
- #define LED_CK 13
- #define COLOR_ORDER BGR // It's GRB for WS2812B and BGR for APA102.
- #define LED_TYPE APA102 // What kind of strip are you using (WS2801, WS2812B or APA102)?
- #define NUM_LEDS 360 // Number of LED's.
- #define HALF_NUM_LEDS 180 //Half the number of LEDs
- #define value_floor 0
- #define value_ceiling 255
- // Initialize changeable global variables.
- uint8_t max_bright = 200; // Overall brightness definition. It can be changed on the fly.
- CRGB leds[NUM_LEDS];
- uint8_t brightness, saturation=255;
- float divFactor;
- float half_factor = 0.00f;
- int kMatrixWidth=25, kMatrixHeight=25;
- uint16_t left[7], mono[7], mono_volume, half_mapped[7], left_value, right_value, half_MAPPED_AMPLITUDE;
- uint8_t band;
- int filter_min = 100; // eliminate msgeq7 noise
- int filter_max = 1023; //maximum value for analogRead()
- // higher value for lowPass_audio means the animation is more responsive to audio,
- // BUT the brightness is less smooth, naturally. keep it lower to get that silky data goodness
- float lowPass_audio = 0.18f; // "f" is to just cut the floating integer off at 2 decimels
- // .18 is a good starting point for smoothing, I think. 0.14 starts to get less responsive
- void setup() {
- // initialize the digital pin as an output.
- // Pin 13 has an LED connected on most Arduino boards:
- LEDS.addLeds<LED_TYPE, LED_DT, LED_CK, COLOR_ORDER>(leds, NUM_LEDS); // Use this for WS2801 or APA102
- FastLED.setBrightness(max_bright);
- set_max_power_in_volts_and_milliamps(5, 2500);
- pinMode(msg7RESET, OUTPUT);
- pinMode(msg7Strobe, OUTPUT);
- Serial.begin(115200);
- }
- void loop() {
- ReadAudio();
- flex_radiate();
- }
- void ReadAudio() {
- half_factor = 0.00f;
- mono_volume = 0;
- digitalWrite(msg7RESET, HIGH); // reset the MSGEQ7
- digitalWrite(msg7RESET, LOW);
- delayMicroseconds(1);
- for (band = 0; band < 7; band++)
- {
- digitalWrite(msg7Strobe, LOW);
- delayMicroseconds(35);
- uint16_t prev_value = left[band]; // store what is now the PREVIOUS value for this band as prev_value
- uint16_t left_value = analogRead(msg7DCout); // store the CURRENT value for this band as a new variable
- // Map & constrain that raw value!
- left_value = constrain(left_value, filter_min, filter_max);
- left_value = map(left_value, filter_min, filter_max, value_floor, value_ceiling);
- //then smooth that thang out
- left[band] = prev_value + (left_value - prev_value) * lowPass_audio;
- //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
- //I've found that averaging both bands to mono inherently makes an animation smoother
- /* prev_value = right[band];
- right_value = analogRead(right_in);
- right_value = constrain(right_value, filter_min, filter_max);
- right_value = map(right_value, filter_min, filter_max, value_floor, value_ceiling);
- right[band] = prev_value + (right_value - prev_value) * lowPass_audio;
- // average to mono,
- mono[band] = (left[band] + right[band]) * 0.5;
- // and add each new mono band value to mono_volume, which is used to calculate the
- // factor to multiply each band by below. this is how the stretching/contracting stuff works
- // be sure to reset half_factor and mono_volume with each iteration
- mono_volume += mono[band];
- */
- mono[band] = left[band]; //added for non-stereo version to make the lines below work
- mono_volume += mono[band];
- digitalWrite(msg7Strobe, HIGH);
- delayMicroseconds(1);
- }
- // now that we have the sum of each band, average dat
- mono_volume /= 7;
- //NOW, half_factor is important. Say I have 240 leds in total. Here I'm dividing
- // half of that by mono_volume so that I can mirror the effect on both sides of the lamp
- // say the average volume is 100 in this current cycle, and I have 120 leds on both sides.
- // 120/100 is 1.2
- // in the following loop, I basically multiply each megeq7 band value by 1.2 so that
- // all leds are filled with the msgeq7 data, but the bands that are not as loud don't stretch as far.
- // hope that makes sense
- half_factor = HALF_NUM_LEDS / mono_volume;
- // here is where the length of each band is calculated by multiplying the band
- // by that "1.2" variable above (which onbiously changes with each iteration)
- // if you were to print these values to the serial monitor, they would all
- // add up to HALF_NUM_LEDS.
- for (band = 0; band < 7; band++){
- half_MAPPED_AMPLITUDE = mono[band] * half_factor;
- half_mapped[band] = half_MAPPED_AMPLITUDE;
- /* Serial.print("half_mapped[band] ");
- Serial.println(half_mapped[band]);
- Serial.print("Mono[band] ");
- Serial.println(mono[band]); */
- }
- // print the audio if you want
- //#ifdef PRINT_AUDIO
- // printAudio();
- //#endif
- }
- void flex_radiate() {
- uint16_t segment, ledindex, cnt, hue;
- uint8_t k=0;
- // ReadAudio();
- //ledindex = HALF_POS; //I didn't know what HALF_POS was, it sounded like the halfway point in the LED strip.
- ledindex = HALF_NUM_LEDS;
- for (band = 0; band < 7; band++) {
- k = (band + 1) % 7; // doesn't work perfectly, but serves as a value for the NEXT band number
- half_MAPPED_AMPLITUDE = half_mapped[band];
- // there is a lot of math here that helps smooth brightness values
- // at the EDGES of each band on the led strip, so it doesn't immediately go from one color to another
- // this helps a TON for having it wrapped around a tube
- divFactor = 1.0f / half_MAPPED_AMPLITUDE;
- // segment is a variable (declare it somewhere) for FINAL led number of each band, with ledindex
- // indicating the START of each band. it is incremented after each cycle
- segment = half_MAPPED_AMPLITUDE + ledindex;
- hue = band * 35; // or whatever you want. just determines how much of the hue spectrum fits on the strip
- //hue += mono[0] * 0.01;
- Serial.print(" Segment ");
- Serial.println(segment); //for debugging
- for (uint16_t index = ledindex; index < segment; index++) {
- brightness = (mono[band] * (half_MAPPED_AMPLITUDE - cnt) * divFactor) + (mono[k] * cnt * divFactor);
- //brightness = map(brightness, 0, 255, 100, 255);
- leds[index] = CHSV(hue, saturation, brightness);
- // to mirror to the bottom half of the strip
- //leds[HALF_POS - (index - HALF_POS)] = CHSV(hue, saturation, brightness);
- leds[HALF_NUM_LEDS - (index - HALF_NUM_LEDS)] = CHSV(hue, saturation, brightness);
- cnt++;
- }
- cnt = 0;
- ledindex += half_MAPPED_AMPLITUDE;
- }
- Serial.print(" mono ");
- Serial.print(mono[band]); //for debugging
- Serial.print(" Half_M_A ");
- Serial.print(half_MAPPED_AMPLITUDE);
- Serial.print(" divF ");
- Serial.println(divFactor);
- // ehhh, blur it. why not.
- // 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)'"
- FastLED.show();
- }
Advertisement
Add Comment
Please, Sign In to add comment