Project tutorial
Voice Loudness Monitor

Voice Loudness Monitor © CC BY

This product alerts the user when they are speaking too loudly via two LEDs. Louder voices spread more viral particles, so quieter is safer.

  • 3 views
  • 0 comments
  • 0 respects

Components and supplies

About this project

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.

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 tutorial, and thanks also to the University of Bristol and the Royal Academy of Engineering for supporting Project Clean Access.

Code

VoiceLoudnessMonitor.inoArduino
No preview (download only).
Code snippet #1Plain text
// 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>

Comments

Similar projects you might like

ECG Monitor

Project tutorial by Rushil Saraswat

  • 16,468 views
  • 16 comments
  • 19 respects

Doggo Water Bowl Refill Monitor/Indicator - Part 2

Project tutorial by HeathenHacks

  • 2,798 views
  • 0 comments
  • 8 respects

Arduino WiFi Pulse Monitor

Project showcase by Andres Santos

  • 14,269 views
  • 8 comments
  • 30 respects

Sleep Quality Monitor

by SrVassili

  • 9,825 views
  • 1 comment
  • 13 respects

Doggo Water Bowl Refill Monitor/Indicator - Part 1

Project tutorial by HeathenHacks

  • 2,377 views
  • 2 comments
  • 8 respects

Heart Rate Monitor (Wearable and Wireless Using ECG)

Project tutorial by Dmitry Dziuba

  • 30,091 views
  • 23 comments
  • 66 respects
Add projectSign up / Login