Measuring sound volume: 25% wrong readings?

I want to measure sound volume with my Arduino, so I created simple circuit with an electret microphone, and to be sure also bought a sound sensor (picture) and connected it to my analog input. Since I don't need to enhance quality sound, but simply detect the volume, I read out the analog input 20 times per second, and create a running average from those readings. Environmental noise generates a value between 20 and 60, and when I clap my hands or start talking you see the average climb to values between 300 and 500. Now my question:

When printing the results, almost 25% of all the readings I do from the analog port are 0.0. I tried reading out my own build circuit, and I tried reading out the sound sensor I bought, but both show the same behavior that almost one/fourth of all readings are zero. I already created a way to exclude those readings from the running average, but I am curious to know WHY this happens, hoping to solve it. Has it something to do with the sampling speed, or is it possible that the microphones clips? Let me know what you think.

I'm sorry, I tried to keep the details as abstract as possible, but I'll try to give some more information :slight_smile:

6) The sound sensor is connected to A0 of my Arduino Duemilanove. The reason I use floating, is because I use the code below to read out the sensor pin and create a very simple way to make a running average, and therefore I need decimals. With a 50ms delay I sample 20 times per second.

float soundvalue = 0;
float soundaverage = 0;

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

void loop()
{
  soundaverage = soundaverage * 0.95 + analogRead(soundvalue) * 0.05;
  Serial.println(soundaverage);
  delay(50);
}

5) I first tried building my own circuit with some opamps and a microphone, and although it worked, it showed some errors while reading out the signal. Since I started questioning myself I bought this sound sensor to be sure and have 'better results'. But as I experienced, the same problems appeared

2) I bought this (see screenshot bottom of post) sensor from a Dutch webshop, there was no real explanation with it. All I know is that there's an LM386 opamp on it, but the chinese company that designs these boards has no datasheets and an impossible to read website. (http://shop.flamingoeda.com/)

3) So now that I knew that it probably was not my circuit that was wrong (since both my own circuit and the sensor showed the same problems), I continued my search in the software. What happens is that about 25% of the the raw readings drops to 0.0. I fixed that making a little if-statement that filters out results below a certain threshold, so that it doesn't effect the average.

Since it happens so often, I'm just curious to find out what this is. I tried speeding up (no delays) and slowing down (1 per second) the sampling rate, but what else can I try? :slight_smile:


Can you also dump a list of values of the sample of a hand clap?
I expect a fast rise and a less fast decay. But all within a second.
What is the maximum value your read? (myabe you can improve sensitivity.
Further I recall volume of sound is logarithmic in nature. If you have a linear measurement it could also explain that many valuers are mapped upon zero.

Without a schematic of the model it's hard to make heads or tails of what you are seeing. Is there a steady DC bias voltage outputted when there is no audio? Could all those 0 readings just be negative peaks that the Arduino A/D just clamps to zero?

I too bought one of these Asian audio modules and could not really understand how to utilize it without a schematic drawing to understand what kind of electrical signal it is developing. There is a diode on the board, so could they be rectifying and filtering the signal giving just an average DC output value? Again without a schematic there is too much unknown about how the audio signal is being processed by the module.

Lefty

integer version, that starts sampling when sound starts. notice higher serial speed to prevent delay.
(code not tested)

long soundvalue = 0;
long soundaverage = 0;
long max = 0;
long sample ;

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

void loop()
{
  max = 0;
  #define THRESHOLD = 0;
  do 
    sample = analogRead(soundvalue);
  while (sample <= THRESHOLD) ;       // wait for sound 

  long start = millis();  // get timing

  while (sample > THRESHOLD)         // sample as long as there is sound 
  {
     if (sample > max) max = sample;
     soundaverage = (soundaverage * 95 +  sample * 5) / 100;
     Serial.println(soundaverage);
     sample = analogRead(soundvalue);
  }
  Serial.print("MAX: ");
  Serial.println(max);
  Serial.print("TIME: ");
  Serial.println(millis() - start);
}

You may 'need' a running average, but you certainly don't need what you refer to as 'decimals'.
Integer arithmetic will work perfectly well.

Found this email on the website - sales@flamingoeda.com