If you are building a rover, a liquid level monitor, or a parking assist system, you have likely asked: how do the sensors work when they use sound to measure distance? Ultrasonic sensors are the workhorses of hobbyist and light-industrial distance measurement, but treating them like simple "plug-and-play" modules leads to jittery readings and bricked microcontroller pins. This guide strips away the abstraction, giving you the exact physics, the raw-to-unit math, and the wiring realities for the two most common modules on the bench: the HC-SR04 and the waterproof JSN-SR04T.
The Physics: How Do Ultrasonic Sensors Work?
At the core of every ultrasonic distance module is a piezoelectric transducer. When the microcontroller pulls the trigger pin HIGH for at least 10 microseconds, the module's internal oscillator drives the transducer with a burst of eight 40kHz acoustic cycles. This high-frequency sound wave travels outward in a roughly 15-to-30-degree cone until it strikes a physical object and reflects back to the receiver transducer.
The module measures the Time-of-Flight (ToF)—the exact duration between the emission of the burst and the detection of the returning echo. Because the speed of sound in dry air at 20°C is approximately 343 meters per second (or 0.0343 centimeters per microsecond), the module's internal logic holds an "Echo" pin HIGH for a duration directly proportional to the distance the sound traveled. The microcontroller simply times this HIGH pulse to calculate the physical gap.
The Output Signal and Raw-to-Unit Math
A common beginner mistake is assuming ultrasonic sensors output an analog voltage that scales with distance. They do not. The output is strictly a digital logic pulse. The data is encoded in the width of the pulse (measured in microseconds), not the amplitude. The Echo pin will snap to either 0V (LOW) or the module's VCC voltage (HIGH).
The Raw-to-Unit Conversion Formula
Because the sound wave must travel to the object and back, the total distance covered is twice the actual gap. Therefore, we must divide the measured time by two before multiplying by the speed of sound.
Distance (cm) = (Pulse_Width_µs / 2.0) * 0.03432Worked Example:
Your microcontroller reads an Echo pulse width of
5800 µs.1. Divide by 2:
5800 / 2 = 2900 µs (one-way travel time).2. Multiply by speed of sound:
2900 * 0.03432 = 99.52 cm.
Microcontroller Implementation
On an Arduino or ESP32, you use the pulseIn() function to capture this timing. Here is the exact C++ snippet to read the raw value and convert it:
const int trigPin = 5;
const int echoPin = 18;
void setup() {
Serial.begin(115200);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop() {
// Clear the trigger pin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Trigger the 40kHz burst
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Read the echo pulse width in microseconds
long duration_us = pulseIn(echoPin, HIGH, 30000); // 30ms timeout
// Convert to centimeters
float distance_cm = (duration_us / 2.0) * 0.03432;
if (duration_us == 0) {
Serial.println("Out of range or timeout");
} else {
Serial.print("Distance: ");
Serial.print(distance_cm);
Serial.println(" cm");
}
delay(60); // Wait 60ms between pings to prevent echo overlap
}
Wiring, Pinouts, and Voltage Translation
While the logic is simple, the physical layer is where microcontrollers get destroyed. The standard HC-SR04 is a 5V device. If you connect its Echo pin directly to a 3.3V ESP32 or Raspberry Pi Pico GPIO, you will inject 5V into a 3.3V-tolerant pin, eventually degrading or killing the silicon. The JSN-SR04T (Version 2.0) solves this by natively supporting 3.3V logic.
| Specification | HC-SR04 (Standard) | JSN-SR04T (V2.0 Waterproof) |
|---|---|---|
| Supply Voltage (VCC) | 5.0V DC (Strict) | 3.3V to 5.0V DC |
| Logic Level (Echo/Trig) | 5V TTL | 3.3V / 5V TTL compatible |
| Operating Current | ~15 mA | ~20 mA (burst), <2 mA (idle) |
| Measuring Range | 2 cm to 400 cm | 20 cm to 450 cm |
| Blind Zone | 0 - 2 cm | 0 - 20 cm |
| ESP32/Pico Safe? | No (Requires voltage divider) | Yes (Direct connection) |
If you must use the cheap HC-SR04 with an ESP32, you must step down the Echo pin voltage. Build a voltage divider using a 1kΩ resistor in series with the Echo pin, and a 2kΩ resistor pulling that junction to GND. This yields exactly 3.33V at the ESP32 GPIO pin (
5V * (2k / (1k + 2k))). Do not skip this step.
Interference, Calibration, and Edge Cases
Ultrasonic sensors do not operate in a vacuum. If your readings are jumping wildly, you are likely hitting one of three physical interference sources.
1. Acoustic Cross-Talk and Multipath Echoes
If you mount two HC-SR04 modules side-by-side on a robot chassis, Sensor A will often trigger Sensor B's receiver. Furthermore, sound bouncing off a nearby wall at an angle can create a "multipath" echo, returning to the sensor later than the direct reflection and causing the microcontroller to read a falsely long distance. Fix: Stagger your sensor polling in code (fire Sensor A, wait 40ms, fire Sensor B) and physically separate them by at least 15 cm.
2. Acoustic Impedance Mismatch (Soft Targets)
Ultrasonic waves reflect beautifully off hard, dense surfaces like wood, metal, and plastic. They are completely absorbed by soft, porous materials like foam, heavy fabric, or fiberglass insulation. If your sensor is pointed at a couch or a person wearing a thick winter coat, the sound wave will not return, and pulseIn() will time out (return 0). Fix: Use Time-of-Flight (ToF) infrared lasers (like the VL53L0X) if your target includes soft textiles.
3. Temperature Drift and Calibration
The speed of sound is not a universal constant; it changes with air temperature. According to thermodynamic principles, the speed of sound in air increases by approximately 0.6 m/s for every 1°C rise in temperature. If you calibrate your sensor at 20°C (343 m/s) but deploy it in a 35°C greenhouse (352 m/s), your distance readings will be off by nearly 3%.
Calibration Math:
Speed_of_Sound = 331.4 + (0.606 * Temperature_C) (in meters per second).
For high-precision builds, wire a DS18B20 temperature probe next to the ultrasonic module and dynamically update the 0.03432 multiplier in your C++ code based on live temperature readings.
Decision Path: Which Ultrasonic Sensor Should You Buy?
Do not default to the cheapest module on Amazon. Use this decision tree to select the exact part number for your environment.
| If your project requires... | Then choose this module... | Why? |
|---|---|---|
| Indoor robotics, breadboard prototyping, 5V Arduino Uno | HC-SR04 | Cheapest option (~$1.50), massive community support, 2cm blind zone is fine for desk toys. |
| ESP32/Raspberry Pi Pico, 3.3V logic, no extra resistors | RCWL-1601 or JSN-SR04T (V2.0) | Native 3.3V I/O. The RCWL-1601 uses I2C/UART options, freeing up GPIO timing constraints. |
| Outdoor environments, liquid tanks, dusty warehouses | JSN-SR04T (V2.0) | IP67 waterproof sealed probe. The transducer is separated from the PCB, allowing remote mounting. |
| Sub-millimeter precision, high-speed conveyor belts | MaxBotix MB1010 (LV-MaxSonar-EZ) | Analog and PWM outputs, continuous real-time ranging, acoustic noise filtering (~$30.00). |
The Final Verdict
If you are buying in bulk for a reliable, modern embedded project in 2026, the default pick is the JSN-SR04T (Version 2.0). The standard HC-SR04 is a relic of the 5V Arduino era; its 5V echo pin is a liability for modern 3.3V ESP32 and ARM-based architectures, and its exposed transducers fail rapidly in high humidity. The JSN-SR04T V2.0 accepts 3.3V logic natively, features a waterproof remote probe, and costs only marginally more (~$4.00). Just remember to account for its 20cm blind zone in your physical CAD design, and your distance measurements will remain rock-solid for years.






