HC-SR04 accuracy and comparing values

I’d recently been playing with the HC-SR04 ultrasonic sensor as part of my latest project (more to come on this), however I encountered some issues with its accuracy, especially when comparing values. It took a bit of playing around but I finally got something functioning.

I started with creating a simple rangeFinder() function based on this guide:

float rangeFinder()
  float dur;
  digitalWrite(TRIG, LOW);
  digitalWrite(TRIG, HIGH);
  digitalWrite(TRIG, LOW);
  dur = pulseIn(ECHO, HIGH);
  return (dur/2)/29.1;

This works well for getting the range in cm, however, repeated measures would often yield differing results, as well as some outliers. My first attempt to compensate for this was to use an average of a few results:

float avRange = (rangeFinder()+rangeFinder()+rangeFinder())/3

Which, kinda worked, but there was still too much variation in the averages. After some googling I came across the NewPing library, which promised to improve some of the performance issues with ultrasonic sensors. You can find it here. To some degree it did, but I came across one draw back: that it gave the results to the nearest cm. Well, actually, I found that it just cut anything past the decimal point rather than rounding. My final solution was to use the NewPing library to handle triggering and reading from the HC-SR04 and convert the result to cm’s myself (in this exampe sonar is an instance of NewPing):

float rangeFinder()
  unsigned int uS = sonar.ping_median(10);
  return (uS/2.0)/29.0;

There was still some variance within measurements, when comparing values. So I wrote another function to compare the similarity between two values within a certain amount of tolerance:

boolean compValuesSimilar(float val1, float val2, float tolerance)
  // checks if val1 is similar to val2 based on a percentage of val2
  // tolerance between 0.0 and 1
  // returns true if they're similar
  tolerance = val2*tolerance;
  if (val2 - tolerance < val1 && val1 < val2 + tolerance)
    return true;
  return false;

~ by Jay on August 24, 2014.

3 Responses to “HC-SR04 accuracy and comparing values”

  1. How were your results when measuring short distances with this sensor? I was unable to get accurate readings below 60cm. I wrote about my results here: http://theotherandygrove.com/parallax-ping-hc-sr04-review/


    • Hey Andy, thanks for your comment. You’ve got pretty similar results to mine, I guess you get what you pay for with the HC-SR04! I’m using it to measure ranges between 4 ~ 40cm and it seems to manage that ok-ish. The data sheet says it can go as low as 2cm, but the two I’ve tested get a bit screwy around 3cm. I’ve compensated for this in my design and moved the sensor back a bit. Not the most accurate of sensors, but between the NewPing library and allowing a certain degree of tolerance with the results (around 10%) I get something workable. I’d be interested to see what results you get using NewPing. You might find it useful since it’s geared for using multiple sensors.


  2. […] my previous post on the accuracy of the HC-SR04 ultra-sonic range finder I found that there were issues that needed […]


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: