Ultrasonic range finders are fun little modules that measure distance. You can use them to find the distance to an object, or to detect when something is near the sensor like a motion detector. They’re ideal for projects involving 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 I’ll be using in this tutorial is the HC-SR04, which can measure distances from 2 cm up 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 easy to set up, and has pretty good accuracy. The other two are a bit more complicated, but are a bit more accurate because they factor in temperature and humidity. But before we get into that, lets talk about how the range finder measures distance.

BONUS: I made a quick start guide for this tutorial that you can download and go back to later if you can’t set this up right now. It covers all of the steps, diagrams, and code you need to get started.

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 that pulse of sound hits an object, it’s reflected off the object and travels back to the ultrasonic range finder. The ultrasonic range finder measures how long it takes the sound pulse to travel in its round trip journey from the sensor and back. It then sends a 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, the Arduino can calculate the distance to the object. The formula relating the speed of sound, distance, and time traveled is:

speed = \frac{distance}{time}

Rearranging this formula, we get the formula used to calculate distance:

distance = speed \ \times \ time

The time variable is 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’ll need to consider the ambient temperature and humidity. The formula for the speed of sound in air with temperature and humidity accounted for is:

c = 331.4 + (0.606 \times T) + (0.0124 \times H) \\  \\ c: \ Speed \ of \ sound \ in \ meters \ per \ second \ (m/s) \\  331.4: \ Speed \ of \ sound \ (in \ m/s) \ at \ 0 \ ^{\circ}C \ and \ 0 \% \ humidity \\  T: \ Temperature \ in \ ^{\circ}C \\  H: \ \% \ Humidity \ (relative \ humidity)

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

c = 331.4 + (0.606 \times 20) + (0.0124 \times 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 reflected ultrasonic pulse back 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 controls the transmitting transducer. Behind the receiving transducer is an IC labelled LM324. This is a quad Op-Amp that amplifies the signal generated by the receiving transducer into a signal that’s 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 total time the 8 pulses take to travel from the transmitting transducer and back to the receiving transducer. However, we only want to measure the distance to the object, and not the distance of the path the sound pulse took. Therefore, we divide that time in half to get the time variable in the d = s x t equation above. Since we already know the the speed of sound (s), 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. If you want to output the readings to an LCD instead, check out the next section. Connecting everything is easy, just wire it up like this:

Arduino Ultrasonic Range Finder

Once you have everything connected, upload this 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);
}

 

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’s 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

If you need more help connecting the LCD, try our other tutorial on setting up an LCD on the Arduino. 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);
}

 

Explanation of the Code

In the basic range finder program at the beginning of this article, we used the formula d = s x t to calculate the distance. In this program, we use the formula that accounts for temperature and humidity (c = 331.4 + (0.606 x T) + (0.0124 x H)).

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 temperature compensated ultrasonic range finder circuit is pretty accurate for what most people will use it for. However, there’s another factor affecting the speed of sound in air (and therefore the distance calculation), and that is humidity. You can tell from the speed of sound equation that humidity only has a 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’ll 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 ZIP 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);
}

 

Explanation of the Code

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 needed to get the temperature and humidity in units we can use directly in the speed of sound equation. The variables for temperature and humidity are named DHT.temperature and DHT.humidity. Then, speed is used as a variable in the distance equation on line 28.

To output the distance measurements 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 to see the ultrasonic range finder circuits in action:

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, subscribe and we’ll let you know when we publish new articles. Also, if you know anyone else that would find this article helpful, please share it!