Skip to content

Instantly share code, notes, and snippets.

@munaf-zz
Created May 21, 2012 18:38
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save munaf-zz/2763839 to your computer and use it in GitHub Desktop.
Save munaf-zz/2763839 to your computer and use it in GitHub Desktop.
Arduino LED Strip + Microphone
#include <ledcontroller.h>
using LedController::Color;
using LedController::LedStrip;
using LedController::Interval;
Color orange(0xFF6600);
Color prettyblue(0x6FBAFC);
#define COL_PRETTYBLUE 0x6FBAFC
#define PIN_SDI 2 // Red data wire (not the red 5V wire!)
#define PIN_CKI 3 // Green wire
#define PIN_MIC A0 // Microphone input
LedStrip ledStrip = LedStrip(PIN_SDI, PIN_CKI);
// Global environment variables.
int rawMicValue;
int rawBackgroundNoise;
int currentLevel = 0;
void setup() {
pinMode(PIN_MIC, INPUT);
// Gather Background Noise
Serial.begin(9600);
Serial.println("Calculating background noise.");
calculateBGNoise();
Serial.println(rawBackgroundNoise);
// Clear the LED Strip
ledStrip.setup();
ledStrip.clear();
ledStrip.send();
delay(2000);
Serial.println("Start Talking!");
}
void loop() {
int tempLevel;
// Read raw mic value
rawMicValue = analogRead(PIN_MIC);
// Filter mic value then convert to level
tempLevel = convertMicToLevel();
// Clear or Set levels based on current filtered mic value
if (tempLevel > currentLevel) {
//Serial.println("SHOULD BE SETTING LEVEL");
for (int i = currentLevel; i <= tempLevel; i++) {
setLevel(i);
ledStrip.send();
}
}
else if (tempLevel < currentLevel) {
//Serial.println("SHOULD BE CLEARLING LEVEL");
for (int i = currentLevel; i >= tempLevel; i--) {
clearLevel(i);
ledStrip.send();
}
}
currentLevel = tempLevel;
Serial.println("raw mic value");
Serial.println(rawMicValue);
delay(300);
}
//************************************************************************************
// Level Management
//
// A level is a group of LEDs that correspond to a specific microphone amplitude.
// Higher microphone amplitude = greater level.
//
// Levels start at zero. The number of levels per LED strip can be configured below.
//************************************************************************************
#define NUM_LEDS 32
#define NUM_LEVELS 8
#define MAX_LED_LEVEL (NUM_LEVELS-1)
#define NUM_LEDS_LEVEL (NUM_LEDS/NUM_LEVELS)
int levelLEDStart(int level) {
// Levels start at 0
// # Pins / # Levels * Level = start
return constrain((NUM_LEDS / NUM_LEVELS) * level, 0, (NUM_LEDS - NUM_LEDS_LEVEL - 1));
}
int levelLEDEnd(int level) {
// Levels start at 0
// # Pins / # Levels * Level + Pins-per-level = end
return constrain(levelLEDStart(level) + (NUM_LEDS_LEVEL-1), 0, NUM_LEDS - 1);
}
// Clears a level (group of LEDs). Does not actually write to LED strip!
void clearLevel(int level) {
// from start to end of level, run ledstrip.clear()
int first_led = levelLEDStart(level);
int last_led = levelLEDEnd(level);
for (int i = first_led; i <= last_led; i++) {
ledStrip.getColors()[i].clear();
}
}
// Colorizes a level (group of LEDs). Does not actually write to LED strip!
void setLevel(int level) {
// from start to end of level, run ledstrip.add()
int first_led = levelLEDStart(level);
int last_led = levelLEDEnd(level);
for (int i = first_led; i <= last_led; i++) {
ledStrip.getColors()[i].clear();
ledStrip.getColors()[i].add(prettyblue.scaled(0.3));
//ledStrip.getColors()[i].setRandom();
}
}
// Changes the mic amplitude range based on background noise.
// It's not perfect due to the crappy background noise detection method.
int filterRawMic() {
int filteredValue = rawMicValue - rawBackgroundNoise;
return constrain(filteredValue, 0, 1023 - rawBackgroundNoise);
}
// Given an LED number, return its level
int LEDToLevel(int led) {
return constrain((led/NUM_LEDS_LEVEL), 0, MAX_LED_LEVEL);
}
// Converts raw mic value to level using LEDToLevel helper function
int convertMicToLevel() {
int LED = map(filterRawMic(), 0, 1023-rawBackgroundNoise, 0, NUM_LEDS - 1);
return LEDToLevel(LED);
}
// Admittedly stupid way of calculating background noise.
// Consider this temporary and use proper signal processing techniques later.
void calculateBGNoise() {
unsigned long noiseSum = 0;
unsigned long rawBGNoiseTemp = 0;
int numReadings = 1000;
for (int i = 0; i < numReadings; i++) {
noiseSum = noiseSum + (unsigned long)(analogRead(PIN_MIC));
}
Serial.println(noiseSum);
rawBGNoiseTemp = noiseSum / ((unsigned long)numReadings);
rawBackgroundNoise = constrain((int)(rawBGNoiseTemp), 0, 1023);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment