Voice Loudness Monitor (Arduino)

1,586

26

4

Introduction: Voice Loudness Monitor (Arduino)

About: I'm a mechanical engineer and a maker

In this pandemic it is important to take reasonable measures to reduce spreading viruses. A paper from 2019 found that louder voices spread more viruses (https://www.nature.com/articles/s41598-019-38808-z) [Asadi et al. 2019].

This simple project aims to remind people to not shout unnecessarily. This can be used in classrooms, meeting rooms or any other setting where people are talking.

Supplies

Arduino Nano x 1

Green 5V LED x 1

Red 5V LED x 1

560 Ohm resistors x 2

Jumper wires (male to male) x 4

Breadboard x 1

Electret microphone with MAX 4466 amplifier (https://www.adafruit.com/product/1063) x 1

USB to USB Mini B cable x 1

USB Power Bank or 5V Power supply x 1

Step 1: Assembling the Circuit

The circuit is fairly simple and can be laid out in a number of ways. On my breadboard I have connected:

  • Green LED +ve to Arduino D3
  • Green LED -ve to Arduino GND
  • Red LED +ve to Arduino D2
  • Red LED -ve to Arduino GND
  • Mic VCC to Arduino 3.3V (this is the least noisy power supply pin)
  • Mic GND to Arduino GND
  • Mic OUT to Arduino A0

For supplying power to the Arduino, I simply connected the Mini USB port on the Arduino board to a USB power bank with the appropriate cable.

Step 2: Writing the Code

A simple way of measuring loudness is to take the maximum and minimum voltage readings from the microphone. A dB sound pressure level can be calculated using the microphone sensitivity and amplifier gain. However, this application does not require this level of detail.

You can have a go at writing your own code or copy the example below:

// Define constants - these can be tuned to the user's preferences
#define sampleWindow 10 // Sample window width in milliseconds (10 ms = 100 Hz)
#define LEDtime 1000 //time to keep LED on for when noise goes above threshold
#define threshold 40 //mV
#define QTY_SAMPLES 16 // the number of samples to be averaged

//Define pins used on the breadboard
#define MIC_IN A0
#define LED_LOUD PD2
#define LED_QUIET PD3
#define V_MIC 3.3

//Create global variables
int sample;
long startLED;
float values[QTY_SAMPLES];
float sum;
int index;


// This function takes a rolling average of QTY_SAMPLES
// The oldest value is removed from the sum and the newest takes its place in the array. Then the mean of this array is returned.
float rollingAverage(float num) {
  sum -= values[index];
  values[index] = num;
  sum += values[index];
  index++;
  index = index % QTY_SAMPLES;
  return sum / QTY_SAMPLES;
}


//Begin serial output, initialise pins and set global variables
void setup()
{
  Serial.begin(9600);
  pinMode(LED_QUIET, OUTPUT);
  pinMode(LED_LOUD, OUTPUT);
  pinMode(MIC_IN, INPUT);
  float sum = 0;
  int index = 0;
}


//Sample the signal amplitude and calculate a rolling average. If the average loudness is too high, then alert user via LEDs
void loop()
{

  // Reset variables
  int signalMax = 0;
  int signalMin = 1024;
  unsigned long startMillis = millis(); // Set the start of the sample window

  // Record the signal maximum and minimum over the sample window
  while (millis() - startMillis < sampleWindow)
  {
    sample = analogRead(MIC_IN);
    if (sample > signalMax)
    {
      signalMax = sample;  // save the new maximum
    }
    else if (sample < signalMin)
    {
      signalMin = sample;  // save the new minimum
    }
  }

  // Convert the signal maximum and minimum into millivolts from the amplifier
  float amplitude = signalMax - signalMin;  // This calculates the peak-to-peak amplitude
  float millivolts = rollingAverage(amplitude) * V_MIC / 1.024; // This calls the rolling average function and converts the average amplitude to millivolts
  Serial.println(millivolts);

  //Alert the user via the LEDs if the noise is too loud
  if (millivolts > threshold) {
    digitalWrite(LED_LOUD, HIGH); digitalWrite(LED_QUIET, LOW);
    startLED = millis();
  } else if (millis() - startLED > LEDtime) {
    digitalWrite(LED_LOUD, LOW); digitalWrite(LED_QUIET, HIGH);
  }
}

//Further work could be converting the millivolts signal into a Sound Pressure Level (dB SPL), or adding more LEDs to display a noise level scale<br>

Step 3: Tuning

The key value to be set is the 'threshold'. This is the number of millivolts which are required to trigger LED_LOUD. This is most easily done by using the serial monitor in the Arduino IDE. Here you can correlate how loudly you speak with what the Arduino calculates.

When the threshold is correctly set, the green LED should be lit during normal conversation, and the red LED should light up whenever anyone speaks more loudly than is necessary.

The other constants can also be tweaked to change the sampling window or the number of samples that are averaged. Play around with these constants to see what effect they have.

Step 4: Thank You

Thank you for reading this instructable, and thanks also to the University of Bristol and the Royal Academy of Engineering for supporting Project Clean Access.

Be the First to Share

    Recommendations

    • Raspberry Pi Contest

      Raspberry Pi Contest
    • New Year, New Skill Student Design Challenge

      New Year, New Skill Student Design Challenge
    • Fix It Speed Challenge

      Fix It Speed Challenge

    4 Comments

    0
    popul4r628
    popul4r628

    10 months ago

    Excuse me, is there a code for this project that supports Arduino Uno or Leonardo?

    0
    Harrrry
    Harrrry

    Reply 9 months ago

    Hi,
    This code should run fine on an Arduino Uno or Leonardo. The only thing you might have to change is where the pins are defined:
    //Define pins used on the breadboard
    #define MIC_IN [pin label here]
    #define LED_LOUD [pin label here]
    #define LED_QUIET [pin label here]

    Hope that helps :)

    0
    agiudes11
    agiudes11

    Question 11 months ago on Step 4

    Hi, I am looking to replicate this for a school project I need to do, however we're using Arduino Uno and not Nano. Would it still be possible for me to achieve the project? Thanks

    0
    Harrrry
    Harrrry

    Reply 11 months ago

    Hello, yes absolutely!
    You will need to redefine the pins and recompile the code for the Arduino Uno, but otherwise everything else should be okay.
    I would love to see a photo on here when you've finished it :)