Prinzip Geräuschmonitor (U-Bahn Station) mit peak hold und decay. Die peak LED geht nicht aus. Ein - 1 wie bei den "eigentlichen LEDs" newPeak = constrain(map(audioFiltered, 10, 200, 0, ledCount), 0, ledCount) - 1; geht nicht, da die peak LED dann vorlaufen würde. Was muß ich ändern? Sehe den Wald vor Bäumen nicht.
#include "FastLED.h"
const byte pinData = 6;
const int timeIntervalSampling = 40; // Sample window Breite (50 ms wäre 20Hz)
const int levelShift = 512;
const byte ledCount = 24;
const byte ledBrightness = 255;
struct CRGB ledRing[ledCount];
struct CRGB ledGradient[ledCount];
CHSV gradientHueStart = CHSV(96, 255, 255);
CHSV grandientHueEnd = CHSV(0, 255, 255);
int audioInRaw;
int audioInRectified;
float audioFiltered;
const int intervalPeakHold = 600;
const byte intervalPeakDecay = 20;
int newPeak;
int previousPeak;
unsigned long timeOfPeak; // Zeitstempel
bool peakDecay = false;
byte peakBrightness;
float peakBrightnessDecay;
void setup()
{
Serial.begin(115200);
FastLED.addLeds<NEOPIXEL, pinData>(ledRing, ledCount);
FastLED.setBrightness(ledBrightness);
fill_gradient(ledGradient, 0, gradientHueStart, ledCount, grandientHueEnd, SHORTEST_HUES);
}
void loop()
{
unsigned long timeSamplingStart = millis();
uint16_t audioPeakToPeak = 0;
uint16_t audioMin = 1023;
uint16_t audioMax = 0;
while (millis() - timeSamplingStart < timeIntervalSampling)
{
audioInRaw = analogRead(0);
audioInRectified = abs(audioInRaw - levelShift);
audioMin = min(audioInRectified, audioMin);
audioMax = max(audioInRectified, audioMax);
}
audioPeakToPeak = audioMax - audioMin;
if (audioPeakToPeak <= 5) // Kann später weg
audioPeakToPeak = 0;
audioFiltered = 0.8 * audioFiltered + (1 - 0.8) * audioPeakToPeak; // Leaky integrator, schnelles attack, langsameres decay
// 10 und 200 sind magic numbers, muß später mit auto-range weg
newPeak = constrain(map(audioFiltered, 10, 200, 0, ledCount), 0, ledCount) - 1;
if (newPeak >= previousPeak)
{
previousPeak = newPeak;
timeOfPeak = millis();
peakDecay = false;
peakBrightness = 255;
}
else if (!peakDecay && (millis() - timeOfPeak > intervalPeakHold))
{
peakDecay = true;
timeOfPeak += intervalPeakHold - intervalPeakDecay;
}
else if (peakDecay && (millis() - timeOfPeak > intervalPeakDecay))
{
if (previousPeak > 0)
{
previousPeak--;
timeOfPeak += intervalPeakDecay;
}
}
FastLED.clear();
for ( byte i = 0; i <= newPeak; i++)
{
ledRing[i] = ledGradient[i];
}
ledRing[previousPeak] = CHSV(0, 255, peakBrightness);
FastLED.show();
}