Quick Summary
How the HC-SR04 ultrasonic distance sensor works and how to connect it to Arduino. Covers the trigger-echo measurement principle, wiring diagrams, Arduino code using both pulseIn() and the NewPing library, and shows how to display distance readings on the Serial Monitor. Range: 2 cm to 400 cm.
The HC-SR04 is probably the first distance sensor most people try with Arduino, and for good reason — it is cheap, simple to wire, and works well enough for most hobby projects. It measures distance using ultrasonic sound waves, so there is no physical contact needed. This tutorial walks you through how the HC-SR04 actually works, how to wire it up, how to write the Arduino code, and how to show distance readings on the Serial Monitor and an optional I2C LCD. By the end, you should be comfortable enough to drop this sensor into whatever you are building next.

What this tutorial covers
Here is what you will learn:
- How ultrasonic distance sensing works, including the time-of-flight principle and the distance formula.
- Wiring the HC-SR04 to an Arduino Uno with a breadboard and jumper wires.
- Writing and uploading Arduino code that reads distance and prints it to the Serial Monitor.
- Optionally connecting an I2C LCD display to show distance readings without a computer.
- Troubleshooting common problems like wrong readings, zero values, and wiring mistakes.
- The limits of ultrasonic sensing and how to get the best accuracy.
How Ultrasonic Distance Sensing Works
An ultrasonic sensor measures distance by sending out a short burst of high-frequency sound and listening for the echo that bounces back. In fact, it is the same idea as echolocation in bats. The HC-SR04 has two cylindrical transducers on its front face: the transmitter (marked T) and the receiver (marked R).

The Time-of-Flight Principle
When you trigger the sensor, the transmitter sends a burst of ultrasonic pulses at about 40 kHz, well above human hearing range. These sound waves travel outward in a cone-shaped pattern. When they hit a solid object, they bounce back toward the sensor, and the receiver picks them up as an echo. The sensor then measures the total time between sending the pulse and getting the echo back. This is called the time of flight.
The Distance Formula
Because the sound travels to the object and back, it covers the distance twice. To get the one-way distance, you use this formula:
Distance = (Time x Speed of Sound) / 2
At room temperature (around 20 degrees C), sound travels at about 343 meters per second, or 0.0343 cm per microsecond. Since the Arduino measures the echo time in microseconds, the formula you will use in code is:
Distance (cm) = duration (us) x 0.0343 / 2
The division by 2 matters because the sound wave makes a round trip. If you skip it, you get double the real distance. The speed of sound also changes a bit with temperature and humidity, so readings might drift a few millimeters in extreme conditions.
Interactive Animation: How Ultrasonic Sensing Works
Click Send Ping and drag the Obstacle Distance slider to see how the HC-SR04 measures distance in real time.
HC-SR04 Specifications
Before wiring anything up, first here are the specs you should know about the HC-SR04.
| Parameter | Value |
|---|---|
| Operating Voltage | 5 V DC |
| Operating Current | 15 mA |
| Measuring Range | 2 cm to 400 cm |
| Measuring Angle | Approximately 15 degrees |
| Ultrasonic Frequency | 40 kHz |
| Trigger Pulse Width | 10 us minimum |
| Accuracy | Approximately +/-3 mm |
| Interface Pins | VCC, Trig, Echo, GND |
Components Needed
To get started, gather the parts listed below. The LCD and its adapter are optional — you only need those for the display upgrade section later.
| Component | Purpose | Required? | Notes |
|---|---|---|---|
| Arduino Uno | Microcontroller board that runs the code and reads sensor data | Yes | Any Arduino-compatible board works. Learn more about Arduino |
| HC-SR04 Ultrasonic Sensor | Measures distance using ultrasonic sound waves | Yes | Four-pin module: VCC, Trig, Echo, GND |
| Breadboard | Provides a solderless platform for making connections | Yes | A half-size breadboard is sufficient |
| Jumper Wires (Male-to-Male) | Connects the sensor to the Arduino through the breadboard | Yes | At least 4 wires needed |
| USB Cable (Type A to B) | Connects the Arduino to your computer for uploading code and serial output | Yes | Included with most Arduino kits |
| HD44780 16×2 LCD with I2C Adapter | Displays distance readings without needing a computer | Optional | Only needed for the LCD upgrade section |
Wiring the HC-SR04 to Arduino
Connecting the HC-SR04 to an Arduino is straightforward. The sensor has four pins, and each one connects directly to the Arduino. Use the wiring table below and also make sure everything is seated firmly on your breadboard before uploading any code.
| HC-SR04 Pin | Arduino Pin | Description |
|---|---|---|
| VCC | 5V | Powers the sensor (must be 5 V) |
| Trig | Digital Pin 9 | Receives the trigger signal from the Arduino |
| Echo | Digital Pin 10 | Sends the echo pulse back to the Arduino |
| GND | GND | Common ground (must be shared with Arduino GND) |
Important: The Arduino and the HC-SR04 must share a common ground. If you forget GND, the sensor will not give you any readings. Double-check this connection if you see 0 cm or no output.

Arduino Ultrasonic Sensor Code
With the wiring done, upload this sketch to your Arduino. It triggers the HC-SR04, reads the echo time, calculates distance in centimeters, and prints the result to the Serial Monitor. New to Arduino code? Our Arduino programming basics guide covers IDE setup and sketch structure.
/**
* Author: Omar Draidrya
* Date: 2024/05/07
* This code measures distance using an ultrasonic sensor
* and outputs the result via serial communication.
*/
#define TRIG_PIN 9 // Trigger pin of the ultrasonic sensor
#define ECHO_PIN 10 // Echo pin of the ultrasonic sensor
void setup() {
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
Serial.begin(9600);
}
void loop() {
long duration, distance;
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
duration = pulseIn(ECHO_PIN, HIGH);
distance = duration * 0.034 / 2;
Serial.print("Distance (cm): ");
Serial.println(distance);
delay(1000);
}
Code Explanation: Line by Line
Below is a breakdown of what each part of the code does, so you can modify it later or track down bugs.
#define TRIG_PIN 9 and ECHO_PIN 10 give human-readable names to the digital pin numbers. In other words, pin 9 controls the trigger, and pin 10 listens for the echo. You can change these to any available digital pins, as long as you also update the wiring.
pinMode(TRIG_PIN, OUTPUT) sets pin 9 as an output. This is because the Arduino needs to send a signal to the sensor to start a measurement.
pinMode(ECHO_PIN, INPUT) sets pin 10 as an input. This is because the Arduino needs to receive the echo signal coming back from the sensor.
Serial.begin(9600) opens serial communication at 9600 baud so the Arduino can send distance readings to your computer. Open the Serial Monitor in the Arduino IDE (Tools then Serial Monitor) to see them.
The trigger sequence: The Arduino pulls the trigger pin LOW, waits 2 microseconds for a clean start, pulls it HIGH for exactly 10 microseconds, then drops it LOW again. That 10-microsecond HIGH pulse tells the HC-SR04 to fire its ultrasonic burst.
Reading the echo and calculating distance
pulseIn(ECHO_PIN, HIGH) is a built-in Arduino function that waits for the echo pin to go HIGH, then measures how long it stays HIGH (in microseconds). That duration is the round-trip time for the sound wave. If no echo comes back within about 1 second, pulseIn returns 0.
distance = duration * 0.034 / 2 converts the echo time to a distance in centimeters. Here, 0.034 is the speed of sound in cm per microsecond (343 m/s converted). Dividing by 2 accounts for the round trip.
Serial.println(distance) then prints the distance followed by a new line, so each reading shows up on its own row in the Serial Monitor.
delay(1000) pauses for one second before the next measurement. You can lower this for faster updates, but you should keep at least 30 ms between readings so the sensor can settle and old echoes do not interfere.
Testing with the Serial Monitor
After uploading, open the Serial Monitor (Ctrl+Shift+M, or Tools then Serial Monitor). Then set the baud rate to 9600 in the bottom-right corner. Point the sensor at a flat surface like a wall or a book and slowly move it closer and farther away. You should see the distance update every second. If you get 0 or wildly jumping numbers, check the wiring section and the troubleshooting section below.
Optional Upgrade: Display Distance on an I2C LCD
If the Serial Monitor version works, you can take it a step further by adding an HD44780 16×2 LCD display with an I2C serial adapter. As a result, your Arduino can show distance readings on a physical screen, so you do not need a computer attached anymore. This section is optional and builds on the same wiring from the previous section.
LCD Wiring Table
Keep the HC-SR04 connected as before (Trig on pin 9, Echo on pin 10, VCC to 5 V, GND to GND). Then add the LCD connections below.
| I2C LCD Pin | Arduino Pin | Description |
|---|---|---|
| VCC | 5V | Powers the LCD module |
| GND | GND | Common ground |
| SDA | A4 | I2C data line |
| SCL | A5 | I2C clock line |
Note on I2C addresses: Most I2C LCD modules default to address 0x27, but some use 0x3F. If your LCD stays blank after uploading, first try changing the address in the code, or alternatively run an I2C scanner sketch to find the right one.

LCD Arduino Code with NewPing Library
This sketch uses two libraries: NewPing for ultrasonic sensor readings and LiquidCrystal_I2C for controlling the LCD over I2C. First install both through the Arduino Library Manager (Sketch then Include Library then Manage Libraries) before uploading. NewPing handles the trigger and echo timing for you, so you do not need to write the low-level pulse code yourself. It also has built-in noise filtering and timeout management.
/**
* Author: Omar Draidrya
* Date: 2024/05/07
* This code measures distance using an ultrasonic sensor
* and displays the result on an LCD.
*/
#include <LiquidCrystal_I2C.h>
#include <NewPing.h>
#define TRIGGER_PIN 9
#define ECHO_PIN 10
#define MAX_DISTANCE 200
LiquidCrystal_I2C lcd(0x27, 16, 2);
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
void setup() {
lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Distance:");
}
void loop() {
delay(50);
int distance = sonar.ping_cm();
lcd.setCursor(0, 1);
if (distance > 0) {
lcd.print(distance);
lcd.print(" cm ");
} else {
lcd.print("Out of range ");
}
}
The I2C adapter is nice because it cuts the wire count way down compared to running an LCD in parallel mode, and it frees up digital pins for other sensors or actuators. If you want another project that uses an I2C LCD, check out our Arduino password door lock project.
Accuracy, Limitations, and Best Practices
The HC-SR04 works well for hobby and educational projects, but it does have physical limits that matter. Knowing these will save you from confusing readings.
Minimum range (blind zone): The HC-SR04 cannot measure objects closer than about 2 cm. At that distance, the outgoing pulse and the returning echo overlap, and the receiver cannot tell them apart.
Soft and angled surfaces: Ultrasonic waves reflect best off hard, flat surfaces facing the sensor head-on. For instance, soft materials like fabric, foam, or fur absorb much of the sound energy. Curved or angled surfaces can deflect the echo away from the receiver entirely.
Narrow detection cone: Additionally, the HC-SR04 has a measuring angle of only about 15 degrees. Consequently, anything outside that cone will not be detected, so keep this in mind when you mount the sensor.
Environmental factors: The speed of sound changes with air temperature and humidity. For example, at 0 degrees C, sound travels at about 331 m/s, while at 30 degrees C it is closer to 349 m/s. For most indoor projects at room temperature, 343 m/s is close enough.
Noisy or jumping readings: Stray echoes, nearby objects, or electrical noise can cause occasional spikes or dips. Because of this, a practical fix is to take multiple readings and average them.
Mounting height and alignment: Mount the sensor so that its transducers face the target area directly. Because of this, even a slight tilt can cause echoes to miss the receiver. On mobile robots, make sure the sensor is mounted rigidly and does not vibrate during movement.
Troubleshooting Common HC-SR04 Problems
If the sensor is not giving you the results you expect, run through these common issues before assuming the hardware is bad.
Always reading 0 cm: This usually means the echo pin is not getting a signal. First, make sure the echo wire goes to the correct pin (pin 10 in this tutorial). Then verify that the sensor GND is connected to the Arduino GND.
Always reading maximum distance: If the sensor keeps returning its maximum value, the echo is probably getting lost. This often happens when the sensor faces open space with nothing in range, or when the target surface absorbs or deflects the sound.
Random jumping values: In most cases, unstable readings come from loose wiring, bad breadboard contacts, or interference from other ultrasonic sources. To fix this, press all wires firmly into the breadboard. If readings still jump, try adding a small delay between measurements or averaging multiple readings.
Code and Configuration Issues
No serial output at all: Check that you selected the correct board and port in the Arduino IDE under Tools, and that the Serial Monitor baud rate matches the value in your code (9600).
Wrong pin assignment in code: If you wired Trig and Echo to different pins than 9 and 10, then update the #define lines at the top of the sketch to match.
Insufficient power or loose wiring: The HC-SR04 needs a stable 5 V supply. For example, if you are running many components off the Arduino 5V pin, the voltage might sag below what the sensor needs.
LCD not showing text: If the screen stays blank after you finish the LCD section, check the I2C address first. Try 0x3F instead of 0x27 in the code. Also check that you connected SDA to A4 and SCL to A5. Also adjust the contrast potentiometer on the back of the I2C adapter.
Frequently Asked Questions (FAQ)
The HC-SR04 can measure distances up to approximately 400 cm (4 meters). However, in practice, readings above 200 to 300 cm tend to become less reliable, especially in environments with competing echoes or soft target surfaces.
The manufacturer designed the HC-SR04 for 5 V operation. The echo pin outputs 5 V, which can damage 3.3 V boards. Use a voltage divider on the echo pin or choose an HC-SR04P variant that supports 3.3 V to 5 V operation.
A reading of 0 cm usually means the sensor did not receive an echo. The most common causes are a missing GND connection, the wrong echo pin in the code, or the object being too close (under 2 cm).
The HC-SR04 has an accuracy of approximately plus or minus 3 mm under ideal conditions. In real-world use, however, expect accuracy of about plus or minus 1 cm depending on the target surface and environment.
Yes, you can connect multiple HC-SR04 sensors to different digital pins on the Arduino. However, trigger them one at a time with a short delay between readings to prevent acoustic crosstalk.
NewPing is an open-source library that handles trigger and echo timing for you, supports multiple sensors, and includes timeout and median filtering.
Take multiple readings and average them. NewPing has a built-in median filter (ping_median()) that handles this automatically.
Common projects include obstacle-avoiding robots, ultrasonic radar, parking sensors, liquid level monitors, and security systems.
No. The HC-SR04 is not waterproof. For underwater use, you need a dedicated waterproof ultrasonic transducer.
The HC-SR04P works on 3.3 V to 5 V, so you can use it with 3.3 V boards like the ESP32 without a level shifter. The standard HC-SR04 needs 5 V.
What to Build Next
As a next step, try mounting the sensor on a servo motor and building an Arduino ultrasonic radar that sweeps and maps the area around it. Or you could drop it into an obstacle-avoiding robot car that drives around objects on its own. If you have not worked with servo motors yet, our Arduino servo control guide will get you up to speed.
Conclusion
The HC-SR04 is a great beginner sensor because it pulls together wiring, timing, and serial output in one small project. At this point, you know how the sensor works, how to wire it, how to read distance in code, and how to display results on a screen. If something goes wrong, the troubleshooting section above will point you in the right direction. From here, you can plug this sensor into just about anything. For more Arduino projects and tutorials, check out OmArTronics.
1 thought on “Arduino Ultrasonic Distance Sensor: HC-SR04 Tutorial with Wiring and Code”