Measuring Sound Levels

Author Gravatar Image WILLIAM EARL
The Audio signal from the output of the amplifier is a varying voltage.  To measure the sound level, we need to take multiple measurements to find the minimum and maximum extents or "peak to peak amplitude" of the signal.  

In the example below, we choose a sample window of 50 milliseconds.  That is sufficient to measure sound levels of frequencies as low as 20 Hz - the lower limit of human hearing.

After finding the minimum and maximum samples, we compute the difference and convert it to volts and the output is printed to the serial monitor.
Copy Code
/****************************************
Example Sound Level Sketch for the 
Adafruit Microphone Amplifier
****************************************/

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

void setup() 
{
   Serial.begin(9600);
}


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

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

   // 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
   double volts = (peakToPeak * 3.3) / 1024;  // convert to volts

   Serial.println(volts);
}
OK, so that's not very exciting.  What else can you do with it?

Scrolling Sound Level Meter

So now we will take the peak-to-peak measurement and use it to drive a Bicolor LED Matrix to display the sound level.  To make it more interesting, we will scroll the display so that the last 8 measurements are graphed in real-time.

To do this you will need to download  the Adafruit GFX Library and LED Backpack Library.  The Wire Library is included in the Arduino IDE installation.

Assemble the Matrix

Follow the tutorial here:

Connect the Matrix

The Matrix backpack has 4 pins, connected as follows:

  1. '+' -> 5v
  2. '-'  -> GND
  3. D -> SDA (Analog Pin 4)
  4. C -> SCL (Analog Pin 5)

Upload the Code

Paste the code below into the Arduino IDE and upload it.  Speak in a normal voice about 6-8 inches from the microphone and the sound level meter matrix display should start scrolling.

Adjust the Gain

Although the amplifier is capable of a rail-to-rail signal (3.3v in this case), the code maps a 1v peak-to-peak signal to the full scale of the display.  

This can be changed in the code.  Or you can adjust the gain trimmer-pot of the amplifier with a small straight-bladed screwdriver.  The amplifier gain is adjustable from 25x to 125x.
Make all gain adjustments gently. If you feel resistance, stop. The tiny trim pot is delicate and it is easy to damage by turning past the stop.
Copy Code
/****************************************
Scrolling Sound Meter Sketch for the 
Adafruit Microphone Amplifier
****************************************/

#include <Wire.h>
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"

// Include the Matrix code for display
Adafruit_BicolorMatrix matrix = Adafruit_BicolorMatrix();

const int maxScale = 8;
const int redZone = 5;

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

void setup() 
{
   Serial.begin(9600);

   matrix.begin(0x70);  // pass in the address
}


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

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

   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;

   // map 1v p-p level to the max scale of the display
   int displayPeak = map(peakToPeak, 0, 1023, 0, maxScale);

   // Update the display:
   for (int i = 0; i < 7; i++)  // shift the display left
   {
      matrix.displaybuffer[i] = matrix.displaybuffer[i+1];
   }

   // draw the new sample
   for (int i = 0; i <= maxScale; i++)
   {
      if (i >= displayPeak)  // blank these pixels
      {
         matrix.drawPixel(i, 7, 0);
      }
      else if (i < redZone) // draw in green
      {
         matrix.drawPixel(i, 7, LED_GREEN);
      }
      else // Red Alert!  Red Alert!
      {
         matrix.drawPixel(i, 7, LED_RED);
      }
   }
   matrix.writeDisplay();  // write the changes we just made to the display
}
Last updated on 2014-04-20 at 10.45.33 AM Published on 2013-01-13 at 09.43.18 PM