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.
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:
Rearranging this formula, we get the formula used to calculate distance:
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:
For example, at 20 °C and 50% humidity, sound travels at a speed of:
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.
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.
The HC-SR04 ultrasonic range finder has four pins: Vcc, Trig, 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.
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:
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);
}
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:
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();
}
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:
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 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 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:
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.
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 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();
}
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!