Introduction: Neo Pixel Arduino Vu Meter

Hi!
This is a project that I created for a Digital Multi Media class that I'm taking. I did it in hopes to notify my dad when he is being too loud. He's been a musician all of his life and due to this he can no longer hear as good as he used to. So hopefully now he can see how loud he is! 


PS: CLICK THE MOV. FILE. to see how my classmates enjoyed the end result!

Step 1: Materials and Tools

Materials

-Arduino Uno-http://store.arduino.cc/index.php?main_page=product_info&cPath=11&products_id=195
-Electret Microphone Amplifier -http://www.adafruit.com/products/1063
-Adafruit NeoPixel Digital RGB LD Weatherproof Strip 30 LED (1 meter) -http://www.adafruit.com/products/1376
-6x AA Battery Holder
-Wires

Tools
-Electrical  Tape
-Soldering Iron
-Zip Ties

Housing (optional)
- 20 in Paper Lantern

Step 2: LET'S DO IT! (wiring)-microphone

I started off by soldering the pins into the microphone and then connecting colored wires to them. The out pin is connected to the orange. The GND pin is connected to the red wire. The VCC pin is connected to the green and black wire. These are split to go into the 3.3v pin on the Arduino and the AREF pin.

Step 3: LET'S DO IT (cont.)-LED

I cut about four inches of colored wire and soldered them to the GND, DIN and +5v. 

Step 4: GO to Your HOME!

For my housing I used a 20 inch white paper lantern. You can choose whatever you would like. Let those brain juices flow!! Inside the lantern there is a frame that I connected my LED strip to using zip ties.

I connected my 6x AA battery pack to the bottom of the farm and placed my Arduino on top of that. I also attached my Arduino with a zip tie. 

Step 5: All of the Wires!

For my microphone I connected the OUT pin to the A5 pin on the Arduino. GND went into GND. VCC pin was split into two. One pin went into 3.3v and the second went into the AREF. 

For the LED's I connected GND to GND. DIN was connected to pin 6 and 5v to the 5v pin. 

DIN on the LEDS shows which way the flow is going. You can alter the pin number in the code. It's worked fine for me. 

Step 6: The Code.

This code was provided by Adafruit for their LED Ampli-tie. I've changed a few things in it to fit my project. 



/*
LED VU meter for Arduino and Adafruit NeoPixel LEDs.

Hardware requirements:
- Most Arduino or Arduino-compatible boards (ATmega 328P or better).
- Adafruit Electret Microphone Amplifier (ID: 1063)
- Adafruit Flora RGB Smart Pixels (ID: 1260)
   OR
- Adafruit NeoPixel Digital LED strip (ID: 1138)
- Optional: battery for portable use (else power through USB or adapter)
Software requirements:
- Adafruit NeoPixel library

Connections:
- 3.3V to mic amp +
- GND to mic amp -
- Analog pin to microphone output (configurable below)
- Digital pin to LED data input (configurable below)
See notes in setup() regarding 5V vs. 3.3V boards - there may be an
extra connection to make and one line of code to enable or disable.

Written by Adafruit Industries.  Distributed under the BSD license.
This paragraph must be included in any redistribution.
*/

#include <Adafruit_NeoPixel.h>

#define N_PIXELS  30  // Number of pixels in strand
#define MIC_PIN   A5  // Microphone is attached to this analog pin
#define LED_PIN    6  // NeoPixel LED strand is connected to this pin
#define DC_OFFSET  0  // DC offset in mic signal - if unusure, leave 0
#define NOISE     20  // Noise/hum/interference in mic signal
#define SAMPLES   40  // Length of buffer for dynamic level adjustment
#define TOP       (N_PIXELS + 2) // Allow dot to go slightly off scale
#define PEAK_FALL 60  // Rate of peak falling dot

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       = 20,      // Current "dampened" audio level
  minLvlAvg = 0,      // For dynamic adjustment of graph low & high
  maxLvlAvg = 512;
Adafruit_NeoPixel
  strip = Adafruit_NeoPixel(N_PIXELS, LED_PIN, NEO_GRB + NEO_KHZ800);

void setup() {

  // This is only needed on 5V Arduinos (Uno, Leonardo, etc.).
  // Connect 3.3V to mic AND TO AREF ON ARDUINO and enable this
  // line.  Audio samples are 'cleaner' at 3.3V.
  // COMMENT OUT THIS LINE FOR 3.3V ARDUINOS (FLORA, ETC.):
analogReference(EXTERNAL);

  memset(vol, 0, sizeof(vol));
  strip.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


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

  }



  // Draw peak dot 
  if(peak > 0 && peak <= N_PIXELS-1) strip.setPixelColor(peak,Wheel(map(peak,0,strip.numPixels()-1,30,150)));

   strip.show(); // Update strip

// Every few frames, make the peak pixel drop by 1:

    if(++dotCount >= PEAK_FALL) { //fall rate

      if(peak > 0) peak--;
      dotCount = 0;
    }



  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 strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } else if(WheelPos < 170) {
   WheelPos -= 85;
   return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else {
   WheelPos -= 170;
   return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}

Make It Glow Contest

Participated in the
Make It Glow Contest