Possibly a basic question - but stuck!


I’m trying to read the output envelope from a Sparkfun Sound Detector with an ESP32. It outputs an analogue value. However I do not want to read it as a voltage, I need to see it as Arduino would - i.e. 0-1023 so I can do the conversion to decibels.

Am I missing something - can I not read the numbers going to the pin directly or must I use the ADC route which seems a bit bizarre as the voltages are not so easy to convert!

Thanks in advance.

You could try a filter and add a unit of measurement:

  - platform: adc
    pin: A0
    name: "Sound Detector"
    update_interval: 10s
      - calibrate_linear:
          - 0.0 -> 0.0
          - 1.0 -> 1023
    unit_of_measurement: 'dB'

Also, see the note on here if you are using an EPS32:

I’ve tried that - just can’t seem to get a sensible result. On an ESP32-S it gives 1.1 all the time, on a generic board I get a reading but it jumps about so much it makes no sense (tried with the envelope pin on the sound detector + the “out” from two other mics. I don’t think ESPHome likes to play with microphones judging by the lack of support for them as a sensor and the apparent lack of i2s support.

I guess I’ll have to use the arduino IDE and MQTT to get some info into HA :frowning:

How have you wired it up? 5V and ground, then envelope directly to an analogue input?

The docs say:

On the ESP32, the voltage measured with the ADC caps out at 1.1V by default as the sensing range or the attenuation of the ADC is set to 0db by default.

…and then explains how to use attenuation to get around that.

The Sparkfun board is very sensitive by default, and might need a resistor in R17 to calm it down a bit (doc).

Not sure what you mean by this: what “numbers”? The Sparkfun board’s envelope output is an analogue voltage that tracks the peaks of the audio waveform. You have to read it as a voltage, as that’s what it is. @Holdestmade’s solution above converts that voltage into the numbers you’re looking for, although the numbers he gives are for the ESP8266 (A0, 1.0V limit).


Yes - it’s wired up 5v + GND and Envelope is sent off to GPIO32. I’ve tried attenuation at 11db, nothing much changes. The problem is at 40db (quiet) nothing is registered. Once you move up into a known level (65db) the responses are truly random - ranging from 0.00v to 1.70v (at attenuation 11db).

Putting it back to attenuation 0db and using some reference points, at 65db it still manages to go way up to around 85db which is very loud. Code excerpt :frowning:

     - calibrate_linear:
         - 0.0 -> 0.0
         - 1.1 -> 1024.0
     - lambda: |-
         if (x < 10) {
           return 49.5 + (20. * log10(x/10.));
         if (x > 10 && x < 30) {
           return 65. + (20. * log10(x/12.));
         if (x > 30) {
           return 70. + (20. * log10(x/17.));

I think there’s too much electrical noise on my test board. I’ll try some other things and see what happens. Thanks for the pointers and info :slight_smile:

Quick update - got it all working by using the Arduino IDE and MQTT. Now the dB level is shown on an OLED on the front of my amplifier :slight_smile:

1 Like

Very nice. What was the solution to your problem, in the end?

Good old Technics, with their “Variable Gain”, giving them the competitive advantage over other integrated amplifiers :face_with_monocle:

I switched to using an INMP441 mic with i2s and an example from github. It samples once a second and I added support for MQTT. The sensor pings a DB level every second and sends it to the pictured ESP8266 with 1.3" OLED screen (cycles through time, temp, humidity, noise level, weather and depending if there’s something playing it shows the track and artist)

I have a lot of Technics stuff :slight_smile:

1 Like