Why accuracy of ultrasonic sensor HC-SR04 so bad for water level?

Hello, i had a problem when using ultrasonic HC-SR04

when i use it for measure water level, it accurate when a distance between sensor and water is 17 cm until 8 cm. but its going bad when distance between sensor and water is 7 cm until 2 cm.

any body know why this is happen?

this is code that i used

// ---------------------------------------------------------------------------
// Example NewPing library sketch that does a ping about 20 times per second.
// ---------------------------------------------------------------------------

#include <NewPing.h>

#define TRIGGER_PIN  2  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     3  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

void setup() {
  Serial.begin(9600); // Open serial monitor at 115200 baud to see ping results.

void loop() {
  delay(50);                     // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
  int Ping = sonar.ping();
  int Dist = (Ping*0.034)/2; 
  Serial.print("Ping: ");
  Serial.print(Ping); // Send ping, get distance in cm and print result (0 = outside set distance range)
  Serial.print(" Dist: ");

Have you checked your sensor against a wall? Does it show the same behavior? What is a bad accuracy for you? Do you have values to show that?

yes i had checked my sensor against the wall, and the value was good.

this is calibration test of my sensor


Does your water have waves?


You might find this page of interest: https://www.davidpilling.com/wiki/index.php/HCSR04

I am interested in (developing) a (liquid level) sensor to target distance around 100 mm and changes of that distance always less than 25 mm....My aim is a quick response to level changes and an accuracy of 1 mm.

The result of all (of my work) is that a modified HC-SR04 can measure tiny (changes in) distances.

Paul_KD7HB: Does your water have waves?


no i read the height when water in calm state

I know this doesn’t answer your question directly, but you could measure water level with a capacitive sensor. You can make one of these as per the attached picture, and measure the value with the capacitor library (search for “capacitor” in the library manager). It would need some manual calibration, but you should be able to achieve a resolution down to millimetres.

Sounds like your ultrasonic transducer has significant ring-down after the pulse, which is causing false readings at short distances - or there is a poor choice of threshold at these ranges. It seems enough that the nature of the surface has a large effect on the reliability of the readings.

At 30kHz a wavelength is about 1cm, so 8cm is only 8 waves. Typical pings sent out on such devices are a few cycles, perhaps 4 cycles, ie about 4cm in length.

If the transducer is too resonant it will stretch the pulse out and reduce the attack rate at the start of the pulse, which is crucial to good resolution. For short range the transducer is still vibrating (ring-down) when the reflection hits it again.

The receiving circuitry has to dynamically adapt its gain or threshold with time to allow for attenuation of the signal over longer distances, and this curve needs to match the signal well for accurate detection over a range of different surface reflectivities - essentially it has to catch the first pulse rising edge.

Basically I think most cheap ultrasonic sensors are likely to have issues at close range (and of course long range), so I can only suggest try a few different devices... But as I understand it most cheap devices are resonant by the nature of their construction, and trying to use them off-resonance severely limits range and efficiency.

From the link in post #4, the author found that there is significant "lack of monotonicity" at short range. The following is his test starting at a range of 75 mm (the origin of the graph has been shifted so that 75 = 1):


One would expect a straight line between the origin and the point (17 mm, 94 us). The error could be as much as 10 mm using a "straight" HC-SR04. Adding tubes and using the author's technique of checking the "envelope," the error is smaller.

The author opines that this is the result of cross talk between the transmitter and receiver transducers, and he found an essentially straight line when using two different HC-SR04s...one as transmitter and one as receiver:




I’d try bouncing the echo off something floating on the water rather than off the surface of the water.

Water surface bounces ultrasound waves very well, no need to float something.

The 2-7 cm distance is at the limit of what these sensors are rated to do. I've had pretty good results in those ranges but instabilities may happen. And you need sufficient time between readings.

DaveEvans: From the link in post #4, the author found that there is significant "lack of monotonicity" at short range. The following is his test starting at a range of 75 mm (the origin of the graph has been shifted so that 75 = 1):

The ripple suggests the unit uses 43kHz, ie a wavelength of about 8mm, hence the periodicity at one half that (roundtrip distance is twice actual distance).