# How to use an HC-SR04 Ultrasonic Distance Sensor with Arduino

The HC-SR04 is an inexpensive, easy to use ultrasonic distance sensor, with a range of 2cm to 400 cm. It is commonly used in obstacle avoiding robots and automation projects. 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. We will first look at an example that does not use an Arduino library. Next, I will show you how you can use the NewPing library to create a more compact code.

Cheap ultrasonic distance/proximity sensors are great but in some projects, you might need a waterproof sensor like the JSN-SR04T or an IR sensor that isn’t influenced by temperature changes. In that case, the articles below might be useful:

Overview

## Supplies

### Software

Makerguides.com is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for sites to earn advertising fees by advertising and linking to products on Amazon.com. As an Amazon Associate we earn from qualifying purchases.

## 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 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 and 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.

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.

## Wiring – Connecting HC-SR04 to Arduino UNO

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

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

## 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 to you how the code works.

```/* Example code for HC-SR04 ultrasonic distance sensor with Arduino.

// 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 at a baudrate of 9600:
Serial.begin(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 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 at a baudrate of 9600:
Serial.begin(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 can calculate the distance by using the formula mentioned in the introduction of this tutorial.

```// 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;```

Finally, the calculated distance is printed 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.

// Include the library:
#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.

### I2C LCD Connections

If you are not using an Arduino Uno, the SDA and SCL pins can be at a different location. An Arduino UNO with the R3 layout (1.0 pinout), also has the SDA (data line) and SCL (clock line) pin headers close to the AREF pin. Check the table below for more details.

The code uses the LiquidCrystal_I2C library, which you can download here on GitHub. Make sure that you have this exact library installed! It also includes the Wire.h library, which allows you to communicate with I2C devices. This library 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 our tutorial on How to control a character I2C LCD with Arduino.

```/* HC-SR04 ultrasonic distance sensor with
Arduino and I2C LCD example code.
*/

#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 = LiquidCrystal_I2C(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 which connections you need to make. Note that I am using a DHT11 with a 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.

### DHT11 Connections

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 also download the two libraries by clicking on the buttons below:

You can click the button in the top right corner of the code field to copy the code.

```/* HC-SR04 ultrasonic distance sensor with
DHT11 and Arduino example code.

// 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 = 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);

// 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

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.

```/* HC-SR04 ultrasonic distance sensor with
DHT11, I2C LCD and Arduino example code.

#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 = LiquidCrystal_I2C(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 = 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 at a baudrate of 9600:
Serial.begin(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. This returns the duration (length of the pulse) in microseconds:
duration = pulseIn(echoPin, HIGH);

// 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.

## 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 of 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.

I would love to know what projects you plan on building (or have already built) with the HC-SR04 distance sensor. 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 to prevent spam.

## Other Useful Links From Around The Web:

Matt Armfield

Thursday 21st of December 2023

Any chance this could have two presets? I park farther in my garage when my hitch mount bike rack is installed vs the winter when it is put away. The ability to either set presets or to push a button to set the distance would be a great option. Since I will probably use an Arduino uno R3 which doesn't have wifi, the button option works best for me.

Stefan Maetschke

Thursday 21st of December 2023

It is definitely possible to extend the code to change pre-set distances via a button press.

Lee Sendall

Thursday 15th of July 2021

for anyone in the USA making this, i have changed this to run inches, also fixed error in program that wouldn't display measurement when using the LDC, humidify/temp sensor.

Also i changed sensor to DHT22 because it's a better sensor. Over 10ft there's about +/- 2" variance that could be background interferance or error in math, but 10ft is more then enough room for what i need.

Also thanks for the Original Author, your program was just want i was looking for.

see below for Imperial code.

/* HC-SR04 ultrasonic distance sensor with DHT22, I2C LCD and Arduino example code. More info: https://www.makerguides.com */

// 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 = LiquidCrystal_I2C(0x27,20,4);

// Define DHT sensor type: #define DHTType DHT22

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

// Create a DHT sensor object: DHT 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 at a baudrate of 9600: Serial.begin(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. This returns the duration (length of the pulse) in microseconds: duration = pulseIn(echoPin, HIGH);

// Calculate speed of sound in ft/s: speedofsound = 1086.7+(0.606*temperature);

// Calculate the distance in inches: distance = duration*(speedofsound/328.084)/200/2.54;

// Print the distance and temperature on the Serial Monitor: lcd.setCursor(0,0); lcd.print("Temp: "); lcd.print(temperature); lcd.print("'C "); lcd.setCursor(0,1); lcd.print("Dist: "); lcd.print(distance); lcd.print(" inches "); lcd.setCursor(0,2); delay(100); }

David Maynerd

Friday 20th of November 2020

Thanks for this very nicely presented tutorial

I am wanting to use the hr sr04 to give an alarm when a certain distance is reached ie the unit needs refilling. So the filled container will have a short reading and then at about 35 cm an alarm needs to sound or be sent to remind to do a refill.

having a arduino system seems like an overkill but maybe you could advise?

regards david

Jonn

Monday 24th of May 2021

Maybe try a water level sensor instead? What is in this container?

Gabby Dela Cruz

Thursday 19th of November 2020

Hi I tried following your code for the combination of the Dht 11, HC-SR04 and the LCD while I am able to get the distance, the temperature says it is 0. what do I need to do?

Benne de Bakker

Saturday 21st of November 2020

Hi Gabby,

I would try to isolate the problem by testing the sensor separately first. There might be a problem with the wiring or the sensor itself. You can find a tutorial for the DHT11 here:

https://www.makerguides.com/dht11-dht22-arduino-tutorial/

Benne

Aisha Rahmat

Wednesday 16th of September 2020

it works great but after I put an object closer than 1cm it prints distance = 135 cm is there any way I can change the distance to 1cm even if it is less than 1 cm away

Benne de Bakker

Thursday 17th of September 2020

Hi Aisha,

You can use the 'constrain' function for this: https://www.arduino.cc/reference/en/language/functions/math/constrain/

For example: sensVal = constrain(sensVal, 1, 150); // limits range of sensor values to between 1 and 150

Benne