Unit D - Sensors & Buses

21. HC-SR04 Ultrasonic Distance

Measure echo time and handle missing or noisy returns.

Estimated time 4 hours

Learning outcomes

  • Explain time-of-flight measurement
  • Generate a valid trigger pulse
  • Convert microseconds to distance
  • Handle timeouts and filter readings

Parts and preparation

Uno, HC-SR04, jumper wires and flat targets.

Before power: inspect wiring, confirm supply voltage and ensure all connected circuits share GND.

HC-SR04 Ultrasonic Distance instructional connection diagram
Open the diagram for a larger view. Trace every connection before building.

Time of flight

A 40 kHz sound burst travels to a target and back. Distance = duration * speed of sound / 2. Near room temperature, sound travels about 0.0343 cm/us.

Echo quality

Soft, angled, small or distant targets may not return a usable echo. Multiple sensors can interfere with one another.

Timeout

pulseIn can wait a long time when no echo arrives. A timeout bounds the wait and returns zero for no pulse.

Filtering

Median or moving-average filters reduce occasional spikes, but filtering cannot correct bad geometry.

Wiring and safe build sequence

Breadboard wiring for lesson 21: HC-SR04 Ultrasonic Distance
Breadboard layout for this lesson. Match colours and pins before powering the circuit. Click the image for a larger view.
  1. VCC -> 5 V
  2. GND -> GND
  3. TRIG -> D9
  4. ECHO -> D10 (5 V signal is suitable for Uno; level-shift for 3.3 V boards)
Power rule: switch off before moving wires. Arduino I/O pins are control signals; high-current loads require a driver and suitable external supply.
const byte trigPin = 9;
const byte echoPin = 10;

void setup() {
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  Serial.begin(9600);
}

void loop() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  unsigned long duration = pulseIn(echoPin, HIGH, 30000UL);
  if (duration == 0) {
    Serial.println("No echo");
  } else {
    float cm = duration * 0.0343 / 2.0;
    Serial.print(cm, 1);
    Serial.println(" cm");
  }
  delay(100);
}

How the code works

  1. 30,000 s limits the blocking wait.
  2. Division by two accounts for the outward and return journey.

Test and record evidence

Expected result: Serial reports plausible distance to a flat target or No echo when no valid pulse returns.

Practical evidence checklist

Common faults and checks
  • Swap-check TRIG and ECHO.
  • Aim squarely at a broad hard target.
  • Ignore readings below the modules minimum range.
Extension challenge: Take five readings and print their median rather than the mean.

Check your understanding

Q1. Why divide echo travel by two?

Show answer

The measured time includes travel to the object and back.

Q2. What does pulseIn return after a timeout?

Show answer

Zero.