Silencio

Keeping noise levels down since 2015

Made by marcgut8712, Vishal Pallikandi, Ruyao Wu, Michael, behnamh8 and fskuok

Silencio is a non intrusive, low cost solution to give people a tool to more effectively self regulate noise levels. Silencio monitors and displays ambient noise on a hanging, lamp like device and thus establishing an accepted noise level. The device would hang over each cluster or row of tables to give precise, location based feedback

Created: February 11th, 2015

0
For the last 2000 years or so, libraries have served the same purpose of storing and lending books and offering a public study space. Procedures have been tweaked and improved but the underlying system has fundamentally stayed the same.

Libraries are an exciting case for a vision project as they stand on the verge of significant change. With the importance of physical books declining rapidly, the role of libraries is bound to evolve.

When we envisioned the library of the future, we did so with studying as its main purpose. We firmly believe that libraries will strengthen their position as public study places by offering more space, more tools and more media, all while physical books will slowly disappear.

With this in mind, we conceived a system that is set to increase the efficiency of visitor management while also establishing low noise levels. The Silencio consist of connected noise level indication along with seating information.

The prototype picks up noise over two microphones of which one is used to cancel out ambient noise. A total of 4 LED rings then displays noise levels, thus subtly reminding visitors to be mindful of their volume.

The seating indication has not made it into the prototype but it would have indicated free seats in walled clusters to visitors with the help of pressure and proximity sensors. The sensors would be connected to a seating chart, saving visitors time to search multiple floors for free seats.

To build the prototype, we used acrylic plates that we cut with the help of a laser cutter and then glued together. The LED strips are also glued to the acrylic discs. One microphone at the bottom of the device, pointing towards the cluster is responsible for the noise levels while a second, top-mounted microphone helps canceling out ambient noise. The spark processor then translates the noise into a numeric value that triggers up to 4 LED rings as each level's threshold is reached.

0
0
#define micPin A0
#define micCancelPin A4

const int sampleWindow = 10; // Sample window width in mS (50 mS = 20Hz)
unsigned int sample;
unsigned int sample2;

double volts=0;
double volts2=0;

//average ON sample
const int numOnSamples=2;
int sampleOnCount=0;
double alpha=0.5; //pick a val between 0 and 1
double averageVal=0;
double averageValPub=0;
double avgLongTime=0;

//average OFF sample
const int numOffSamples=250;
int sampleOffCount=0;
double currentAvg=0;
double currentAvgPub=0;

//publish events to cloud
const double ambientNoiseLevel=0.6;

unsigned long lastTimeStamp=0;

void setup() 
{
  //Serial.begin(9600);
  Spark.variable("volts",&volts,DOUBLE);
  Spark.variable("currentAvgPub",&currentAvgPub,DOUBLE);
  pinMode(D0, OUTPUT);
  pinMode(D1, OUTPUT);
  pinMode(D2, OUTPUT);
}


void loop() 
{
  unsigned long startMillis= millis();  // Start of sample window
  unsigned int peakToPeak = 0;   // peak-to-peak level
   unsigned int peakToPeak2 = 0;

  unsigned int signalMax = 0;
  unsigned int signalMin = 4095; //1024

   unsigned int signalMax2 = 0;
  unsigned int signalMin2 = 4095; //1024

  // collect data for 50 mS
  while (millis() - startMillis < sampleWindow)
  {
     sample = analogRead(micPin);
     sample = analogRead(micCancelPin);
     if (sample < 4095)  // toss out spurious readings
     {
        if (sample > signalMax)
        {
           signalMax = sample;  // save just the max levels
           signalMax2= sample2;
        }
        else if (sample < signalMin)
        {
           signalMin = sample;  // save just the min levels
           signalMin2 = sample2;
        }

     }
  }
  peakToPeak = signalMax - signalMin;  // max - min = peak-peak amplitude
  volts = (peakToPeak * 3.3) / 4095;  // convert to volts

  peakToPeak2 = signalMax2 - signalMin2;  // max - min = peak-peak amplitude
  volts2 = (peakToPeak2 * 3.3) / 4095;  // convert to volts

  volts=volts-volts2;

  if(sampleOnCount<numOnSamples)
  {
      //if(volts>averageVal)
      //averageVal=volts;
      averageVal=alpha*volts + (1-alpha)*averageVal;
      avgLongTime=alpha*volts + (1-alpha)*avgLongTime;
      sampleOnCount++;
  }
  else
  {
      averageValPub=averageVal; //publish or return the val of averageVal before resetting
      averageVal=0;
      sampleOnCount=0;
  }

   if(sampleOffCount<numOffSamples)
  {
      if (averageValPub>currentAvg)
      {
          currentAvg=averageValPub;
          currentAvgPub=currentAvg;
      }
      sampleOffCount++;
  }
  else
  {
      sampleOffCount=0;
      currentAvg=0;
  }

   if(millis()-lastTimeStamp>10000)
   {
       Spark.publish("updateEvent", "%d",avgLongTime);
       lastTimeStamp=millis();
   }

   checkForPublish();
  //Serial.println(volts);
}

void checkForPublish()
{
   if (currentAvgPub<(ambientNoiseLevel))
   {Spark.publish("valueChange", "0");
   digitalWrite(D0,LOW); digitalWrite(D1,LOW); digitalWrite(D2,LOW);
   }
   if (currentAvgPub<(1.0)&&currentAvgPub>(ambientNoiseLevel))
   {Spark.publish((const char *)"valueChange", (const char *)"1");
   digitalWrite(D0,HIGH); digitalWrite(D1,LOW); digitalWrite(D2,LOW);
   }
   if (currentAvgPub<(1.1)&&currentAvgPub>(1.0))
   {Spark.publish((const char *)"valueChange", (const char *)"2");
   digitalWrite(D0,HIGH); digitalWrite(D1,HIGH); digitalWrite(D2,LOW);
   }
   if (currentAvgPub>(1.1))
   {Spark.publish((const char *)"valueChange", (const char *)"3");
   digitalWrite(D0,HIGH); digitalWrite(D1,HIGH); digitalWrite(D2,HIGH);
   }
}
Click to Expand
0

Noise Level Map

Noise level map is connected to Spark Cloud and will display the noise level of all areas in the last 10 mins. It refresh every 10 seconds to display the newest data.

White indicates noise level 0, more red means higher noise level

0
#define micPin A0
#define micCancelPin A4

const int sampleWindow = 10; // Sample window width in mS (50 mS = 20Hz)
unsigned int sample;
unsigned int sample2;

double volts=0;
double volts2=0;

//average ON sample
const int numOnSamples=2;
int sampleOnCount=0;
double alpha=0.5; //pick a val between 0 and 1
double averageVal=0;
double averageValPub=0;
double avgLongTime=0;

//average OFF sample
const int numOffSamples=250;
int sampleOffCount=0;
double currentAvg=0;
double currentAvgPub=0;

//publish events to cloud
const double ambientNoiseLevel=0.6;

unsigned long lastTimeStamp=0;

void setup() 
{
  //Serial.begin(9600);
  Spark.variable("volts",&volts,DOUBLE);
  Spark.variable("currentAvgPub",&currentAvgPub,DOUBLE);
  pinMode(D0, OUTPUT);
  pinMode(D1, OUTPUT);
  pinMode(D2, OUTPUT);
}


void loop() 
{
  unsigned long startMillis= millis();  // Start of sample window
  unsigned int peakToPeak = 0;   // peak-to-peak level
   unsigned int peakToPeak2 = 0;

  unsigned int signalMax = 0;
  unsigned int signalMin = 4095; //1024

   unsigned int signalMax2 = 0;
  unsigned int signalMin2 = 4095; //1024

  // collect data for 50 mS
  while (millis() - startMillis < sampleWindow)
  {
     sample = analogRead(micPin);
     sample = analogRead(micCancelPin);
     if (sample < 4095)  // toss out spurious readings
     {
        if (sample > signalMax)
        {
           signalMax = sample;  // save just the max levels
           signalMax2= sample2;
        }
        else if (sample < signalMin)
        {
           signalMin = sample;  // save just the min levels
           signalMin2 = sample2;
        }

     }
  }
  peakToPeak = signalMax - signalMin;  // max - min = peak-peak amplitude
  volts = (peakToPeak * 3.3) / 4095;  // convert to volts

  peakToPeak2 = signalMax2 - signalMin2;  // max - min = peak-peak amplitude
  volts2 = (peakToPeak2 * 3.3) / 4095;  // convert to volts

  volts=volts-volts2;

  if(sampleOnCount<numOnSamples)
  {
      //if(volts>averageVal)
      //averageVal=volts;
      averageVal=alpha*volts + (1-alpha)*averageVal;
      avgLongTime=alpha*volts + (1-alpha)*avgLongTime;
      sampleOnCount++;
  }
  else
  {
      averageValPub=averageVal; //publish or return the val of averageVal before resetting
      averageVal=0;
      sampleOnCount=0;
  }

   if(sampleOffCount<numOffSamples)
  {
      if (averageValPub>currentAvg)
      {
          currentAvg=averageValPub;
          currentAvgPub=currentAvg;
      }
      sampleOffCount++;
  }
  else
  {
      sampleOffCount=0;
      currentAvg=0;
  }

   if(millis()-lastTimeStamp>10000)
   {
       Spark.publish("updateEvent", "%d",avgLongTime);
       lastTimeStamp=millis();
   }

   checkForPublish();
  //Serial.println(volts);
}

void checkForPublish()
{
   if (currentAvgPub<(ambientNoiseLevel))
   {Spark.publish("valueChange", "0");
   digitalWrite(D0,LOW); digitalWrite(D1,LOW); digitalWrite(D2,LOW);
   }
   if (currentAvgPub<(1.0)&&currentAvgPub>(ambientNoiseLevel))
   {Spark.publish((const char *)"valueChange", (const char *)"1");
   digitalWrite(D0,HIGH); digitalWrite(D1,LOW); digitalWrite(D2,LOW);
   }
   if (currentAvgPub<(1.1)&&currentAvgPub>(1.0))
   {Spark.publish((const char *)"valueChange", (const char *)"2");
   digitalWrite(D0,HIGH); digitalWrite(D1,HIGH); digitalWrite(D2,LOW);
   }
   if (currentAvgPub>(1.1))
   {Spark.publish((const char *)"valueChange", (const char *)"3");
   digitalWrite(D0,HIGH); digitalWrite(D1,HIGH); digitalWrite(D2,HIGH);
   }
}
Click to Expand
x
Share this Project


About

Silencio is a non intrusive, low cost solution to give people a tool to more effectively self regulate noise levels. Silencio monitors and displays ambient noise on a hanging, lamp like device and thus establishing an accepted noise level. The device would hang over each cluster or row of tables to give precise, location based feedback