Esp32 inaccurate voltage reading

Hello im having a inaccurate reading on my voltage i have a esp32

see attached files readings and configuration


esphome code
esphome reading

What is your input voltage to the resistor voltage dividers?

0dB attenuation gives a maximum value (at the output of your divider) of 1.1V, so the maximum input you can use is 2.2V. See:

1sec update time should be enough settling time for the ADC storage capacitor to stabilise before making a reading but try increasing the update time and see if that makes a difference.

The only other thing is the output impedance of the sensors connected to your voltage dividers. It could be affecting the voltage divider if it is in the 5k Ohm range or more as it is essentially in series with the 5k1 resistors.

Why not dispose with the dividers and use a larger ADC attenuation (if needed)?

thank you for your reply @tom_l

i dont really understand it because im new to it but im willing to learn the basics,

so i have this A4s board from kinconyIoT, and a submersible water level sensor 24v with 0-5V output, wire are connected to 24v kinconyboard powered by 24v/10A power supply

Sensor - (+)wire connected to 24v (-)wire"black"connected to Ground (s)wire"green"connected to AI1(0-5V)

esphome config: esphome code

Diagram :

i want only to measure the water level by % like if the tank is half = 50% full= 100%

but i got an inconsistent reading , but if the sensor or tank has no water the reading is consistent , but if i put water on it the reading is in consistent .

please help or any suggestion on the code?

thanks

Ok you could be exceeding the ADC input voltage. With the resistor divider the 5v max is 2.5V and with the ESp ADC attenuation set to 0 the maximum allowed input to the ADC is only 1.1v.

Also you need to scale the ADC voltage to take into account that there is a resistor voltage divider in front of the ADC.

Try this:

sensor:
  - platform: adc
    pin: GPIO34
    name: "Water Tank Sensor"
    update interval: 10s # you dont need faster than this.
    accuracy decimal: 0
    attenuation: 11db
    internal: false
    filters:
      - multiply: 1.5106

This should give you a voltage reading pretty close to what you measure on the input to the board.

To get 0-100% full we need to know the relationship between the measured voltage and the tank level.

1 Like

this is my new reading sir it already lessen the noise . i test the reading using voltmeter is 0.419v
Screenshot 2023-06-16 125659

i will use this senor to monitor water level at the same time if the water is low in the tank it will turn on the water pump and if the tank is full it automatic turn off it off, how do i set that in to percentage if the value of the reading is always up and down ?

my pail is full off water for testing first the reading using voltmeter is 0.419v. without water on it its 008.2mv

You can add an averaging filter to reduce noise.

sensor:
  - platform: adc
    pin: GPIO34
    name: "Water Tank Sensor"
    update interval: 3s # you dont need faster than this. Update time will be 30s with the average filter below. 
    accuracy decimal: 0
    attenuation: 11db
    internal: false
    filters:
      - multiply: 1.5106
      - sliding_window_moving_average:
          window_size: 10
          send_every: 10
          send_first_at: 1

To convert this voltage to a % capacity you need to get a voltage reading for at least two known % levels.

e.g.

2.5v , 50%
1v , 13%

You can then use the calibrate filter to convert voltage to % see:

https://esphome.io/components/sensor/index.html#calibrate-linear

1 Like

Now sir im getting this water full

Water full

and this is empty water

empty tank

thanks you @tom_l

sensor:
  - platform: adc
    pin: GPIO34
    name: "Water Tank Sensor"
    update interval: 3s # you dont need faster than this. Update time will be 30s with the average filter below. 
    accuracy decimal: 0
    attenuation: 11db
    internal: false
    unit_of_measurement: "%"  
    icon: "mdi:waves-arrow-up"
    filters:
      - multiply: 1.5106
      - sliding_window_moving_average:
          window_size: 10
          send_every: 10
          send_first_at: 1
      - calibrate_linear:
          # Map from sensor -> to true value
          - 0.475 -> 100.0
          - 0.21451 -> 0

I changed the unit and icon as well as adding the calibration filter.

It looks like you are only using about 10% of the full range of that sensor (0.5v at max instead of 5v). You will have a bit quantisation noise.

1 Like

i already try the code its working the only problem is that the percentage when the pail is full is sometimes 90% then 89% also 96% , im a little bit worry if i try to automate the turning on and off the water pump. maybe the tank will overflow if not accurate hehe.

without water
empty

with full of water
Screenshot 2023-06-16 151628
Screenshot 2023-06-16 151726
Screenshot 2023-06-16 152107

this my testing pail full of water

Ok, so if you are only testing in a bucket this is the reason:

When you install it in your tank it should be considerably more accurate.

Note: you will have to change the calibration points when you move the sensor to your tank.

1 Like

Now i see, if i move it to the tank i only change the value for 100% right ?

Yeah your 0 shouldn’t change.

How deep is your tank?

2M deep i think

Assuming your bucket is about 250mm deep, your new 100% level in the 2m tank, will be in the ballpark of:

0.5V * 2m / 0.25m = 4V

So that will be using 80% of the sensor’s range (4V/5V) and should be much more accurate.

1 Like

I am sorry I only just read this. I have same sensor but went for adding ADS115 to the ESP because it is accurate and could go to the higher voltage. My tank is 3.5m. Once in place pretty accurate.

Next thing is to add a template calculation to show volume litres

I think this would be a subject/ project worth adding to ESPHOME page

Thank you i will post the result once implemented in actual tank.

Nice i would like to know how you show the volume liters in home assistant frontend thank you :slight_smile:

What shape is your tank?

Like this

The hemisphere on the top and bottom will complicate the calculations. If you ignore those and just assume it is a cylinder it should be easy to convert % level to Litres with a template sensor in ESPHome.