Audio input - microphone with amplifier MAX4466

When using this product, or similar ones, is the sensitivity, please see the low range of values below, at only one metre away from a laptop's speakers at full volume the best one can expect? Also, in silence, room with no windows, no aircon, etc., there seems to be quite some noise.


#define samples (256)

int audioInRaw;
int audioInRectified;

void setup()
{
  Serial.begin(115200);
  //analogReference(EXTERNAL);
}

void loop()
{
  audioIn();
}

void audioIn()
{
  long audioAverage = 0, audioMax = 0, audioMin = 1024;

  for (int i = 0; i < samples; i++)
  {
    int audioInRaw = analogRead(A4);

    audioInRectified = abs(audioInRaw - 337); // level shift for 3,3V
    audioMin = min(audioMin, audioInRaw);
    audioMax = max(audioMax, audioInRaw);
    audioAverage += audioInRaw;
  }

  audioAverage /= samples;

  Serial.print("audioInRectified:"); Serial.print(audioInRectified); Serial.print(" ");
  Serial.print("audioMin:"); Serial.print(audioMin); Serial.print(" ");
  Serial.print("audioMax:"); Serial.print(audioMax); Serial.print(" ");
  Serial.print("audioAverage:"); Serial.print(audioAverage); Serial.print(" ");
  Serial.print("audioPeakToPeak:"); Serial.println(audioMax - audioMin);
}

Just a thought - if electret microphone based solutions just aren't the right thing to monitor (road) noise, should I buy a microphone with TRS headphone jack output? Reason is that line-level or headphone-level output with around 1V peak-to-peak can be processed well with Arduinos or compatibles, like I found out with some guidance recently. Or are there good electret microphone breakout boards, and I just bought the wrong one?

Did you allow for your audio being AC and the negative will soon kill your Arduino A/D converter?

The headphone-level or line-level solution, whether 5V, 3,3V or 1,1V based, works very well.

@Lagom
There is no negative. The output of the microphone board should be connected directly to your Arduino.
What voltage are you supplying to your mic board?
Whar is the ADC Vref?

That's what I did. That's how I get the values shown in the serial plotter screenshots above. I didn't say there's negative voltage from electret microphone/amplifier boards.

The question here is about possible noise reduction, obtainable resolution, and if these types of electret microphone/amplifier boards are a suitable route forward - or if I should rather buy a microphone with TRS headphone jack output (Rode, Beyerdynamic, Audiotechnica, Sennheiser, etc.), and do what was successfully discussed in the other thread.

What are the sound levels and frequency range you are trying to measure?

Nighttime street, with occasional car, motorcycle, tram and truck noise. I don't want to pick out specific frequencies.

While awaiting judgement on the suitability of electret microphone boards, I tried out another product at hand. Quite impressive that, in a silent room with no windows, aircon, etc., it picks up the ticking of a BRAUN alarm clock two metres away. The second screenshot is music playing at half volume from a laptop a metre away.


The output of this "ready to go" decibel meter breakout board matches the output of this app surprisingly well. No replacement for a professional calibrated product of course, but not too shabby either.

So, back to the ways noise can be reduced. Got a new microcontroller and new microphone with amplifier MAX4466, gain pot in default position between 25 x and 125 x, powered from the microcontroller's 3,3V output pin, which is powered from a 5V 2A wall PSU, no other components connected.

Windowless room, no aircon, etc., 3,3 V AREF and audio off and audio on compared. With audio off, quite noisy signal. Also, value range much lower compared to input from a headphone jack. But that's the way it is, I suppose. Apart from the noise - is the code I obtain RMS with ok?

The microphone datasheet mentions a sensitivity of -44 dBV, so that means microphoneSensitivity 0,00631 VRMS, right? The gain pot is set to half-way between 25 x gain and 125 x gain, so I assume 75 x gain, which would equate to 37 dB according to this source.

With 20 * log10(audioRMS/microphoneSensitivity), I should be able to calculate dB(SPL) on a hobbyist level, so I can compare to the "ready to go" decibel meter breakout board, the app, and a commercial dB(SPL) meter? Would that be a good way to go about it? Here it's done, but with the levelShift value of 512 ("AmpMax"), not the microphoneSensitivity value as suggested here. Some say this. Others say that. What do you audio experts suggest?


const byte pinAudioIn = 0;
const byte timeIntervalSampling = 35;
const int levelShift = 512; // 512 for 3,3V AREF as reference voltage, without 337

int sampleCounter;
int audioInRaw;
int audioInRectified;
long audioRMSPrecalc;

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

  analogReference(EXTERNAL); // Use 3,3V AREF as reference voltage, bias = 1,65V
}

void loop()
{
  unsigned long timeSamplingStart = millis();

  while (millis() - timeSamplingStart < timeIntervalSampling)
  {
    audioInRaw = analogRead(pinAudioIn);
    audioInRectified = abs(audioInRaw - levelShift);
    audioRMSPrecalc += ((long) audioInRectified * audioInRectified);

    sampleCounter ++;
  }

  audioRMSPrecalc /= sampleCounter;
  
  float audioRMS = sqrt(audioRMSPrecalc);

  Serial.print("audioInRectified:"); Serial.print(audioInRectified); Serial.print(" ");
  Serial.print("audioRMS:"); Serial.println(audioRMS);

  sampleCounter = 0;
}

There's something wrong with obtaining the RMS - the 2nd screenshot shows the RMS value often exceeding the rectified signal from which it is calculated. So, what is wrong with the code, the way I obtain the RMS value? With that being wrong, it's no use to continue attempting to obtain dB(SPL). As this is an audio signal, a mishmash of countless superpositioned sine waves, not a pure sine wave, I can't just multiply the rectified signal with 0,707.

Do you have an oscilloscope? I think you should first check the signals in the board, before the Arduino. And also check the noise in VCC.

I'm not an expert in amplification and I'm not sure about your tests. I understand that you observe a level of noise of about 5mV in silence, right? Or is it more? And is that audible with headphones?
The level of audio when you have some music is too low with the gain up?

That noise could even be in your power source, EMI from a computer or display around, etc.
You could try to identify the type of noise and it's frequencies. If it is about 20KHz you can try to filter them out. But I imagine that the module already has a low pass filter.

Unfortunately not, I can only try to borrow one. There are no headphones connected to the microcontroller board. Tried various 5V PSUs, but the result is more or less the same. I was hoping that, since this breakout board is quite popular, some audio forum cracks may know what to do, or can say with reasonable confidence that one cannot improve much with these kind of low-cost breakout boards. I could hook up a Behringer or Sennheiser with TRS output to an analog pin via one of the typical microphone input circuits, but that's beside the point - I want to learn how far one can go with this thing.

Putting the noise issue aside, I went ahead with the RMS and then dB(SPL) issue. The approach to calculate RMS with a time window appears to be the correct one, as the signal is based on noise, music or speech, not a pure sine wave. With that, I then calculate dB(SPL) with float audioDB = 20.0 * log10(audioRMS / levelShift); and get results that are 2 to 3 off in comparison with the app mentioned in post #10.

However, the microphone's sensitivity of -44 dBV (0,00631 VRMS) and the amplifier's default gain of 75 x (37 dB) are not accounted for. How should this be done? Maybe I can get a bit closer to what the app shows, and then to an SPL meter. I'd really like to find out how far one can go with this type of breakout board. Thanks!

const byte pinAudioIn = 0;
const byte timeIntervalSampling = 30;
const int levelShift = 512; // 512 for 3,3V AREF as reference voltage, without 337

int sampleCounter;
int audioInRaw;
int audioInRectified;
float audioRMSPrecalc;

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

  analogReference(EXTERNAL); // Use 3,3V AREF as reference voltage, bias = 1,65V
}

void loop()
{
  unsigned long timeSamplingStart = millis();

  while (millis() - timeSamplingStart < timeIntervalSampling)
  {
    audioInRaw = analogRead(pinAudioIn);
    audioInRectified = abs(audioInRaw - levelShift);
    audioRMSPrecalc += ((long) audioInRectified * audioInRectified); // Square each value and add them up

    sampleCounter ++;
  }

  audioRMSPrecalc /= sampleCounter; // Divide by number of samples taken

  float audioRMS = sqrt(audioRMSPrecalc); // Take the square root
  float audioDB = 20.0 * log10(audioRMS / levelShift);

  Serial.print("zero:"); Serial.print(0); Serial.print(" ");
  Serial.print("audioDB:"); Serial.println(audioDB);

  sampleCounter = 0;
}

These are the values from A0 and from the specification sheet I found, lots of different units, and dB is a ratio of two levels.

  • audioInRaw ~ 512 silence, 430 - 590 ~ sound
  • audioInRectified ~ 0 - 15 silence, ~ 0 - 160 sound
  • audioRMS ~ 5 silence, ~ 5 - 35 sound
  1. Reference sound pressure 20 µPa (0dB)
  2. Microphone sensitivity -44 dBV (0,00631 VRMS)
  3. Amplifier gain 75 x (+37 dB)

The formula I took from here

float audioDB = 20.0 * log10(audioRMS / levelShift);

can't be quite right, because it does not take 1., 2., and 3. into account.

So, how can I calculate dB(SPL) the correct way from audioRMS, reference sound pressure, microphone sensitivity and amplifier gain?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.