2
\$\begingroup\$

I have to detect sounds levels in an enclosed area, so I thought this could be the right choice.

/*EDIT
I wish to collect sounds levels of about 30-60dB, normally human conversations or just environmental noise. What I really want to achieve with this is to collect sounds that may be noticeable to humans.
*/

I purchased an Electret Microphone with Auto Gain from Adafruit https://www.adafruit.com/product/1713

I am trying to interface it with a raspberry pi 3 to detect sound levels, however, I have not been able to find a solution for it as most of the tutorials are for Arduino or other breakout boards, does anyone have a solution for this?

Understood that the output from the microphone is analog typed and I have an adc converter ADS1115 and MCP3008 that would be useful, but I have not been able to search for the solution that would guide me on using the microphone and the converter.

//EDIT I have been able to hook the sensor to the ADC and MCP, however, the values stay constant and do not seem to change at all, even playing songs into the microphone do not change the values. I get a constant value ranging from 200 to 300 on MCP and around 1056 on ADC.

Followed tutorials on https://learn.adafruit.com/adafruit-microphone-amplifier-breakout/measuring-sound-levels but I need to output them in decibels on RPI, I need to send the data to a server.

I have been using Adafruit's libraries on MCP3008 and ADC1115, am I doing this wrongly?

I need to collect the sound levels in decibels and put them up into a server.

Cheers

\$\endgroup\$
  • \$\begingroup\$ Have you closely and completely followed all the instructions found at their linked page: learn.adafruit.com/adafruit-microphone-amplifier-breakout/… \$\endgroup\$ – jonk Nov 13 '16 at 4:49
  • \$\begingroup\$ @jonk I have followed that tutorial completely, what I am asking here is for a solution that would allow me to use RPI to read the values, and the values I am reading from RPI, does not respond to the "sounds I made". In that tutorial, adafruit only uses arduino, and I was able to pick up voltage values, however, I need sound levels, maybe you could propose how I could convert these values to sound levels, etc in decibels? \$\endgroup\$ – Ming Jin Nov 13 '16 at 4:54
  • 1
    \$\begingroup\$ Voltage values is what you will get. To convert those into something else, like sound levels, you will need to carefully read the datasheet for the mic they use AND the IC with AGC that they use and you will have to develop the mathematics yourself. The mic will have specifications regarding its behavior as a sound pressure transducer. The IC will have more specs. Anyway, it's what I'd do if this were my project. Sit down with the paperwork, haul out some paper, read until I understand fully, then develop the math and then the code. I would propose you do that, too. \$\endgroup\$ – jonk Nov 13 '16 at 4:57
  • \$\begingroup\$ Have you considered doing the sound level-to-dB conversion in the analog domain? \$\endgroup\$ – ThreePhaseEel Nov 13 '16 at 5:00
  • \$\begingroup\$ @jonk sounds fair enough, would be trying this solution first. \$\endgroup\$ – Ming Jin Nov 13 '16 at 5:03
4
\$\begingroup\$

You selected a microphone board with automatic-gain. This is exactly the OPPOSITE of what you need. You can not measure the actual audio levels when there is something upstream UN-doing all the audio level changes ("auto-gain"). So first, you must use the proper microphone module that will deliver the actual, honest, un-modified audio levels to you.

Second, you are trying to measure audio LEVELS, not the actual audio WAVEFORM itself. That means you need to average or integrate the audio signal to produce the "envelope" of the audio levels. You can do this in software by sampling the audio at some high rate and furiously do mathematical calculations, or you can do this much more simply in hardware by rectifying and integrating the audio signal into a moving DC signal which represents the audio LEVEL at any particular moment. Then you can sample and scale this varying DC into deciBels or whatever.

I would very strongly recommend getting a microphone board essentially designed to do exactly what you are proposing. Namely the Sparkfun Sound Detector board. This board has the electret microphone capsule, and also the mic preamp, and a peak detector and an output buffer amplifier. All you need to do is connect the peak detector output from this board to an analog input pin on your Arduino and you have the audio envelope delivered to you on a silver platter. Easy-peasy.

Example: https://www.sparkfun.com/products/12642

\$\endgroup\$
  • \$\begingroup\$ Actually, I need to be able to use this with rpi, considering that I have an ADC/MCP, would I be able to hook the sensor up to it? \$\endgroup\$ – Ming Jin Nov 13 '16 at 6:44
  • \$\begingroup\$ It makes no difference. The SparkFun board delivers a nice DC envelope signal appropriate for ANY microcontroller or ADC. \$\endgroup\$ – Richard Crowley Nov 13 '16 at 7:26
  • \$\begingroup\$ Weirdly, I am having difficulty finding this product locally, may I ask if this alternative be appropriate? sgbotic.com/index.php?dispatch=products.view&product_id=752 Breakout Board for INMP401 (ADMP401) MEMS Microphone \$\endgroup\$ – Ming Jin Nov 13 '16 at 9:30
  • \$\begingroup\$ or this sgbotic.com/… Breakout Board for Electret Microphone \$\endgroup\$ – Ming Jin Nov 13 '16 at 9:31
  • \$\begingroup\$ The sgbotic board is just a "raw" microphone capsule. You would need to connect that to the microphone input of the RasPi and devise some software to take the microphone signal and integrate it into the sound level envelope. $10 seems pretty expensive as a breakout board for a $1 mic capsule. \$\endgroup\$ – Richard Crowley Nov 13 '16 at 13:53
3
\$\begingroup\$

You have the wrong thing, first off

The automatic gain control (AGC) on your existing microphone-board is not what you want here -- a sound level detector is going to get thrown off by the action of the AGC loop changing the gain all over the place as it tries to maintain a constant output level (what else would you expect from an AGC loop?). You might as well just get a cheap electret microphone, such as Sparkfun's, and use it directly in whatever circuit you put together.

Analog logarithms are the way to go here

One of the ground truths of modern, cheap ADCs, especially the ones provided on highly integrated systems, is that their dynamic range is limited by noise on the low end and the low supply voltage available on the high end. Furthermore, taking your logarithms digitally makes poor use of the ADC bits you have available to you -- small changes in signal at the low end cause a relatively large change in the log, but are hard for the ADC to distinguish due to its limited resolution.

As a result of all this, I'd use a linear-in-dB RMS-DC converter chip to convert your sound input to dBs, then feed that detected "control voltage" to your ADC for measurement purposes. Thankfully, this isn't hard -- the RMS-DC converter from a THAT4316 runs happily off 3.3 or 5VDC, and is simple to apply -- an example circuit using it, the Sparkfun electret mic linked above, and the LT1678 low noise dual op amp is shown below.

schematic

simulate this circuit – Schematic created using CircuitLab

OA1A, R5, and R6 are a single-supply, gain = 100 noninverting amplifier serving as a mic preamp with its input biased to the midpoint of the supply range by R2, which also biases the mic. The gain was chosen because the THAT4316 has a minimum input level of 100nA, or 100uV with the resistor chosen, and with the 5mV/Pa sensitivity of the mic chosen, we only get 1uV from the mic for a 30dB input. C5 and R1 AC couple the audio signal to U1 and convert it to a current, respectively, while C2 is the RMS-DC timing capacitor. R3, R4, and OA1B gain up the +/-300mV output swing from U1 to better match the ADC's input range. C1, C3, C4, and C6 provide supply decoupling of various sorts.

Note that C2 and C5 should be film capacitors (not ceramic, electrolytic, or tantalum), and R1, R3, R4, R5, and R6 should be 1% or better resistors, preferably thin film or metal film as they lack excess noise. Also, C3 should connected directly between pin 8 of U1 and the grounded end of C2 -- this keeps current spikes from U1's RMS-DC converter from messing up the rest of the circuit's operation. Finally, if you can't get a LT1678, you'll want to pay attention to the output swing -- you need a part that can pull within a couple hundred mV or so of the negative rail, in addition to running off of a single 3.3V supply with a decent common mode range, and being quiet -- the LT1678 can pull off 4.4nV/root-Hz voltage noise at 10Hz, and with the low Zin (dominated by R2) and the resistor values chosen (tip: Rg dominates Rf when it comes to noise calculations), we are op-amp limited on noise here, albeit not by much.

The resulting signal is a voltage swinging from nearly 0V to nearly 3.3V, with a linear-in-dB transfer function -- the THAT4316's RMS-DC converter has the nice property that the output is 6mV per dB of input level.

\$\endgroup\$
0
\$\begingroup\$

The manufacturer of the microphone says that it's amp output "can be easily used with any Analog/Digital converter that is up to 3.3V input. If you want to pipe it into a Line Input, just use a 1-100uF blocking capacitor in series (100uF sounds best)."

You have two options here:

  • The simplest option: attach USB sound card to the Pi and feed the amp output through a 100uF blocking capacity into the sound card's input. You can then use your program of choice to process the sound. Link to Pi Compatible Sound Card: https://www.adafruit.com/product/1475
  • If for some reason, previous option doesn't meet your need, you can use an Analog to Digital Converter (like the MCP3008 or the ADS1x15(ADS1015 / ADS1115)) and program the Python code needed to interpret converters output. There is a complete guide on how to do that here: https://learn.adafruit.com/raspberry-pi-analog-to-digital-converters/overview (it details the wiring and what python libraries you need to use.) Hope this helps!
\$\endgroup\$
  • \$\begingroup\$ I dont think this is what I need, I have already tried and the output is not what I needed \$\endgroup\$ – Ming Jin Nov 13 '16 at 7:38
  • \$\begingroup\$ Ok. No worries. \$\endgroup\$ – thebunnyrules Nov 14 '16 at 8:28
  • \$\begingroup\$ this answer is right nonetheless. \$\endgroup\$ – jitter Apr 14 at 19:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.