Created
May 21, 2012 18:38
-
-
Save munaf-zz/2763839 to your computer and use it in GitHub Desktop.
Arduino LED Strip + Microphone
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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