How to use a HC-SR04 Ultrasonic Distance Sensor with Arduino

How to use a HC-SR04 Ultrasonic Distance Sensor with Arduino

The HC-SR04 is an inexpensive, easy to use distance sensor, with a range of 2 to 400cm. It is commonly used in obstacle avoiding robots and automation projects. Did you know that your car uses similar sensors in the parking assist system? 

In this tutorial you will learn how the sensor works and how to use it with Arduino. I have included 5 examples with a wiring diagram and code so you can start experimenting with your sensor.

What this article covers

Other distance/proximity sensor tutorials

How does an ultrasonic distance sensor work?

Ultrasonic sensors work by emitting sound waves with a frequency that is too high for a human to hear. These sound waves travel through the air with the speed of sound, roughly 343 m/s. If there is an object in front of the sensor, the sound waves get reflected back and the receiver of the ultrasonic sensor detects them. By measuring how much time passed between sending and receiving the sound waves, the distance between the sensor and the object can be calculated.

At 20°C the speed of sound is roughly 343 m/s or 0.034 cm/µs. Let’s say that the time between sending and receiving the sound waves is 2000 microseconds. If you multiply the speed of sound by the time the sound waves traveled, you get the distance that the sound waves traveled. 

Distance = Speed x Time

But that is not the result we are looking for. The distance between the sensor and the object is actually only half this distance because the sound waves traveled from the sensor to the object and back from the object to the sensor. So you need to divide the result by two.

Distance (cm) = Speed of sound (cm/µs) × Time (µs) / 2

And so for the example this becomes:

Distance (cm) = 0.0343 (cm/µs) × 2000 (µs) / 2 = 34.3 cm

Temperature dependence of the speed of the speed of sound​

The speed of sound actually depends strongly on temperature and to a far lesser degree on the humidity of the air. Wikipedia states that the speed of sound increases with roughly 0.6 m/s per degree Celsius. For most cases at 20°C you can just use 343 m/s but if you want to get more accurate readings, you can calculate the speed of sound with the following formula:

V (m/s) = 331.3 + (0.606 × T)

V = Speed of sound (m/s)
T = Air Temperature (°C)

This formula doesn’t include the humidity since its effect on the speed of sound is only very small.

Below you can find a tutorial on how to use a DHT11 temperature and humidity sensor to calibrate the speed of sound and get a more accurate distance reading with the HC-SR04.

How the HC-SR04 works

At the front of the HC-SR04 sensor you can find two silver cylinders (ultrasonic transducers), one is the transmitter of the sound waves and the other is the receiver. To let the sensor generate a sonic burst, you need to set the Trig pin high for at least 10 µs. The sensor then creates an 8 cycle burst of ultrasound at 40 kHz. 

This sonic burst travels at the speed of sound, bounces back and gets received by the receiver of the sensor. The Echo pin then outputs the time that the sound waves traveled in microseconds. 

How does the HC-SR04 ultrasonic distance sensor work

You can use the pulseIn() function in the Arduino code to read the length of the pulse from the Echo pin. After that, you can use the formula mentioned above to calculate the distance between the sensor and the object.

HC-SR04 Specifications

HC-SR04Specifications
Operating voltage5V
Operating current15mA
Frequency40 kHz
Measuring range2 - 400 cm
Resolution3 mm
Measuring angle15 degrees
Trigger input signal10µs high pulse

For more information you can check out the datasheet here.

Now let’s take a look at how to wire up the sensor and then I will show you some example codes.

Things used in this tutorial:

Hardware components

Parts are available on Amazon via the links below. You can click the plus sign on the right for additional information about the specific item.
NameQuantityDescriptionBuy
HC-SR04 sensorx 1Ultrasonic distance sensor with 2 - 400 cm range.Buy Now
Arduino UNO R3x 1You can also use other microcontrollers like an Arduino Mega or esp32.Buy Now
Breadboardx 1I highly recommend to buy at least 1 good quality breadboard like the BusBoard Prototype Systems BB400 or BB830.Buy Now
Jumper wires~ 10-Buy Now
USB Type-B cablex 1Used to power the Arduino UNOBuy Now
DHT11 sensor (optional)x 1Temperature and humidity sensor to calibrate the speed of sound.Buy Now
2004 I2C LCD (optional)x 11602 I2C LCD can also be used.Buy Now

Software

PictureNameLink
Arduino-LogoArduino IDE

*Note: the above links are affiliated which means – at no additional cost to you – if you purchase anything using them you’re helping to support my work on this site. My humble thanks (I really appreciate it)! 

Wiring – Connecting HC-SR04 to Arduino UNO

The wiring diagram below shows you how to connect the HC-SR04 sensor to the Arduino. 

HC-SR04 with Arduino UNO wiring
HC-SR04 with Arduino wiring diagram

The code examples below use digital pin 2 and 3 for the trigger and echo pin, but of course you can change this to any digital pin you want.

HC-SR04 Connections

HC-SR04Arduino
VCC5V
TrigPin 2
EchoPin 3
GNDGND

Example code for HC-SR04 with Arduino

Now that you have wired up the sensor it is time to connect the Arduino to the computer and upload some code. You can upload the following example code to your Arduino using the Arduino IDE. Next, I will explain you how the code works.

/*
HC-SR04 Ultrasonic Distance Sensor with Arduino Example Code
More info: https://www.makerguides.com
*/

//Define Trig and Echo pin
#define trigPin 2
#define echoPin 3

//Define variables
long duration;
int distance;

void setup() 
{
//Define inputs and outputs
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);

//Begin Serial communication
Serial.begin(9600); // Starts the serial communication at a baudrate of 9600
}

void loop()
{
//Clear the trigPin by setting it LOW
digitalWrite(trigPin, LOW);
delayMicroseconds(5);

//Trigger the sensor by setting the trigPin high for 10 microseconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);

//Read the echoPin. pulseIn() returns the duration (length of the pulse) in microseconds.
duration = pulseIn(echoPin, HIGH);
// Calculate the distance
distance= duration*0.034/2;

//Print the distance on the Serial Monitor (Ctrl+Shift+M)
Serial.print("Distance = ");
Serial.print(distance);
Serial.println(" cm");
delay(50);
}

How the code works

First, the trigger pin and the echo pin are defined. I call them trigPin and EchoPin. The trigger pin is connected to digital pin 2 and the echo pin to digital pin 3 on the Arduino.

The statement #define is used to give a name to a constant value. The compiler will replace any references to this constant with the defined value when the the program is compiled. So everywhere you mention trigPin, the compiler will replace it with the value 2 when the program is compiled.

//Define Trig and Echo pin
#define trigPin 2
#define echoPin 3

Next I defined two variables: duration and distance. Duration stores the time between sending and receiving the sound waves. The distance variable is used to store the calculated distance.

//Define variables
long duration;
int distance;

In the setup(), you start by setting the trigPin as an output and the echoPin as an input. Next you initialize serial communication at a baud rate of 9600. Later you will display the measured distance in the serial monitor, which can be accessed with Ctrl+Shift+M or Tools > Serial Monitor. Make sure the baud rate is also set to 9600 in the serial monitor.

void setup()
{
//Define inputs and outputs
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);

//Begin Serial communication
Serial.begin(9600); // Starts the serial communication at a baud rate of 9600
}

In the loop(), you trigger the sensor by setting the trigPin HIGH for 10 µs. Note that to get a clean signal you start by clearing the trigPin by setting it LOW for 5 microseconds.

void loop() 
{
//Clear the trigPin by setting it LOW
digitalWrite(trigPin, LOW);
delayMicroseconds(5);

//Trigger the sensor by setting the trigPin high for 10 microseconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);

Next, you need to read the length of the pulse sent by the echoPin. I use the function pulseIn() for this. This function waits for the pin to go from LOW to HIGH, starts timing, then waits for the pin to go LOW and stops timing.

After that you calculate the distance by using the formula mentioned in the introduction of this tutorial.

//Read the echoPin. This returns the duration (length of the pulse) in microseconds.
duration = pulseIn(echoPin, HIGH);

//Calculate the distance
distance= duration*0.034/2;

Finally, print the calculated distance in the serial monitor.

// Print the distance on the Serial Monitor (Ctrl+Shift+M)
Serial.print("Distance = ");
Serial.print(distance);
Serial.println(" cm");
delay(50);
}

Example code HC-SR04 with Arduino and NewPing library

The NewPing library written by Tim Eckel can be used with many ultrasonic distance sensors. The latest version of this library can be downloaded here on bitbucket.org. You might notice that the code below, which uses the NewPing library, is a lot shorter than the code we used before. Besides that, the NewPing library does include some other nice features. It allows you to set a max distance to read, it won’t lag for a full second when no echo is received and it has a built-in median filter.

You can install the library by going to Sketch > Include Library > Add .ZIP Library in the Arduino IDE.

The library does include some examples that you can use, but you will have to modify them to match your hardware setup. I have included a modified example code below that can be used with the same wiring setup as before.

/* HC-SR04 Ultrasonic Distance Sensor with NewPing library Example Code. More info: www.makerguides.com */

#include <NewPing.h>

//Define pins and max distance
#define trigPin  2
#define echoPin  3
#define MAX_DISTANCE 350 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

NewPing sonar(trigPin, echoPin, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
float duration, distance;

void setup() {
Serial.begin(9600); // Open serial monitor at 9600 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.
duration = sonar.ping();
distance = (duration / 2) * 0.0343;
Serial.print("Distance = ");
Serial.print(distance);       // Distance will be 0 when out of set max range.
Serial.println(" cm");
}

You can also use  distance = sonar.ping_cm()  or distance = sonar.ping_in() which returns the measured distance in whole centimeters or  inches. With this function you do not need to take a duration measurement and calculate the distance.

Interfacing ultrasonic sensors in 3 pin mode

The NewPing library also makes it easy to interface with ultrasonic sensors while using only 1 I/O pin. This can be handy if you have very few I/O pins available or if you want to use a 3 pin ultrasonic sensor like the Parallax Ping.

To create a 3 pin setup (GND, 5V and SIG) you have to connect both the trigger pin and the echo pin to the same digital pin on the Arduino. In the code, the only thing you have to change is line 6-7 and define the same pin for both the trigPin and the echoPin. For example digital pin 2.

//Define Trig and Echo pin
#define trigPin 2
#define echoPin 2

How to use ping_median() digital filter

The main thing I like about the NewPing library is that it has a built-in median filter. This filter can greatly improve the accuracy of your HC-SR04 readings. The ping_median() function takes many duration measurements in a row, throws away the out of range readings and then averages the remaining ones. By default it will take 5 readings but you can specify how many it should take. Replace line 19 with below lines.

int iterations = 5;
duration = sonar.ping_median(iterations);

Example code HC-SR04 with I2C LCD and Arduino

To display the measured distance on a 2004 or 1602 I2C LCD, all you have to do is make the following connections and upload the code below. The HC-SR04 sensor is connected in the same way as before.

HC-SR04 with I2C LCD and Arduino UNO wiring
HC-SR04 with Arduino and I2C LCD wiring diagram

I2C LCD Connections

I2C LCDArduino
GNDGND
VCC5V
SDAA4
SCLA5

The code uses the LiquidCrystal_I2C library, which you can download here on GitHub. It also includes the Wire.h library, which allows you to communicate with I2C devices. It should come pre-installed with the Arduino IDE.

If you want to learn more about how to control a I2C LCD with Arduino, you can check out the full tutorial here.

You can click the button in the top right corner of the code field to open the complete code in a new window.

/*
HC-SR04 Ultrasonic Distance Sensor with Arduino and I2C LCD Example Code
More info: https://www.makerguides.com
*/

//Include the libraries
#include <Wire.h>
#include <LiquidCrystal_I2C.h>


//Define Trig and Echo pin
#define trigPin 2
#define echoPin 3

//Define SDA and SCL pin for LCD
#define SDAPin A4 //Data pin
#define SCLPin A5 //Clock pin

//Connect to LCD via I2C, default address 0x27 (A0-A2 not jumpered)
LiquidCrystal_I2C lcd(0x27,20,4); //Change to (0x27,16,2) for 1602 LCD 

//Define variables
long duration;
int distance;

void setup()
{
//Define inputs and outputs
pinMode(trigPin, OUTPUT); 
pinMode(echoPin, INPUT); 

//Initiate the LCD
lcd.init();
lcd.backlight();
}

void loop()
{
//Clear the trigPin by setting it LOW
digitalWrite(trigPin, LOW);
delayMicroseconds(5);

//Trigger the sensor by setting the trigPin high for 10 microseconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);

//Read the echoPin. This returns the duration (length of the pulse) in microseconds.
duration = pulseIn(echoPin, HIGH);

//Calculate the distance
distance = duration*0.034/2;

//Display the distance on the LCD
lcd.setCursor(0,0); //Set the cursor to column 1, line 1 (counting starts at zero)
lcd.print("Distance = "); //Prints string "Display = " on the LCD
lcd.print(distance); //Prints the measured distance
lcd.print(" cm  "); //Prints "cm" on the LCD, extra spaces are needed to clear previously displayed characters
delay(50);
}

Note that I used a 20 x 4 LCD display. If you have a different size LCD (16 x 2 is also common) you need to change line 20 to LiquidCrystal_I2C lcd(0x27,16,2);. If your LCD doesn’t have the default I2C address, 0x27, check out the complete I2C tutorial where I explain how you can find out what the address is.

Example code HC-SR04 with DHT11 temperature sensor and Arduino

As mentioned earlier, the speed of sound strongly depends on the air temperature. If you want to measure long distances (3-4 m) it can be a good idea to add a DHT11 or DHT22 temperature and humidity sensor to your setup. This will allow you to calibrate the speed of sound in real time and thereby increase the accuracy of your measurements.

Adding a DHT11 sensor is really simple. The wiring diagram below shows you what connections you need to make. Note that I am using a DHT11 with breakout board, so I only need to wire up 3 pins. Be sure to check the label of the sensor, the order of the pins can be different depending on the manufacturer. The HC-SR04 sensor is connected in the same way as before.

HC-SR04 with DHT11 and Arduino UNO wiring
HC-SR04 with Arduino and DHT11 wiring diagram

DHT11 Connections

DHT11Arduino
VCC (+)5V
Signal (s)Pin 4
GND (-)GND

If you want to learn more about using 3 and 4 pin temperature and humidity sensors with Arduino, you can check out the full tutorial here.

The code below uses the Adafruit DHT Humidity & Temperature Sensor library which you can download here on GitHub. This library only works if you also have the Adafruit_Sensor library installed, which is also available on GitHub.

You can click the button in the top right corner of the code field to open the complete code in a new window.

/*
HC-SR04 Ultrasonic Distance Sensor with Arduino Example Code
More info: https://www.makerguides.com
*/

//Include Adafruit sensor library
#include <Adafruit_Sensor.h> //https://github.com/adafruit/Adafruit_Sensor
//Include Adafruit DHT library
#include <DHT.h> //https://github.com/adafruit/DHT-sensor-library

//Define Trig pin, Echo pin and DHTPin
#define trigPin 2
#define echoPin 3
#define DHTPin 4

//Define DHT sensor type
#define DHTType DHT11

//Define variables
long duration;
int distance;
float speedofsound;

//Create a DHT sensor object
DHT dht(DHTPin,DHTType);

void setup()
{
//Define inputs and outputs
pinMode(trigPin, OUTPUT); 
pinMode(echoPin, INPUT); 

dht.begin();

//Begin Serial communication
Serial.begin(9600); // Starts the serial communication
}

void loop()
{
//Clear the trigPin by setting it LOW
digitalWrite(trigPin, LOW);
delayMicroseconds(5);

//Trigger the sensor by setting the trigPin high for 10 microseconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);

//Read the echoPin. This returns the duration (length of the pulse) in microseconds.
duration = pulseIn(echoPin, HIGH);

//Read the temperature
float temperature = dht.readTemperature();

//Calculate speed of sound in m/s
speedofsound = 331.3+(0.606*temperature);

//Calculate the distance in cm
distance = duration*(speedofsound/10000)/2;

//Print the distance and temperature on the Serial Monitor
Serial.print("Temperature = ");
Serial.print(temperature);
Serial.print(" Celsius");
Serial.print(", Distance = ");
Serial.print(distance);
Serial.println("cm");
delay(100);
}

Example code HC-SR04 with DHT11 and I2C LCD

HC-SR04 with DHT11, I2C LCD and Arduino UNO wiring
HC-SR04 with Arduino, DHT11 and I2C LCD wiring diagram

The code below can be used to combine all 3 examples above. It displays both the temperature, the speed of sound and the measured distance on the LCD.

You can click the button in the top right corner of the code field to open the complete code in a new window.

/*
HC-SR04 Ultrasonic Distance Sensor with Arduino Example Code
More info: https://www.makerguides.com
*/

//Include Adafruit sensor library
#include <Adafruit_Sensor.h> //https://github.com/adafruit/Adafruit_Sensor
//Include Adafruit DHT library
#include <DHT.h> //https://github.com/adafruit/DHT-sensor-library
#include <Wire.h> //Library for I2C communication
#include <LiquidCrystal_I2C.h> //Library for LCD

//Define Trig pin, Echo pin and DHTPin
#define trigPin 2
#define echoPin 3
#define DHTPin 4

//Define SDA and SCL pin from LCD
#define SDAPin A4 //Data pin
#define SCLPin A5 //Clock pin

//Connect to LCD via i2c, default address 0x27 (A0-A2 not jumpered)
LiquidCrystal_I2C lcd(0x27,20,4);

//Define DHT sensor type
#define DHTType DHT11

//Define variables
long duration;
int distance;
float speedofsound;

//Create a DHT sensor object
DHT dht(DHTPin,DHTType);

void setup()
{
//Define inputs and outputs
pinMode(trigPin, OUTPUT); 
pinMode(echoPin, INPUT); 

dht.begin();

//Initiate the LCD
lcd.init();
lcd.backlight();

//Begin Serial communication
Serial.begin(9600); // Starts the serial communication
}

void loop()
{
//Clear the trigPin by setting it LOW
digitalWrite(trigPin, LOW);
delayMicroseconds(5);

//Trigger the sensor by setting the trigPin high for 10 microseconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);

//Read the echoPin. This returns the duration (length of the pulse) in microseconds.
duration = pulseIn(echoPin, HIGH);

//Read the temperature
int temperature = dht.readTemperature();

//Calculate speed of sound in m/s
speedofsound = 331.3+(0.606*temperature);

//Calculate the distance in cm
distance = duration*(speedofsound/10000)/2;

//Print the distance and temperature on the Serial Monitor
lcd.setCursor(0,0);
lcd.print("Temperature: ");
lcd.print(temperature);
lcd.print(" " "\xDF" "C");
lcd.setCursor(0,1);
lcd.print("Speed: ");
lcd.print(speedofsound);
lcd.print(" m/s ");
lcd.setCursor(0,2);
lcd.print("Distance: ");
lcd.print(distance);
lcd.print(" cm  ");
delay(100);
}

HC-SR04 Dimensions

Below you can find the dimensions of the HC-SR04 ultrasonic sensor. I have noticed that there are some small differences between manufacturers, so I recommend double checking against your own sensor.

HC-SR04 Dimensions
HC-SR04 Dimensions

HC-SR04 CAD

I have created basic CAD drawings of the HC-SR04 ultrasonic sensor that you can download below.

Conclusion

In this article I have shown you how the HC-SR04 ultrasonic distance sensor works and how you can use it with Arduino. I hope you found it useful and informative. If you did, please share it with a friend that also likes electronics!

Personal project: A couple months ago I built an interactive wall installation with some friends. We used around 30 ultrasonic distance sensors to detect people walking in front of the wall. The wall included lights and sound effects that changed depending on how far away people were standing.

HC-SR04 Example AMS Prototypes
Photo: Guus Schoonewille

I would love to know what projects you plan on building (or have already built) with the HC-SR04 distance sensor. Please leave a comment down below and share your ideas.

Share on facebook
Share on twitter
Share on linkedin
Share on pinterest
Share on email
Share on whatsapp

Beginner

Creative Commons License

If you have any questions, suggestions or if you think that things are missing in this tutorial, please leave a comment down below. Note that comments are held for moderation in order to prevent spam.

Leave a Reply

Your email address will not be published. Required fields are marked *