0

VU meter peak hold principle for Adafruit RGB LEDs and strip
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

VU meter peak hold principle for Adafruit RGB LEDs and strip

by Systembolaget on Sun Dec 05, 2021 4:08 pm

Thought to drop the proper minimal code for "peak hold" VU meter style projects after a fun experiment with the noise in a London underground station. Of course, the input could be any kind of noise, like aircraft, motorway, classroom mayhem or... music ; )

The GitHub repo has a link to the complete code, a graphic explanation of the "peak hold" principle, and a link to a video of the whole shebang in action https://github.com/systembolaget/Physic ... dafruit-IO and it's easy do adapt for larger rings or strips, or change the colours via a FastLED palette.

I hope it's as helpful as the colour sensing tutorial https://learn.adafruit.com/adafruit-col ... ing-colors from a while ago.

Code: Select all | TOGGLE FULL SIZE
void loop()
{
  // Other things that happen in loop() go here

  // The three following blocks of code contain the peak hold and
  // peak decay logic, based on a hold and a decay interval

  // If the new peak value is higher than the previous peak value
  if (newPeak >= previousPeak)
  {
    previousPeak = newPeak; // Set the previous peak value to the new peak value

    timePeak = millis(); // And take a timestamp of when that happened

    brightnessPeak = ledBrightness; // Then set the peak LED's brightness to that of all LEDs

    decay = false; // And set the decay flag to false to hold the peak LED in the current position on the ring
  }

  // If the peak LED is not decaying and the peak hold interval (here 900 ms) has expired
  else if (!decay && (millis() - timePeak >= intervalPeakHold))
  {
    timePeak += intervalPeakHold; // Add the expired interval to the timestamp

    decay = true; // And set the peak LED to decay, so its position on the ring and its brightness can change
  }

  // If the peak LED is set to decay and a decay interval (here 50 ms) has passed
  else if (decay && (millis() - timePeak > intervalPeakDecay))
  {
    // And only while the peak LED has not yet dropped to position zero the ring
    if (previousPeak > 0)
    {
      previousPeak --; // Lower the peak LED's position on the ring by one

      // If the peak LED's brightness has dropped to or below zero
      if (brightnessPeak <= 0)
      {
        brightnessPeak = 0; // Then keep it off
      }

      // If the peak LED's brightness has not yet dropped to zero
      else
      {
        brightnessPeak -= 16; // Then reduce the peak LED's brightness
      }

      timePeak += intervalPeakDecay; // And add the expired decay interval to the timestamp
    }
  }

  // Clear the LED array that holds all LED's colour and brightnesss data
  FastLED.clear();

  for ( byte i = 0; i <= newPeak; i++)
    // And depending on the new peak value (= number of LEDs to light)
  {
    // Copy the corresponding colour from the gradient array to the LED array
    ledRing[i] = ledGradient[i];
  }

  // And also set the peak hold LED's colour and brightness
  ledRing[previousPeak] = CHSV(0, 255, brightnessPeak); // Red

  // Then display all LED's data on the ring
  FastLED.show();
}

Systembolaget
 
Posts: 289
Joined: Wed Mar 08, 2017 1:01 pm

Please be positive and constructive with your questions and comments.