ESPHome adc scatter is too big

I am trying to read values from my 3.8V battery through 47kOm divider with ESP32. But values scattered to much:

ESPHome sensor code
  - platform: adc
    pin: 35
    name: "E-ink Battery Volts"
    id: eink_display_battery_volts
    update_interval: 3000ms
    attenuation: auto 
    accuracy_decimals: 3
    internal: false

Since this project is working for several seconds every 10 minutes, even averaging is not showing data useful for calculating battery percentage.

Where problem can be?

It varies by .03v or 1.5%. That is very minimal

Since not all voltage from battery is useful voltage, that means after convertion to battery percentage it is ~10% mistake, which is too much

	  - platform: adc
    pin: A0
    name: esp12f Battery
    id: battery_voltage_12f
    filters:
      - multiply: 4.8208
    accuracy_decimals: 3
    update_interval: 60s

What is your code for battery like

This is my battery over 3 days. Sometimes it reads same value every 10mins for 6 hrs straight. I take it the ESP32 can read up to 3V on its ADC pins. Is your 3.8V battery a lithium battery? I suspect your voltage divider resistor is too small.

My code is:

  - platform: adc
    pin: 35
    name: "E-ink Battery Volts"
    id: eink_display_battery_volts
    update_interval: 3000ms
    attenuation: auto 
    accuracy_decimals: 3
    internal: false

I change two 47 kOm to two 150 kOm, and looks like it dosn’t become better:


I am newbie in electronics, so don’t really know, what I am doing wrong… Shall I change resistors to somthing even bigger?

Much bigger resistors wont help. You mentioned checking voltage every 10mins but it looks like you are checking every 3 seconds. I take it you are putting the ESP32 into deepsleep? My device sleeps for 10 or 5 mins depending on battery and takes a temp reading and voltage reading then goes back into deepsleep after few seconds (as soon as HA reports it got readings from ESP).
I use an ESP12f which can only measure up to 1V

Voltage divider

So I then take 4.2V/0.84 and get the multiplication filter of 5. This needs adjusting as there are other resistances I haven’t measured.

You need to work out the internal resistance of the ESP if you don’t already know
Use Voltage divider calculator You need to measure the actual voltage across your source battery and use that along with your raw voltage shown on the ESP( which needs to be lower than 3V for ESP32 and lower than 1V for my ESP12f) and along with your 47K resistor and you will get value of internal resistor R2 and then use calculator to work out what R1 (currenlty 47k) needs to be to bring the output voltage closer to 3V. 2x47K may be enough. Resistors in a breadboard are prone to odd values due to bad contact. Once they are soldered into a project they should read more stable.
Having said all that I would recommend running ESP with deepsleep on first to see if that makes readings more stable.

https://esphome.io/components/sensor/adc.html

The above link suggest ESP32 also only reads to 1.1V unless certain values changed. Lots of variables to be changed. If too high a voltage across ADC you will damage the pin.
attenuation: auto might be the best setting

Looking at your graph the biggest changes are voltages drops. How are you using your 3.8V battery to power an ESP32. Are you using an LDO regulator to boost it up to 5V to power via 5V pin or dropping it to 3.3V for 3.3V pin?

ESP ADC has a voltage range of 0 … 1V.
Some ESP boards already include a voltage divider, i.e. D1 mini has a divider 220k : 100k which results in a range of 0 … 3.2V on its A0 pin. In this case you can further extend the range by adding a single resistor (NOT another voltage divider) in front of A0. This resistor adds to the internal 220k.

In case of noisy measurements on ADC please also consider RF interference. After all your measuring input is just millimeters away from a bursting WiFi antenna. We just had a discussion about that (see link below). You may want to add a 100nF bypass capacitor directly between ADC/A0 and GND, as close as possible to the pins.

1 Like

0 - 1v1 in the case of an esp32.

1 Like

When a attenuation of 0db is used. Setting attenuation to auto should give a range of ~0.075V to ~3.12V.

Since version 2021.11 of esphome the esp32 also use calibration data to have more accurate readings (not necessarily with less scatter)

1 Like

Perhaps the original poster could draw us a diagram of his circuit, so could see how battery and sensors all connect to ESP32.

If we are talking about ttgo t5 e-ink

Just is need this:

###

  - platform: adc
    pin: 35
    name: "${dev} Battery Level"
    update_interval: 30s
    attenuation: 11db
    filters:
      - multiply: 1.84
    accuracy_decimals: 2
    id: battv

###

Wondering if you ever solved your large changes of battery voltage? I recently had a similar problem and it was solved by fitting a pulldown resistor to a switching transistor.

I now have different issue, so full esp project not working. But thank you for advice! Will look into it, when will fix current issue.