When sourcing distance modules globally, you will frequently see this ubiquitous 40kHz transceiver listed under its multilingual trade name, the sensor ultrasonik HC-SR04. Whether you are building a rover, a parking assistant, or a sump-pump alarm, this $2 module is the default choice for non-contact ranging. However, its simplicity hides specific electrical and acoustic pitfalls. The HC-SR04 does not output an analog voltage proportional to distance; it outputs a digital pulse width representing the time-of-flight (ToF) of a sound wave. Misunderstanding this output type, failing to translate its 5V logic for 3.3V microcontrollers, or ignoring acoustic interference will result in erratic readings or fried GPIO pins.
How the Sensor Ultrasonik HC-SR04 Actually Works
The module relies on a pair of piezoelectric transducers: one acts as a transmitter (Tx) and the other as a receiver (Rx). When the microcontroller pulls the Trigger pin HIGH for at least 10 microseconds, the module's onboard oscillator fires an eight-cycle burst of 40kHz ultrasonic sound. This acoustic pulse travels through the air at roughly 343 meters per second, strikes a target, and reflects back to the receiver.
The moment the burst is transmitted, the module pulls its Echo pin HIGH. When the reflected 40kHz wave is detected by the Rx transducer, the Echo pin drops LOW. The output is strictly a digital time-domain pulse, measured in microseconds (µs). There is no internal DAC converting this to an analog voltage, and attempting to read the Echo pin with an analog-to-digital converter (ADC) will yield useless data. You must measure the duration of the HIGH state using a hardware timer or a function like pulseIn().
Pinout, Wiring, and ESP32 Voltage Translation
The most common bench failure with this module occurs when makers wire the Echo pin directly to a 3.3V microcontroller like the ESP32 or Raspberry Pi Pico. The HC-SR04 is powered by 5V and its Echo pin outputs a 5V TTL signal. Feeding 5V into an ESP32 GPIO pin exceeds its absolute maximum ratings and will permanently damage the silicon (Espressif ESP32 Datasheet). You must use a voltage divider.
| Pin | Function | Supply / Logic Range | Arduino (5V) Connection | ESP32 (3.3V) Connection |
|---|---|---|---|---|
| VCC | Power Supply | 4.5V to 5.5V DC | 5V Pin | VIN (5V) Pin |
| GND | Ground | 0V | GND | GND |
| Trig | Trigger Input | Accepts 3.3V or 5V | Digital Pin (e.g., D9) | GPIO (e.g., GPIO 5) |
| Echo | Output Pulse | Outputs 5V TTL | Digital Pin (e.g., D10) | GPIO via Voltage Divider |
Wiring Steps for ESP32
- Connect the HC-SR04 VCC to the ESP32 VIN (5V) pin. Do not use the 3.3V pin; the module will fail to oscillate reliably below 4.2V.
- Connect GND to GND.
- Connect Trig directly to your chosen ESP32 output pin (e.g., GPIO 5).
- Place a 1kΩ resistor between the HC-SR04 Echo pin and your ESP32 input pin (e.g., GPIO 18).
- Place a 2kΩ resistor between the ESP32 input pin (GPIO 18) and GND. This creates the divider network.
The Raw-to-Unit Math: Converting Pulse Width to Distance
Because the output is a time duration, you must apply the physics of sound to derive physical distance. The formula relies on the speed of sound in dry air at 20°C, which is approximately 343 meters per second, or 0.0343 centimeters per microsecond (cm/µs).
The raw calculation is:
Distance (cm) = (Pulse_Width_µs × 0.0343) / 2
We divide by 2 because the sound wave travels to the object and back (round-trip). If your microcontroller reads a pulse width of 1166 µs, the math is: (1166 × 0.0343) / 2 = 20.00 cm.
Calibration and Temperature Scaling
The speed of sound is not a fixed constant; it scales with ambient temperature. If your project operates outdoors or in an unheated garage, the 0.0343 constant will introduce error. The speed of sound in air is calculated as v = 331.3 + (0.606 × T) where T is temperature in Celsius. For high-precision builds, interface a DS18B20 temperature sensor and dynamically update your multiplier in code. For indoor room-temperature projects, the static 0.0343 multiplier is sufficient.
Interference Sources and Signal Degradation
Ultrasonic sensors are acoustic devices, meaning they obey the laws of reflection and absorption. If your serial monitor is spitting out erratic numbers or max-range timeouts (often reading 0 or 400+ cm), check these physical interference sources:
- Specular Reflection (Angled Surfaces): Sound reflects like light. If the target surface is angled more than 20 degrees away from the sensor's perpendicular axis, the acoustic bounce will deflect away from the Rx transducer, resulting in a timeout.
- Acoustic Absorption: Soft, porous materials like clothing, foam, and heavy curtains absorb 40kHz waves rather than reflecting them. The sensor will fail to detect a person wearing a thick winter coat at distances beyond 1 meter.
- Cross-Talk: If you mount multiple HC-SR04 modules on a single robot, firing them simultaneously will cause the Rx of one module to listen to the Tx of another. You must fire them sequentially in code, waiting for the echo (or a timeout) before triggering the next sensor.
- Power Supply Ripple: The transmitter draws a spike of roughly 15mA when firing. If powered from a weak USB hub or a long, thin wire, the voltage sags, reducing the acoustic output power and shrinking your effective range. Use a local 100µF decoupling capacitor across the VCC and GND pins on the module.
Decision Tree: Should You Use the HC-SR04 or an Alternative?
While the HC-SR04 is cheap, it is not a universal solution. Use the decision matrix below to determine if this is the correct transducer for your specific physical environment, or if you need to pivot to a different sensing technology.
| Application Constraint | Recommended Technology | Concrete Part Pick |
|---|---|---|
| Target is soft, angled, or sound-absorbing | LiDAR (Laser Time-of-Flight) | Benewake TF-Luna (850nm) |
| Must detect objects through glass or plastic walls | Microwave Radar (Doppler) | RCWL-0516 Module |
| Requires sub-millimeter precision or narrow beam | Infrared Laser ToF | STMicroelectronics VL53L1X |
| Budget < $3, target is solid/flat, indoor use | Ultrasonic 40kHz | HC-SR04 |
For implementation, utilize the standard Arduino pulseIn() function with a strict timeout parameter (e.g., pulseIn(echoPin, HIGH, 30000)) to prevent your main loop from hanging indefinitely when the sound wave fails to return.






