Prototype Circuit

It's good protocol (& wise engineering!) to prototype your circuits before soldering permanently. You can use small alligator clips to connect the components temporarily. The pins on the mic sensor are small, so be sure to double check your connections if your having trouble getting the circuit to work. It might be easier to solder wires to the mic and then alligator clip to those. Since drumsets are so loud, the code is set to have a low sensitivity for the mic, so make sure to give a loud sound when testing the NeoPixels audio response. Rubbing the microphone with your finger is a good way to get a reaction.

The NeoPixel strips digital input connects to pin D0 of the Gemma. The negative connection of the NeoPixel strip goes to the ground pin on the Gemma. The positive power wire of the NeoPixel LED strip connects to the VBat pin of the Gemma (not 3.3V!) The out pin on the mic amp goes to pin A1/D2 of the Gemma - this is an anolog input pin. The positive power breakout pin on the mic amp will connect to the 3.3v pin of the Gemma since it is a clear power source than VBat, the voltage goes through the onboard regulator. The negative ground pin of the mic amp can share the same ground connection on the Gemma (together with the NeoPixel strip).

This project can work with either the original Gemma or the newer Gemma M0. A 3V Trinket board is also an option, but not the 5V variety…the circuit relies on the 3.3V regulator present on these other boards.

The Code

The Gemma is programmed via USB with the Arduino IDE. You can modify and customize the code to fit your setup. For starters, we can easy change the pin outs and number of NeoPixels. In our setup, each drum used 60 NeoPixels for each drum piece.

If your new to using the Gemma and the Arduino IDE, check out this guide for setting up. Have some extra time on your hands? Learn how to customize the code to change the color!

/* Sound-Reactive Drums for Adafruit Gemma/Trinket and NeoPixel LEDs.

Hardware requirements:
 - Adafruit Gemma, Gemma M0, or 3V Trinket microcontroller.
   Do NOT use a 5V Trinket; circuit DEPENDS on the 3V regulator!
 - Adafruit Electret Microphone Amplifier (product ID: 1063)
 - A length of NeoPixel LEDs, such as:
   o Adafruit Flora RGB Smart Pixels (ID: 1260)
   o Adafruit NeoPixel Digital LED strip (ID: 1138)
   o Adafruit Neopixel Ring (ID: 1463)
 - Lithium-polymer battery (such as 1578, but other sizes OK) and charger (1304)

Software requirements:
 - Adafruit NeoPixel library

Connections:
 - 3Vo (3V) to mic amp +
 - Vout (5V) to NeoPixel +
 - GND to mic amp - and NeoPixel -
 - Mic OUT to analog pin (configurable below)
 - Neopixel IN to digital pin (configurable below)
 Disconnect USB after programming; audio input requires clean DC from battery.

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

#include <Adafruit_NeoPixel.h>

#define LED_PIN      0 // NeoPixel LED strand is connected to D0
#define N_PIXELS    60 // Number of NeoPixels in strand
#define MIC_PIN     A1 // Microphone connects to A1 (aka D2)
#define DC_OFFSET    0 // DC offset in mic signal - if unusure, leave 0
#define NOISE       90 // Noise floor in mic signal
#define SAMPLES     50 // Length of buffer for dynamic level adjustment
#define BRIGHTNESS 255 // 0 (off) to 255 (max brightness)

int  lvl[SAMPLES];     // Save up recent mic readings
int  damp      = 10;   // Current "dampened" audio level
int  minLvlAvg = 0;    // For dynamic adjustment of graph low & high
int  maxLvlAvg = 512;
byte counter   = 0;    // Array index for storing recent mic readings

Adafruit_NeoPixel strip(N_PIXELS, LED_PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  memset(lvl, 0, sizeof lvl); // Clear lvl[] array to 0
  strip.begin();              // Initialize NeoPixels
}

void loop() {
  int n = analogRead(MIC_PIN);          // Raw reading from mic
  n = abs(n - 512 - DC_OFFSET);         // Center on zero, rectify to 0-512
  n = (n <= NOISE) ? 0 : (n - NOISE);   // Remove noise/hum
  lvl[counter] = n;                     // Save value for dynamic leveling
  if(++counter >= SAMPLES) counter = 0; // Increment array index, roll over if needed

  damp = ((damp * 7) + n + 3) / 8; // "Dampened" mic reading (else looks twitchy)

  // Calculate upper/lower range of prior mic readings
  uint16_t minLvl = lvl[0], maxLvl = lvl[0];
  for(uint8_t i = 1; i < SAMPLES; i++) {
    if(lvl[i] < minLvl)      minLvl = lvl[i];
    else if(lvl[i] > maxLvl) maxLvl = lvl[i];
  }
  // minLvl and maxLvl indicate the mic range over prior readings, used
  // for vertically scaling the output graph (so it looks interesting
  // regardless of current 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) < N_PIXELS) maxLvl = minLvl + N_PIXELS;
  minLvlAvg = (minLvlAvg * 63 + minLvl + 31) / 64; // Dampen min/max levels
  maxLvlAvg = (maxLvlAvg * 63 + maxLvl + 31) / 64; // (fake rolling average)
  // Bar height based on dampened reading scaled by dynamic min/max levels:
  int height = N_PIXELS * (damp - minLvlAvg) / (long)(maxLvlAvg - minLvlAvg);
  if(height < 0)             height = 0;  // Clip to strand bounds
  else if(height > N_PIXELS) height = N_PIXELS;

  // Color NeoPixels based on above calculations & apply rainbow gradient.
  strip.fill(0); // Clear everything, easier than setting individual pixels
  for(uint8_t i = 0; i < height; i++) { // For each pixel up to 'height'...
    // Use the ColorHSV function to produce a rainbow of hues. 20000 is
    // green-ish, the -40000 proceeds "backwards" through the color wheel,
    // with red at 0 and a magenta-ish hue around -20000. This is explained
    // in more depth on the "Arduino Library Use" page of NeoPixel Uberguide.
    strip.setPixelColor(i, strip.ColorHSV(20000 - 40000 * i / strip.numPixels(), 255, BRIGHTNESS));
  } 

  strip.show(); // Update NeoPixels
}

This guide was first published on Dec 04, 2013. It was last updated on Mar 08, 2024.

This page (Circuit Diagram) was last updated on Mar 08, 2024.

Text editor powered by tinymce.