Help with A01NYUB ultrasonic sensor to measure water tank level

Hi all,

I’m using the A01NYUB with an Arduino Nano ESP32 to measure the water in my water tank. I’m using ESPHome to link it with Home Assistant.

I’m having issues with the readings however. I think my code is ok, but looking at the logs I can see a lot of errors and the values keep jumping from the the expected value to approx 38cm so I think the issue lies in the sensor.

The ultrasonic sensor is attached to a threaded PVC cap looking directly down into the water tank. This is a large cement water tank. Not sure how much water it holds, but think 20,000L type of tank.

Any ideas how I can fix this?

I’m assuming I should keep the bell mouth on as I’d estimate the tank to be a little over 2m tall so it needs a good bit of range. The water shouldn’t come too close to the sensor, I’d say maybe 40cm away if the tank was completely full.

Here’s an example of ESPHome logs:

As you can see most of the readings are errors and when it does get a reading it keeps getting around 38cm which is not accurate and 74cm which I believe to be accurate (I know this because it was 1.4m before it started raining so I do have some valid data to show the tank filling up), but since the majority of readings are 38cm I’m getting bad data in Home Assistant.

I should note that there was a few hours when I did get consistent readings when I first set it up, so it seems that the sensor can work correctly. I’m thinking perhaps it’s temperature related or humidity related or something like that? Could it be caused by echos interfering? If so how could I fix that?

I’ve played around with the code a little bit but can’t seem to fix it

esphome:
  name: water-tank
  friendly_name: Water-Tank

esp32:
  board: esp32-s3-devkitc-1
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: -REDACTED

ota:
  - platform: esphome
    password: -REDACTED

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Water-Tank Fallback Hotspot"
    password: -REDACTED-

captive_portal:
    
# Water Tank - Ultrasonic Sensor A01NYUB

output:
  - platform: gpio
    pin: GPIO10
    id: A01NYUB_Sensor_Power

uart:
    rx_pin: GPIO8
    tx_pin: GPIO9
    baud_rate: 9600

sensor:
  - platform: "a01nyub"
    name: "Water Level"
    id: "Water_Level"
    filters: 
#      - max: 
#        window_size: 60
#        send_every: 300
#        send_first_at: 30
       - quantile:
          window_size: 7
          send_every: 4
          send_first_at: 3
          quantile: .9


## chatgpt code
  - platform: template
    name: "Water Tank Fill Percentage"
    unit_of_measurement: "%"
    lambda: |-
      if (id(Water_Level).state == NAN) {
        return NAN;  // Return NAN if the distance is invalid
      }
      // Calculate percentage based on the distance
      float distance = id(Water_Level).state;
      // Define the max and min distance for full and empty tanks
      float min_distance = 2.00;  // Empty tank distance (in metres)
      float max_distance = .30;   // Full tank distance (in metres)
      
      // Clamp the value between 0 and 100 to avoid out-of-bounds errors
      float percentage = 100.0 * (1.0 - (distance - max_distance) / (min_distance - max_distance));
      // Ensure the percentage is between 0 and 100
      if (percentage < 0) {
        return 0.0;
      } else if (percentage > 100) {
        return 100.0;
      }
      return percentage;

Thanks for taking the time to read.

Cheers

Use a stable and clean 5V source. Voltage fluctuations can lead to wrong readings.

Hi Jason,

Are you able to send through a photo how you have the sensor hooked up? Looking at your code it appears that you’re using a GPIO pin to power the sensor, it should instead be powered from the 3v3 pin of the Arduino.

It’s powered by the 3.3v pin. Ground goes to ground obviously and then I have the blue wire connected to the pin labelled D6 and the green wire to the pin labelled D5 on the PCB.

Today the readings are MUCH more stable, although still not without issue despite not changing anything.

I’m thinking it’s maybe an environmental factor?

From what I understand this would require me to use resistors, etc, as the Arduino ESP32 pins should operate at 3.3v on UART pins?

I was hoping I could limit the equipment to just the microcontroller, sensor and USB power if possible but if it’s necessary to get better readings I could put more effort into it. The sensor is supposed to be compatible with 3.3v

Hi @Jason262112

Powering it from the 3v3 rail on the Arduino is fine in your case, to rule out environment factors you could look at leaving the sensor inside pointing at a wall overnight, in theory it should give you the reliable results if the conditions in the tank are what is causing the issue.

I’m thinking it must be environmental.

From around 11am today the readings have been pretty solid.

Maybe this is a stupid question, but would an ultrasonic sensor be impacted by echo in a solid enclosed location like a cement water tank?

It looks like the tank level percentage filters are doing a better job of filtering the outlying sensor readings so playing around with the filters in both sections of the code might help a bit. So as long as more than half the readings come back accurate it gives me enough data to work with.

While I’d love 100% accurate data at the end of the day I just want to know if I’m running out of water when there’s no rain so I can order a water delivery because a family of 6 with no water isn’t a fun time.

I’ll update if I figure out any more information that could be useful to anyone.

Hi @Jason262112

There is definitely a possibility that there is an echo in the tank that’s giving you the weird readings. I did notice in your logs from earlier posts that you were getting readings every 200ms, given what you’re measuring you could probably drop the sample timing to to every minute, which should limit any interference from echoing