Ultrasonic Distance Measurement with Arduino
The Arduino microcontroller sends a signal from a digital pin (usually connected to the Trig pin on the sensor) to initiate the transmission of ultrasonic waves into the environment. When these waves encounter an obstacle, they reflect back toward the sensor and are received by the Echo pin.
Distance = (Time × Speed of Sound) / 2
We divide by 2 because the measured time includes the trip to the object and the return trip (round-trip time).
Key Points:
- Trig pin: Used to trigger the ultrasonic pulse.
- Echo pin: Receives the reflected pulse.
- Typical speed of sound: ~340 m/s = 0.034 cm/µs
- Common sensor model: HC-SR04
The task
In this exercise, we will use an ultrasonic sensor (such as the HC-SR04) to measure the distance to an object. The Arduino sends a signal to the sensor to trigger the emission of ultrasonic waves. These waves travel through the air, bounce off an object, and return to the sensor. By measuring the time it takes for the echo to return, we can calculate how far the object is from the sensor.The following Arduino sketch demonstrates how to control the sensor, calculate the distance, and display the result in the Serial Monitor.
The wires diagram
We use two digital I/O pins for the ultrasonic sensor’s trigger and echo. An orange wire connects Arduino digital pin 9 to the sensor’s Trigger pin, and a yellow wire connects Arduino digital pin 10 to the sensor’s Echo pin.
Finally, tie the Arduino’s GND to the sensor’s GND pin to complete the circuit.
How an ultrasonic sensor measures distance - more details
The HC-SR04 uses ultrasound to measure the distance to an obstacle in front of it, sends out an ultrasonic signal (a high-frequency wave of about 40KHz) and waits for it to return, measuring the return time.Based on the time that has passed between sending and receiving the signal - it calculates the distance.
Step by Step: How HC-SR04 Measures Duration
1. Arduino sends the TRIGGER signal
On the trigger pin (usually pin 9), Arduino sends:
digitalWrite(trigPin, HIGH);
delayMicroseconds(10); // 10 microseconds
digitalWrite(trigPin, LOW);
This tells the sensor: "Send out an ultrasonic pulse!"
2. The sensor automatically emits 8 ultrasonic waves (at 40 kHz)
This lasts very briefly (less than 1 ms). At the same time, HC-SR04 activates the echo pin.
3. Echo pin goes HIGH
When the sensor sends the pulse, the echo pin becomes HIGH. It stays HIGH while the ultrasonic signal is traveling.
4. Sensor detects the returning wave
When the ultrasonic wave reflects from an object and returns, the echo pin goes LOW.
That means:
- Echo pin = HIGH → signal is on its way.
- Echo pin = LOW → signal returned, measurement complete.
How duration is measured
Arduino uses the pulseIn() function to measure how long the echo pin was HIGH, in microseconds (μs):
long duration = pulseIn(echoPin, HIGH);
Then the distance is calculated with:
float distance = duration * 0.034 / 2;
Why * 0.034 / 2?
Speed of sound: 340 m/s = 0.034 cm/μs.
We divide by 2 because the signal travels to the object and back.
| Time | Event |
|---|---|
| t0 | Arduino sends a 10μs signal to the TRIG pin |
| t1 | HC-SR04 sends ultrasonic wave and sets ECHO to HIGH |
| t2 | Wave is reflected and received, ECHO goes LOW |
| t2 - t1 | Duration of the pulse in microseconds (μs) |
Ultrasonic Distance Measurement with Arduino-code
// Ultrasonic distance measurement with the HC-SR04
int trigerPin = 9; // pin connected to the Trig pin of the ultrasonic sensor
int echoPin = 10; // pin connected to the Echo pin of the ultrasonic sensor
long dur; // duration of the pulse
float dist; // calculated distance
void setup() {
// Set the mode of the pins
pinMode(trigerPin, OUTPUT); // Trig pin as output
pinMode(echoPin, INPUT); // Echo pin as input (reads the returning signal)
Serial.begin(115200); // start serial communication at 115200 baud
}
void loop() {
// Send a 10-microsecond pulse to the trigger pin
digitalWrite(trigerPin, LOW); // make sure the trigger pin is low
delayMicroseconds(2); // wait for 2 microseconds
digitalWrite(trigerPin, HIGH); // set the trigger pin high
delayMicroseconds(10); // keep it high for 10 microseconds
digitalWrite(trigerPin, LOW); // set it low again
// Read the time it takes for the echo to return
dur = pulseIn(echoPin, HIGH); // duration of the HIGH pulse on the echo pin
// Calculate the distance in cm: sound travels about 0.034 cm per microsecond,
// divide by 2 because it goes to the object and back
dist = dur * 0.034 / 2;
// Print the result to the Serial Monitor
Serial.print("Distance: ");
Serial.print(dist, 2); // print with 2 decimal places
Serial.println(" cm"); // the unit is centimeters
delay(500); // short delay before the next measurement
}
How Trigger Pulse Length Affects Ultrasonic Sensor Operation
Trigger Pulse Duration Considerations
1. Pulse shorter than 10 μs
The HC-SR04 requires a trigger pulse of at least 10 microseconds to emit ultrasound. A shorter pulse (e.g. 5 μs) may not register, and no ultrasonic burst will be sent. In that case, pulseIn(echoPin, HIGH) returns 0 because the ECHO pin never goes HIGH.
2. Pulse longer than 10 μs
Many HC-SR04 modules still function if the trigger pulse lasts 20 μs or 50 μs, since the sensor reacts to the first rising edge and counts an internal 10 μs. However, this behavior is outside the official specification and may be unpredictable on some units. It is recommended to use exactly 10 μs for reliable operation.
3. Pulse longer than the echo return time (t₂ − t₁)
The trigger pulse initiates the ultrasonic burst, but the ECHO measurement is independent. Even if the trigger remains HIGH (e.g. 50 μs), the ECHO pin timing starts from the moment the sensor transmits, not when the trigger ends. Excess trigger duration is ignored internally.
⚠️ Potential Issues with Excessively Long Pulses
- Internal timing may be disrupted (sensor might send more than 8 pulses).
- Subsequent measurements could be delayed.
- Readings may become inconsistent.
For consistent results, always use the standard trigger sequence:
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
Summary Table
| Trigger Duration | Behavior |
|---|---|
| < 10 μs | No ultrasonic burst sent |
| = 10 μs | Correct operation |
| > 10 μs | May work but not recommended |
| > echo return time | No effect on ECHO timing |
Automatic ECHO Pin Behavior
The ECHO pin transitions to HIGH automatically, not by user code but by the HC-SR04 hardware itself.
How It Works
When a trigger pulse is sent to the sensor:
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
the following sequence occurs internally:
- Eight ultrasonic pulses are emitted at 40 kHz.
- The ECHO pin is immediately set to
HIGH. - The ECHO pin remains
HIGHuntil the returning echo is detected. - Upon echo detection, the ECHO pin is reset to
LOW.
The duration that ECHO stays HIGH corresponds to the round-trip travel time of the ultrasonic wave.
Measuring the Pulse
The pulseIn() function is used to measure this HIGH time in microseconds:
long duration = pulseIn(echoPin, HIGH);
This function:
- Waits for the ECHO pin to go
HIGH(start of pulse). - Measures how long the pin remains
HIGH. - Returns the duration in microseconds.
Since the sensor controls the ECHO output, the pin only needs to be declared as an input:
pinMode(echoPin, INPUT);
No digitalWrite(echoPin, …) calls are required, as the ECHO line is driven by the sensor hardware.
Enhancements Overview
To improve reliability and readability over the initial sketch:
- Corrected pin mode: Set the Echo pin to
INPUTso the Arduino can read the return pulse. - Modular code: Encapsulated trigger/echo logic in a
measureDistance()function for clarity. - Timeout handling: Added a timeout to
pulseIn()to prevent blocking if no echo is received. - Error checking: Returned
-1when no echo is detected, and reported “Out of range” instead of printing an invalid distance. - Constants: Defined the speed of sound as a named constant for easy adjustment.
// Ultrasonic distance measurement with the HC-SR04 – improved version
const int triggerPin = 9; // Trig pin of the ultrasonic sensor
const int echoPin = 10; // Echo pin of the ultrasonic sensor
const float SOUND_SPEED = 0.034; // speed of sound in cm/μs
void setup() {
// Configure pin modes
pinMode(triggerPin, OUTPUT);
pinMode(echoPin, INPUT);
Serial.begin(115200);
}
void loop() {
// Measure and report the distance
float distance = measureDistance();
if (distance < 0) {
Serial.println("Out of range or no echo");
} else {
Serial.print("Distance: ");
Serial.print(distance, 2);
Serial.println(" cm");
}
delay(500);
}
/**
* Sends a 10 μs TRIG pulse, waits for ECHO and returns the distance in cm.
* Returns -1 on timeout or no echo.
*/
float measureDistance() {
// Trigger pulse
digitalWrite(triggerPin, LOW);
delayMicroseconds(2);
digitalWrite(triggerPin, HIGH);
delayMicroseconds(10);
digitalWrite(triggerPin, LOW);
// Wait for the echo with a 30 ms timeout
long duration = pulseIn(echoPin, HIGH, 30000UL);
if (duration <= 0) {
return -1.0;
}
// Calculate the distance
return (duration * SOUND_SPEED) / 2.0;
}
Troubleshooting
No Readings
If pulseIn() returns zero, it usually means the HC-SR04 didn’t detect any echo. Common causes:
- Too close: Objects closer than
< 2 cmlie within the sensor’s blind zone and won’t reflect a usable echo. - Too far: Targets beyond
> 400 cmexceed its maximum range, so no echo is received. - Wiring issues: Loose or swapped trigger/echo pins can prevent the pulse from being sent or received.
Interference & Crosstalk
When using multiple ultrasonic sensors simultaneously, their pulses can collide, causing erroneous zero or sporadic readings:
- Sequential triggering: Fire each sensor one at a time with a small delay (e.g. 50 ms) between readings.
- Physical spacing: Mount sensors at least 10 cm apart (or angle them) to reduce overlap of ultrasonic beams.
- Shielding: Use small baffles or foam tubes around each sensor’s emitter/receiver to help confine the sound path.
Check your knowledge
Open the quiz
Quiz: ultrasonic sensor
1. How long must the pulse on the Trig pin last?
2. What does pulseIn(echoPin, HIGH) measure?
3. In what range does the HC-SR04 measure reliably?
4. Why is the time divided by 2?
| Previous |< Arduino-Measurement of the unknown resistor |
Next Introduction to Servo Motors >| |
