Ultrasonic range finders are fun little modules that measure distance. You can use them to find the precise distance to an object, or also just to detect when something is within range of the sensor (like a motion detector). Ultrasonic range finders are ideal for projects involving robotic navigation, object avoidance, and home security. Because they use sound to measure distance, they work just as well in the dark as they do in the light. The ultrasonic range finder we will be using in this tutorial is the HC-SR04. The HC-SR04 can measure distances from 2 cm to 4oo cm with an accuracy of ±3 mm.

In this article, I’ll show you how to make three different range finder circuits for the Arduino. The first range finder circuit is simple, easy to set up, and has good accuracy. The other two are a bit more complicated, but are more accurate because they factor in temperature and humidity. But before we get into that, lets talk about how the range finder measures distance.

The Speed of Sound

Ultrasonic range finders measure distance by emitting a pulse of ultrasonic sound that travels through the air until it hits an object. When the pulse of sound hits the object, it’s reflected off the object and back to the ultrasonic range finder. The ultrasonic range finder times how long it takes the sound pulse to travel in its round trip journey back to the sensor. It then sends an electrical signal to the Arduino with information about how long it took for the sonic pulse to travel.

Knowing the time it takes the ultrasonic pulse to travel back and forth to the object, and also knowing the speed of sound, we can calculate the distance to the object. The formula relating the speed of sound, distance, and time traveled is:

speed = distance / time

Rearranging this formula, we get the formula we will use to calculate the distance:

distance = speed x time

The time variable will be provided by the ultrasonic range finder as the time it takes for the ultrasonic pulse to leave the sensor, bounce off the object, and return to the sensor. We actually divide this time in half since we only need to measure the distance to the object, not the distance to the object and back to the sensor. The speed variable is the speed at which sound travels through air.

The speed of sound in air changes with temperature and humidity. Therefore, in order to accurately calculate distance, we will need to consider the local ambient temperature and humidity. The formula for the speed of sound in air that factors in temperature and humidity is:

c = 331.4 + (0.606 x T) + (0.0124 x H)

c = Speed of sound in meters per second (m/s)

331.4 = Speed of sound (in m/s) at 0 °C and 0% humidity

T = Temperature in °C

H = % Humidity (relative humidity)

For example, at 20 °C and 50% humidity, sound travels at a speed of:

c = 331.4 + (0.606 x 20) + (0.0124 x 50)

c =  344.02 m/s.

In the equation above, it’s clear that temperature has the largest effect on the speed of sound. Humidity does have some influence, but it’s much less than the effect of temperature.

How the Ultrasonic Range Finder Measures Distance

On the front of the ultrasonic range finder are two metal cylinders. These are transducers. Transducers convert mechanical forces into electrical signals. In the ultrasonic range finder, there is a transmitting transducer and receiving transducer. The transmitting transducer converts an electrical signal into the ultrasonic pulse, and the receiving transducer converts the ultrasonic pulse into an electrical signal. If you look at the back of the range finder, you will see an IC behind the transmitting transducer labelled MAX3232. This is the IC that generates the ultrasonic pulse. Behind the receiving transducer is an IC labelled LM324. This is a quad Op-Amp that amplifies the detected ultrasonic signal into a signal that is strong enough to transmit to the Arduino.

Ultrasonic Range Finder Details

The HC-SR04 ultrasonic range finder has four pins: VccTrig, Echo, and GND. The Vcc pin supplies the power to generate the ultrasonic pulses. The GND pin is connected to ground. The Trig pin is where the Arduino sends the signal to start the ultrasonic pulse. The Echo pin is where the ultrasonic range finder sends the information about the duration of the trip taken by the ultrasonic pulse to the Arduino.

To initiate a distance measurement, we need to send a 5V high signal to the Trig pin for at least 10 µs. When the module receives this signal, it will emit 8 pulses of ultrasonic sound at a frequency of 40 KHz from the transmitting transducer. Then it waits and listens at the receiving transducer for the reflected signal. If an object is within range, the 8 pulses will be reflected back to the sensor. When the pulse hits the receiving transducer, the Echo pin outputs a high voltage signal. The length of this high voltage signal is equal to the the total time the 8 pulses take to travel from the transmitting transducer, be reflected off the object, and travel back to the receiving transducer. However, since we only want to measure the distance to the object, we divide this time in half to get the time variable in the d = s x t equation above. Since the speed of sound is known, we also know the s variable, and now we can solve the equation for distance.

Ultrasonic Range Finder Setup for Serial Monitor Output

Let’s start by making a simple ultrasonic range finder that will output distance measurements to your serial monitor. It’s easy, just wire it up like this:

Arduino Ultrasonic Range Finder

Once you have everything connected, upload this range finding program to the Arduino:

#define trigPin 10
#define echoPin 13

void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

void loop() {
  float duration, distance;
  digitalWrite(trigPin, LOW); 
  delayMicroseconds(2);
 
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  duration = pulseIn(echoPin, HIGH);
  distance = (duration / 2) * 0.0344;
  
  if (distance >= 400 || distance <= 2){
    Serial.print("Distance = ");
    Serial.println("Out of range");
  }
  else {
    Serial.print("Distance = ");
    Serial.print(distance);
    Serial.println(" cm");
    delay(500);
  }
  delay(500);
}

This program outputs the distance readings to the serial monitor, but if you want to output the readings to an LCD, there are instructions below.

Explanation of the Code

Line 11: Declares the variables duration and distance.

Lines 12 and 13: Sends a 2 µs LOW signal to the trigPin to make sure it is turned off at the beginning of the program loop.

Lines 15-17: Sends a 10 µs HIGH signal to the trigPin to initiate the sequence of eight 40 KHz ultrasonic pulses sent from the transmitting transducer.

Line 19: Defines the duration variable as the length (in µs) of any HIGH input signal detected at the echoPin. The Echo pin output is equal to the time it takes the emitted ultrasonic pulse to travel to the object and back to the sensor.

Line 20: Defines the distance variable as the duration (time in d = s x t) multiplied by the speed of sound converted from meters per second to centimeters per µs (0.0344 cm/µs). 

Lines 22-24: If the distance is greater than or equal to 400 cm, or less than or equal to 2 cm, display “Distance = Out of range” on the serial monitor.

Lines 26-30: If the distance measurement is not out of range, display the distance calculated in line 20 on the serial monitor for 500 ms.

Ultrasonic Range Finder With LCD Output

If you want to output the distance measurements to a 16X2 LCD, follow this diagram to connect the range finder and LCD to your Arduino:

Arduino Ultrasonic Range Finder and LCD Diagram

When everything is connected, upload this code to the Arduino:

#include <LiquidCrystal.h>
#define trigPin 10
#define echoPin 13

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

void loop() {
  float duration, distance;
  digitalWrite(trigPin, LOW); 
  delayMicroseconds(2);
 
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  duration = pulseIn(echoPin, HIGH);
  distance = (duration / 2) * 0.0344;
  
  if (distance >= 400 || distance <= 2){
    lcd.print("Out of range");
    delay(500);
  }
  else {
    lcd.print(distance);
    lcd.print(" cm");
    delay(500);
  }
  delay(500);
  lcd.clear();
}

Ultrasonic Range Finder on Arduino With LCD Output

A Higher Accuracy Ultrasonic Range Finder

Since temperature is a variable in the speed of sound equation above (c = 331.4 + (0.606 x T) + (0.0124 x H)), the temperature of the air around the sensor affects our distance measurements. To compensate for this, all we need to do is add a thermistor to our circuit and input its readings into the equation. This should give our distance measurements greater accuracy. A thermistor is a variable resistor that changes resistance with temperature. To learn more about thermistors, check out our article, Arduino Thermistor Temperature Sensor Tutorial. Here is a diagram to help you add a thermistor to your range finder circuit:

Arduino Ultrasonic Range Finder With Temperature Compensation Diagram

R1 = 10K Ohm resistor

Th = 10K Ohm thermistor

Note: the value of R1 should equal the resistance of your thermistor.

After everything is connected, upload this code to the Arduino:

#include <math.h>
#define trigPin 10
#define echoPin 13

double Thermistor(int RawADC) {
 double Temp;
 Temp = log(10000.0*((1024.0/RawADC-1))); 
 Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp ))* Temp );
 Temp = Temp - 273.15;          
 return Temp;
}

void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

void loop() {
  int val;                
  double temp;            
  val=analogRead(0);      
  temp=Thermistor(val);

  float duration, distance;
  float spdSnd;
  digitalWrite(trigPin, LOW); 
  delayMicroseconds(2);
 
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  duration = pulseIn(echoPin, HIGH);
  spdSnd = 331.4 + (0.606 * temp) + 0.62;
  distance = (duration / 2) * (spdSnd / 10000);
  
  if (distance >= 400 || distance <= 2){
    Serial.print("Distance = ");
    Serial.println("Out of range");
  }
  else {
    Serial.print("Distance = ");
    Serial.print(distance);
    Serial.println(" cm");
    delay(500);
  }
  delay(500);
}

In the basic range finder program at the beginning of this article, we only used the formula d = s x t to calculate the distance. In this program, we add the formula for the speed of sound in air (c = 331.4 + (0.606 x T) + (0.0124 x H)) to get a more accurate determination of the speed of sound. In lines 5-10, the Steinhart-Hart equation is used to convert the thermistor resistance values to temperature, which are stored in a variable called temp. In line 35, we add a new variable (spdSnd) which contains the speed of sound equation. The output from the spdSnd variable is used as the speed in the distance function on line 36.

The Very High (Almost Too High) Accuracy Ultrasonic Range Finder

The ultrasonic range finder circuit with temperature compensation is pretty accurate for what most people will use it for. However, there is one more factor affecting the speed of sound in air (and therefore the distance calculation), and that is humidity. You might be able to tell from the speed of sound equation that humidity only has a very small effect on the speed of sound, but lets check it out anyway.

There are several types of humidity sensors you can use on the Arduino, but I will be using the DHT11 humidity and temperature sensor. This module actually has a thermistor in addition to the humidity sensor, so the set up is really simple:

Arduino Ultrasonic Range Finder With Temperature and Humidity

After everything is connected, we will need to install a special library to run the code. The library is the DHTLib library written by Rob Tillaart. The library is easy to install. First, download the .zip file below. Then in the Arduino IDE, go to Sketch>Include Library>Add Library, then select the DHTLib.zip file.

Circuit Basics ZIP Icon DHTLib

After the library is installed, upload this code to your Arduino:

#include <dht.h>

#define trigPin 10
#define echoPin 13
#define DHT11_PIN 7

dht DHT;

void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

void loop() {
  
  float duration, distance;
  float speed;
  
  digitalWrite(trigPin, LOW); 
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  duration = pulseIn(echoPin, HIGH);
  speed = 331.4 + (0.606 * DHT.temperature) + (0.0124 * DHT.humidity);
  distance = (duration / 2) * (speed / 10000);
  
  if (distance >= 400 || distance <= 2){
    Serial.print("Distance = ");
    Serial.println("Out of range");
  }
  else {
    Serial.print("Distance = ");
    Serial.print(distance);
    Serial.println(" cm");
    delay(1000);
  }
  delay(1000);
}

The temperature and humidity readings output by the DHT11 are digital, so we don’t need to use the Steinhart-Hart equation to convert the thermistor’s resistance to temperature. The DHTLib library contains all of the functions we need to get the temperature and humidity in units we can use directly in our equation for the speed of sound. The variables for temperature and humidity in the speed equation on line 27 are simply replaced with DHT.temperature and DHT.humidity, respectively. Then, speed is used as a variable in our distance equation on line 28.

To output the distance measurements of our high accuracy range finder to an LCD, first connect your LCD following our tutorial How to Set Up an LCD Display on an Arduino, then upload this code:

#include <dht.h>
#include <LiquidCrystal.h>

#define trigPin 10
#define echoPin 13
#define DHT11_PIN 7

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

dht DHT;

void setup() {
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

void loop() {
  
  float duration, distance;
  float speed;
  
  digitalWrite(trigPin, LOW); 
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  duration = pulseIn(echoPin, HIGH);
  speed = 331.4 + (0.606 * DHT.temperature) + (0.0124 * DHT.humidity);
  distance = (duration / 2) * (speed / 10000);
  
  if (distance >= 400 || distance <= 2){
     lcd.print("Out of range");
    delay(500);
  }
   else {
    lcd.print(distance);
    lcd.print(" cm");
    delay(500);
  }
  delay(500);
  lcd.clear();
}

Arduino High Accuracy Ultrasonic Range Finder with Temperature and Humidity

Watch the video tutorial for this project here:

Thanks for reading! Leave a comment if you have any questions about how to set these up. If you like our articles here at Circuit Basics, leave your email address in the sidebar at the top of this post and we will let you know when we publish new articles. Also, if you know anyone else that would find this article helpful, please share it!


Need an easy-to-use way to design circuits and layout PCBs?

Try EasyEDA, a free circuit design software that also offers low cost, high quality PCB manufacturing.