Finishing off my sound reactive LED code

Hey there,

I am pretty much complete with my project. The last thing I want to do is change my coding so that my LEDs all react to sound in general, or lower frequencies, like bass and drums etc. At the moment the code that I’m using pretty much makes it a VU meter. I’m using an adafruit Flora as the controller and there are three strips attached to that. Like I said it all works, but I’m so code illiterate, it isn’t funny, and the research I’ve been doing for the past week has lead me to nothing better. Would appreciate any push in the right direction.

Thanks

Jack

This is the code in case the attachment doesn’t work:

/* LED “Color Organ” for Adafruit Trinket and NeoPixel LEDs.

Hardware requirements:

  • Adafruit Trinket or Gemma mini microcontroller (ATTiny85).
  • Adafruit Electret Microphone Amplifier (ID: 1063)
  • Several Neopixels, you can mix and match
    o Adafruit Flora RGB Smart Pixels (ID: 1260)
    o Adafruit NeoPixel Digital LED strip (ID: 1138)
    o Adafruit Neopixel Ring (ID: 1463)

Software requirements:

  • Adafruit NeoPixel library

Connections:

  • 5 V to mic amp +
  • GND to mic amp -
  • Analog pinto microphone output (configurable below)
  • Digital pin to LED data input (configurable below)

Written by Adafruit Industries. Distributed under the BSD license.
This paragraph must be included in any redistribution.
*/
#include <Adafruit_NeoPixel.h>

#define N_PIXELS 60 // Number of pixels you are using
#define MIC_PIN 10 // Microphone is attached to FLORA GPIO d10(A10)
#define LED_PIN_1 6 // NeoPixel LED strand is connected to GPIO D6
#define LED_PIN_2 12 // NeoPixel LED strand is connected to GPIO D13
#define LED_PIN_3 9 // NeoPixel LED strand is connected to GPIO D9
#define DC_OFFSET 0 // DC offset in mic signal - if unusure, leave 0
#define NOISE 100 // Noise/hum/interference in mic signal
#define SAMPLES 60 // Length of buffer for dynamic level adjustment
#define TOP (N_PIXELS +1) // Allow dot to go slightly off scale
// Comment out the next line if you do not want brightness control or have a Gemma
//#define POT_PIN 3 // if defined, a potentiometer is on GPIO #3 (A3, Trinket only)

byte
peak = 0, // Used for falling dot
dotCount = 0, // Frame counter for delaying dot-falling speed
volCount = 0; // Frame counter for storing past volume data

int
vol[SAMPLES], // Collection of prior volume samples
lvl = 10, // Current “dampened” audio level
minLvlAvg = 0, // For dynamic adjustment of graph low & high
maxLvlAvg = 512;

Adafruit_NeoPixel strip1 = Adafruit_NeoPixel(N_PIXELS, LED_PIN_1, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip2 = Adafruit_NeoPixel(N_PIXELS, LED_PIN_2, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip3 = Adafruit_NeoPixel(N_PIXELS, LED_PIN_3, NEO_GRB + NEO_KHZ800);

void setup() {
memset(vol, 0, sizeof(vol));
strip1.begin();
strip2.begin();
strip3.begin();
}
void loop() {
uint8_t i;
uint16_t minLvl, maxLvl;
int n, height;
n = analogRead(MIC_PIN); // Raw reading from mic
n = abs(n - 512 - DC_OFFSET); // Center on zero
n = (n <= NOISE) ? 0 : (n - NOISE); // Remove noise/hum
lvl = ((lvl * 7) + n) >> 3; // “Dampened” reading (else looks twitchy)

// Calculate bar height based on dynamic min/max levels (fixed point):
height = TOP * (lvl - minLvlAvg) / (long)(maxLvlAvg - minLvlAvg);

if(height < 0L) height = 0; // Clip output
else if(height > TOP) height = TOP;
if(height > peak) peak = height; // Keep ‘peak’ dot at top

// if POT_PIN is defined, we have a potentiometer on GPIO #3 on a Trinket
// (Gemma doesn’t have this pin)
uint8_t bright = 255;
#ifdef POT_PIN
bright = analogRead(POT_PIN); // Read pin (0-255) (adjust potentiometer
// to give 0 to Vcc volts
#endif
strip1.setBrightness(bright); // Set LED brightness (if POT_PIN at top
// define commented out, will be full)
strip2.setBrightness(bright); // Set LED brightness
strip3.setBrightness(bright); // Set LED brightness

// Color pixels based on rainbow gradient
for(i=0; i<N_PIXELS; i++) {
if(i >= height) {
strip1.setPixelColor(i, 0, 0, 0);
strip2.setPixelColor(i, 0, 0, 0);
strip3.setPixelColor(i, 0, 0, 0);
}
else {
uint32_t color = Wheel(map(i,0,strip1.numPixels()-1,30,150));
strip1.setPixelColor(i,color);
strip2.setPixelColor(i,color);
strip3.setPixelColor(i,color);
}
}

strip1.show(); // Update strip
strip2.show(); // Update strip
strip3.show(); // Update strip

vol[volCount] = n; // Save sample for dynamic leveling
if(++volCount >= SAMPLES) volCount = 0; // Advance/rollover sample counter

// Get volume range of prior frames
minLvl = maxLvl = vol[0];
for(i=1; i<SAMPLES; i++) {
if(vol < minLvl) minLvl = vol*;*
else if(vol > maxLvl) maxLvl = vol*;*
* }*
* // minLvl and maxLvl indicate the volume range over prior frames, used*
* // for vertically scaling the output graph (so it looks interesting*
* // regardless of volume level). If they’re too close together though*
* // (e.g. at very low volume levels) the graph becomes super coarse*
* // and ‘jumpy’…so keep some minimum distance between them (this*
* // also lets the graph go to zero when no sound is playing):*
* if((maxLvl - minLvl) < TOP) maxLvl = minLvl + TOP;*
_ minLvlAvg = (minLvlAvg * 63 + minLvl) >> 6; // Dampen min/max levels_
_ maxLvlAvg = (maxLvlAvg * 63 + maxLvl) >> 6; // (fake rolling average)
}
// Input a value 0 to 255 to get a color value.
// The colors are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
* if(WheelPos < 85) {
return strip1.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
} else if(WheelPos < 170) {
WheelPos -= 85;
return strip1.Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return strip1.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
}_

LED_volume_meter.ino (5.37 KB)*

Look at you code as posted. Does it look the same as it does in the IDE ? I am willing to bet that it doesn't because the forum software has turned some of it into italics and hidden the array indices where you used i as the index. Using code tags would stop that happening and also make it easier to read you program and copy it to an editor or the IDE to help with your question/problem.

You can add code tags by selecting the text to be tagged and clicking the 7th icon from the right above the smileys in the reply editor.

UKHeliBob:
Look at you code as posted. Does it look the same as it does in the IDE ? I am willing to bet that it doesn't because the forum software has turned some of it into italics and hidden the array indices where you used i as the index. Using code tags would stop that happening and also make it easier to read you program and copy it to an editor or the IDE to help with your question/problem.

You can add code tags by selecting the text to be tagged and clicking the 7th icon from the right above the smileys in the reply editor.

Ok thanks man, I might try that.
But yeah thats copy/pasted exactly from the IDE.
All the italics are on the IDE too.

All the italics are on the IDE too.

I find that very hard to believe. Which version of the IDE are you using ?

I’m using 1.0.6

There are no italics in the code in your screenshot.
Look at all the lines after this in your original post

for(i=1; i<SAMPLES; i++) {

Oh wow, I am an absolute retard haha!
Ok now I get what you’re saying.

/* LED "Color Organ" for Adafruit Trinket and NeoPixel LEDs.

Hardware requirements:
 - Adafruit Trinket or Gemma mini microcontroller (ATTiny85).
 - Adafruit Electret Microphone Amplifier (ID: 1063)
 - Several Neopixels, you can mix and match
   o Adafruit Flora RGB Smart Pixels (ID: 1260)
   o Adafruit NeoPixel Digital LED strip (ID: 1138)
   o Adafruit Neopixel Ring (ID: 1463)

Software requirements:
 - Adafruit NeoPixel library

Connections:
 - 5 V to mic amp +
 - GND to mic amp -
 - Analog pinto microphone output (configurable below)
 - Digital pin to LED data input (configurable below)

Written by Adafruit Industries.  Distributed under the BSD license.
This paragraph must be included in any redistribution.
*/
#include <Adafruit_NeoPixel.h>

#define N_PIXELS  60  // Number of pixels you are using
#define MIC_PIN   10  // Microphone is attached to FLORA GPIO d10(A10)
#define LED_PIN_1  6  // NeoPixel LED strand is connected to GPIO D6
#define LED_PIN_2 12  // NeoPixel LED strand is connected to GPIO D13
#define LED_PIN_3  9  // NeoPixel LED strand is connected to GPIO D9
#define DC_OFFSET  0  // DC offset in mic signal - if unusure, leave 0
#define NOISE     100  // Noise/hum/interference in mic signal
#define SAMPLES   60  // Length of buffer for dynamic level adjustment
#define TOP       (N_PIXELS +1) // Allow dot to go slightly off scale
// Comment out the next line if you do not want brightness control or have a Gemma
//#define POT_PIN    3  // if defined, a potentiometer is on GPIO #3 (A3, Trinket only) 

byte
  peak      = 0,      // Used for falling dot
  dotCount  = 0,      // Frame counter for delaying dot-falling speed
  volCount  = 0;      // Frame counter for storing past volume data
  
int
  vol[SAMPLES],       // Collection of prior volume samples
  lvl       = 10,     // Current "dampened" audio level
  minLvlAvg = 0,      // For dynamic adjustment of graph low & high
  maxLvlAvg = 512;

Adafruit_NeoPixel  strip1 = Adafruit_NeoPixel(N_PIXELS, LED_PIN_1, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel  strip2 = Adafruit_NeoPixel(N_PIXELS, LED_PIN_2, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel  strip3 = Adafruit_NeoPixel(N_PIXELS, LED_PIN_3, NEO_GRB + NEO_KHZ800);

void setup() {
  memset(vol, 0, sizeof(vol));
  strip1.begin();
  strip2.begin();
  strip3.begin();
}
void loop() {
  uint8_t  i;
  uint16_t minLvl, maxLvl;
  int      n, height;
  n   = analogRead(MIC_PIN);                 // Raw reading from mic 
  n   = abs(n - 512 - DC_OFFSET);            // Center on zero
  n   = (n <= NOISE) ? 0 : (n - NOISE);      // Remove noise/hum
  lvl = ((lvl * 7) + n) >> 3;    // "Dampened" reading (else looks twitchy)
  
  // Calculate bar height based on dynamic min/max levels (fixed point):
  height = TOP * (lvl - minLvlAvg) / (long)(maxLvlAvg - minLvlAvg);

  if(height < 0L)       height = 0;      // Clip output
  else if(height > TOP) height = TOP;
  if(height > peak)     peak   = height; // Keep 'peak' dot at top

// if POT_PIN is defined, we have a potentiometer on GPIO #3 on a Trinket 
//    (Gemma doesn't have this pin)
  uint8_t bright = 255;   
#ifdef POT_PIN            
   bright = analogRead(POT_PIN);  // Read pin (0-255) (adjust potentiometer 
                                  //   to give 0 to Vcc volts
#endif
  strip1.setBrightness(bright);    // Set LED brightness (if POT_PIN at top
                                  //  define commented out, will be full)
  strip2.setBrightness(bright);    // Set LED brightness
  strip3.setBrightness(bright);    // Set LED brightness

  // Color pixels based on rainbow gradient
  for(i=0; i<N_PIXELS; i++) {  
    if(i >= height) {              
       strip1.setPixelColor(i,   0,   0, 0);
       strip2.setPixelColor(i,   0,   0, 0);
       strip3.setPixelColor(i,   0,   0, 0);
    }
    else {
      uint32_t color = Wheel(map(i,0,strip1.numPixels()-1,30,150));
       strip1.setPixelColor(i,color);
       strip2.setPixelColor(i,color);
       strip3.setPixelColor(i,color);
    }
  } 

   strip1.show(); // Update strip
   strip2.show(); // Update strip
   strip3.show(); // Update strip

  vol[volCount] = n;                      // Save sample for dynamic leveling
  if(++volCount >= SAMPLES) volCount = 0; // Advance/rollover sample counter

  // Get volume range of prior frames
  minLvl = maxLvl = vol[0];
  for(i=1; i<SAMPLES; i++) {
    if(vol[i] < minLvl)      minLvl = vol[i];
    else if(vol[i] > maxLvl) maxLvl = vol[i];
  }
  // minLvl and maxLvl indicate the volume range over prior frames, used
  // for vertically scaling the output graph (so it looks interesting
  // regardless of volume level).  If they're too close together though
  // (e.g. at very low volume levels) the graph becomes super coarse
  // and 'jumpy'...so keep some minimum distance between them (this
  // also lets the graph go to zero when no sound is playing):
  if((maxLvl - minLvl) < TOP) maxLvl = minLvl + TOP;
  minLvlAvg = (minLvlAvg * 63 + minLvl) >> 6; // Dampen min/max levels
  maxLvlAvg = (maxLvlAvg * 63 + maxLvl) >> 6; // (fake rolling average)
}

// Input a value 0 to 255 to get a color value.
// The colors are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  if(WheelPos < 85) {
   return strip1.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } else if(WheelPos < 170) {
   WheelPos -= 85;
   return strip1.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else {
   WheelPos -= 170;
   return strip1.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}

ahhh that worked :slight_smile:

Is there a way that you could edit this to work with A 12 dot strip and a 300 dot strip? Been having trouble trying to get it to work correctly. Thanks, I may be able to post my code, but I make no guarantees