Team: Xuan, Rhea, Hannah, Micah
Update
The code is working and the lights are reactive to sound. Unfortunately, the fill lights in the background are not working, there may be a wiring issue. It will have to be looked into later.
Previous
It doesn’t quite work, but it will soon! We were pretty ambitious with the design of this project and perhaps aimed a bit too high for the “rough prototype” level. But it’s just so pretty and we’re pretty proud. Below are the pictures of the prototype of the model:
And here is the updated code:
#include int outputPins[] = {3,5,6,9,10,11}; #define BRIGHTNESS 50 #define NUM_ZONES_TOT 5 // dynamic zones #define NUM_DLEDS 3 #define NUM_DZONES 4 Adafruit_NeoPixel strip0 = Adafruit_NeoPixel(NUM_DLEDS, outputPins[0], NEO_GRB + NEO_KHZ800); Adafruit_NeoPixel strip1 = Adafruit_NeoPixel(NUM_DLEDS, outputPins[1], NEO_GRB + NEO_KHZ800); Adafruit_NeoPixel strip2 = Adafruit_NeoPixel(NUM_DLEDS, outputPins[2], NEO_GRB + NEO_KHZ800); Adafruit_NeoPixel strip3 = Adafruit_NeoPixel(NUM_DLEDS, outputPins[3], NEO_GRB + NEO_KHZ800); // static zones #define NUM_SLEDS 6 #define NUM_SZONES 2 Adafruit_NeoPixel strip4 = Adafruit_NeoPixel(NUM_SLEDS, outputPins[4], NEO_GRB + NEO_KHZ800); Adafruit_NeoPixel strip5 = Adafruit_NeoPixel(NUM_SLEDS, outputPins[5], NEO_GRB + NEO_KHZ800); const int sampleWindow = 50; // Sample window width in mS (50 mS = 20Hz) unsigned int sample; const int analogIn = A0; uint16_t numPix[] = {strip0.numPixels(),strip1.numPixels(), strip2.numPixels(),strip3.numPixels(),strip4.numPixels(),strip5.numPixels()}; Adafruit_NeoPixel striparray[] = {strip0,strip1,strip2,strip3,strip4,strip5}; unsigned int signalMax = 500; unsigned int signalMin = 1024; //color arrays int r[] = {241,226,238,255}; int g[] = {117,72,39,0}; int b[] = {173,155,99,0}; void setup() { Serial.begin(9600); // initialize strips to off for(int s = 0; s < NUM_ZONES_TOT; s++) { striparray[s].setBrightness(BRIGHTNESS); striparray[s].begin(); striparray[s].show(); } } void loop() { int sample = soundSample(); //take sound measurement w/ mic int nz = map(sample,500,1020,0,NUM_DZONES+1); //map sample value onto dynamic zones outputResponse(nz); if(sample == 900) { blinkStrip(); } } int soundSample() { unsigned long startMillis= millis(); // Start of sample window unsigned int peakToPeak = 0; // peak-to-peak level // collect data for 50 mS while (millis() - startMillis < sampleWindow) { sample = analogRead(0); if (sample < 1024) // toss out spurious readings { if (sample > signalMax) { signalMax = sample; // save just the max levels } else if (sample < signalMin) { signalMin = sample; // save just the min levels } } } peakToPeak = signalMax - signalMin; // max - min = peak-peak amplitude return sample; } void outputResponse(int numZones) { int index = numZones - 1; //set all dynamic pixels to off for(int z = 0; z < NUM_DZONES; z++) { turnOffStrip(z); } //but... if numZones > 0, turn on the corresponding zone if(numZones > 0) { for(int p = 0; p < numPix[index]; p++) { //set pixel color to corresponding color striparray[index].setPixelColor(p, striparray[index].Color(r[index],g[index],b[index])); } } //set background color updateBackground(index); //update all zones for(int z = 0; z < NUM_ZONES_TOT; z++) { striparray[z].show(); } } // blink the fourth strip 3 times void blinkStrip() { for(int count = 0; count < 3; count++) { turnOffStrip(3); striparray[3].show(); delay(1000); for(int p = 0; p < numPix[3]; p++) { striparray[3].setPixelColor(p, striparray[3].Color(255,0,0)); } striparray[3].show(); delay(1000); } } //set pixels to off in a certain LED strip void turnOffStrip(int stripNum) { for(int p = 0; p < numPix[stripNum]; p++) { striparray[stripNum].setPixelColor(p, striparray[stripNum].Color(0,0,0)); } } //update background color to reflect noise levels void updateBackground(int index) { for(int p = 0; p < NUM_SLEDS; p++) { striparray[4].setPixelColor(p,striparray[4].Color(r[index],g[index],b[index])); striparray[5].setPixelColor(p,striparray[5].Color(r[index],g[index],b[index])); } }
Code outline:
-
- Electret Microphone Sensor detects ambient noise levels and returns an analog value.
- The analog value is mapped to a noise level between 1 and 4.
- This tells the outputResponse function to trigger the in the corresponding zone. It also tells all relevant strips which color to be, which changes with the noise level.
- At the highest noise level, the finger and background blink three times to catch the attention of the room.
This product is perfect for office spaces or college dorms, where conversations can spike in volume without anyone really noticing… until someone (a cop? a grumpy roommate? a disgruntled classmate?) comes to tell to shhhhhhhhhh!