Accurate water level monitoring

I have followed some other peoples ideas and connected a fuel tanks sensor (Water Fuel Level Sender Tank Level Sending Unit Car Marine Boat 240-33 ohms AU | eBay) to a ESP32. Very similar setup to Water tank - water level sensor using fuel/water sender and esphome

I have setup a voltage divider (I can’t remember the resistance I ended up using, but it’s around 200 Ohms) and I get a range of voltages from about 0.6V to 2V.

The problem is that the ESP32 only seems to pickup about 15 steps for the entire 240mm range. I would like the measurements to be much more accurate then that. Does anyone have any experience with getting accurate ADC values? Is it a limitation of the ESP32? From testing the sensor the resistance seems to change linearly with the depth

My config is included below:

esphome:
  name: esp32-devkitc-water-level

esp32:
  board: esp32dev
  framework:
    type: arduino

...

sensor:
  - platform: adc
    pin: GPIO32
    name: "Raw Water Level Voltage"
    id: water_raw_voltage
    unit_of_measurement: "V"
    update_interval: 120s
    attenuation: auto
    accuracy_decimals: 3

  - platform: adc
    pin: GPIO32
    name: "Water Level Poly Offset"
    id: water_offset
    unit_of_measurement: "mm"
    update_interval: 120s
    attenuation: auto
    accuracy_decimals: 3
    filters:
      - calibrate_polynomial:
          degree: 3
          datapoints:
            - 2.050 -> 0
            - 1.627 -> 10
            - 1.626 -> 20
            - 1.619 -> 30
            - 1.554 -> 40
            - 1.477 -> 50
            - 1.466 -> 60
            - 1.475 -> 70
            - 1.389 -> 80
            - 1.386 -> 90
            - 1.389 -> 100
            - 1.189 -> 120
            - 1.187 -> 130
            - 1.041 -> 140
            - 1.038 -> 150
            - 0.870 -> 160
            - 0.868 -> 170
            - 0.632 -> 180
            - 0.630 -> 190

I use ESP32 and it has full 4095 increments available. I set the attenuation to manual setting; I didn’t want it changing around during operation. I am also using ADS115 for an application with higher voltage and more accuracy. For what it is worth my template is below … very different use case. Have you read the ESPHome ADC page? Useful discussion on the ESP32.

  - platform: adc
    pin: GPIO33
    name: "Wind Direction"
    id: winddirection1
    icon: mdi:compass-rose
    unit_of_measurement: "º"
    update_interval: 10s
    accuracy_decimals: 0
    attenuation: 11db
    raw: True
    filters:
      - calibrate_linear:
          - 0.0 -> 0.0
          - 4095-> 360
      - offset: 5
      - sliding_window_moving_average:
          window_size: 20
          send_every: 6



Thanks, so it sounds like I should be able to get more information then.

I have read through the documentation, it recommends against using raw values (Analog To Digital Sensor — ESPHome), but it seems like that’s the best bet to get more accurate measurements.

Well, for my example I used a sender closer to 1m long but even so I would suggest you should be able to get more than 15 steps out of the 240mm version - again, just use the log option and you will almost certainly see the settings change with the slightest movement of the float. I just used ten points but if it wasn’t for the fact I’m lazy I am certain I could have easily done 100. I’d suggest perhaps reviewing the pullup resistor, and/or you could also try increasing the number of decimal points you’re using.

Cheers!

I have checked the log of the voltages, but I only get about 10 steps. Are you using raw values to get more then that?

If you are hunting down and eliminating sensor or ESP32 I would start by setting to raw and then read what the value is if the open pin is taken to ground and then to reference voltage 3.3v. pin. Gnd should be 0 and 3.3v should be 4095. That will ensure the ESP is working.