Turn down volume of TV/receiver when it's too loud

Every time we watch TV we have to basically hold the remote in the hand because the volume varies so much.
I thought of an idea. Use a microphone to measure the sound coming out of the center speaker behind the TV and adjust the volume of my Yamaha receiver.

See it in action (with a volume up again after 1 second).
(high number means low volume on this receiver since it’s negative db scale)

I added a gy-max4466 microphone on a breadboard with a ESP8266.
Gave it 3.3 volts, ground and connected the output of the microphone to A0.

With ESPHome you can use the ADC sensor to measure the voltage coming out of the speaker and have it react to values above a threshold like this:

  - platform: adc
    pin: A0
    name: "Sound"
    update_interval: 0.2s
    internal: true
      - above: 0.72 
          - switch.turn_on: snd
      - below: 0.30 # You must have below: but by setting it below the normal baseline it's deactivated. 

I use a GPIO switch in the board because I had problems getting it to work when publishing the values to HA and have an automation run.

ESPHome switch:

  - platform: gpio
    pin: D3 # unused pin, just to make sure it's visible in HA.
    name: "snd"
    id: snd

Now this switch can be used as a trigger in an automation:
This automation runs a script that sets a new volume and turns off the GPIO switch.

- id: '1586697299820'
  alias: Skruva ner
  description: ''
  - entity_id: switch.snd
    platform: state
    to: 'on'
  condition: []
  - data: {}
    service: script.1586684255359
  - data: {}
    entity_id: switch.snd
    service: switch.turn_off

Where the script is:

  alias: New Script
  - service: media_player.volume_set
        entity_id: media_player.yamaha_receiver
        volume_level: >
           {{ states.media_player.yamaha_receiver.attributes.volume_level - 0.10 }}

Yamaha receivers can be controlled within HA with volume up/down or set.
This script uses the current volume and lowers it by 10%.
This can most likely be edited to change the volume of a TV either with API or with a broadlink.

It works beautifully!
You don’t even notice the high sound before it’s already lowered.

But I have thought of some improvements already.
I have two problems. One is soon one year old and the other is soon four years old.
If you also have something like that, they will trigger it to lower the volume since the microphone can’t distinguish TV from kids.
But I will look in to hooking up the ESP directly to the output of the receiver. I will measure what the voltage is on the speaker cables or look at other ways.


Why to not set it proper sound level from the beginning?

1 Like

It’s impossible.
In every movie these days the sound varies too much.
It’s not uncommon that a scene where two people talk in calm matter there is something happening in the background, lets say a car drives by.
Now the sound of that car is so much louder than the talk that you must lower the volume. And that is very annoying.
Same thing with TV-shows, the Swedish version of Who wants to be a millionaire has such a loud intro that if you level the sound to the intro, you will not be able to hear anything of the actual show.

Maybe it’s different where you are. But movies should be the same.

1 Like

I see the problem now.

BTW. Some of the AVRs has this option built-in to keep the volume on proper level.


Can you give details or photos of the sensor you built? I’m just starting out with the custom builds and would love to start with this one - thanks in advance!

Picture is hard since it’s hard to get to behind the TV.

But the microphone chip has three pins.
Vcc, gnd and data.

Data is the pin your ESP needs to read and that is a AC signal.
The gnd is ground.
Vcc is up to 5 volt if I remember correctly and the data pin will have half the voltage as the base.

Meaning if you give vcc 3.3 volt, the data will have 1.65 volt ± the AC signal.
If you give vcc 5 volt then data will have 2.5 volt ± AC signal.

Because of that I went with 3.3 volt, that way I’m far from the maximum 3.5 volt (I believe it is) the ESP chips tolerate.

So the data out from the microphone goes to A0 or any analog input of the ESP and you flash the ESP with ESPHome and the yaml I have above.

You will need to change the thresholds to fine tune it for your needs.

Thank you so much for this - now to get ordering. One last question - power input, how are you doing this? Battery or some sort of adapter?

I have a USB strip behind the TV to power lots of things back there, I just use a output there.
Battery is not a good idea with wifi since it use relatively much power.

Ah yes - I have a USB strip I can use in my WiFi gang plug. Thanks again!!

Or just an old phone charger and a micro cable.

Thanks for the idea… I’ve used in my own automation to turn the volume down on the bedrooms of my children. I don’t mind them sleeping with some music, but 75dB is a bit load :slight_smile: This automation will monitor the sound between 21:30 and 23:00 and lowers it to 30% with 1% increments every 30 seconds. This is my automation so far, just need to figure out how I can monitor more speakers without creating more automations.

alias: Schakeling - Muziek slaapkamers zachter
description: ''
  - platform: time_pattern
    seconds: /30
  - condition: state
    entity_id: media_player.woonkamer
    state: playing
  - condition: numeric_state
    entity_id: media_player.slaapkamer_1
    attribute: volume_level
    above: '0.30'
  - condition: time
    after: '21:30:00'
    before: '23:00:00'
  - service: media_player.volume_set
      entity_id: media_player.slaapkamer_1
      volume_level: |
        {{ states.media_player.slaapkamer_1.attributes.volume_level - 0.01 }}
mode: single