Lesson 1.3: Ultrasonic sensor
The HC-SR04 measures the distance to an obstacle the way a bat does: it makes a sound we can't hear and listens for how long it takes to come back. It's the basis of obstacle-avoiding robots, parking sensors and level gauges.
Parts
How it works
A 10 µs pulse on Trig makes the module emit a burst of eight cycles at 40 kHz. As it leaves, Echo goes HIGH, and it drops back to LOW when the echo arrives: the length of that pulse is the round-trip time.
Sound travels at about 343 m/s at 20 °C, that is, 0.0343 cm per microsecond. Since the pulse covers there and back, the distance is half: distance (cm) = duration (µs) × 0.0343 / 2. For 10 cm, the echo takes about 583 µs.
pulseIn() measures the pulse length. Its third argument is a timeout: if no echo comes back —nothing in front, or out of range— it returns 0 instead of blocking the program for a whole second.
Specifications
- Range
- 2 cm – 4 m
- Frequency
- 40 kHz
- Detection angle
- about 15°
- Supply
- 5 V
Wiring
| Component | Connects to | Note |
|---|---|---|
| HC-SR04, VCC | 5V | |
| HC-SR04, Trig | Pin 12 | |
| HC-SR04, Echo | Pin 11 | |
| HC-SR04, GND | GND |
Code
// Measures the distance with the HC-SR04 five times a second.
const int TRIG_PIN = 12;
const int ECHO_PIN = 11;
void setup() {
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
Serial.begin(9600);
}
void loop() {
// 10-microsecond trigger pulse.
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
// Echo duration, with a 30 ms limit.
unsigned long duration = pulseIn(ECHO_PIN, HIGH, 30000UL);
if (duration == 0) {
Serial.println("No echo");
} else {
float cm = duration * 0.0343 / 2;
Serial.print(cm);
Serial.println(" cm");
}
delay(200);
}What the code does
- The 2 µs LOW before the trigger makes sure the pulse starts clean.
- pulseIn(ECHO_PIN, HIGH, 30000UL) waits for Echo to go high and measures how long it stays HIGH, up to 30 ms: roughly 5 m.
- The maths uses float to keep the decimals; Serial.print() prints two by default.
Step by step
- Wire the module following the table. With female-to-male wires you don't need a breadboard.
- Upload the code and open the serial monitor at 9600 baud.
- Point the sensor at a wall and slowly move it closer and further away.
Result
The serial monitor shows the distance in centimetres five times a second, and «No echo» when nothing is in range.
If it doesn't work
- If it always reads «No echo», check that Trig and Echo aren't swapped.
- Soft or angled surfaces absorb or deflect the sound: try a flat wall.
- Below 2 cm the reading isn't reliable: the echo returns before the module has finished transmitting.