← How-Tos
electronics 1 hr ago ◯ 5 min read

Ultrasonic Distance Sensors for Makers: HC-SR04, JSN-SR04T, and Getting Reliable Readings

ultrasonic sensorHC-SR04JSN-SR04TESP32Arduinosensors

Ultrasonic distance sensors are one of the cheapest, most common ranging components in the maker ecosystem — a two-dollar HC-SR04 shows up in half the beginner robotics tutorials ever written — but the gap between "it kind of works on a breadboard demo" and "it gives reliable readings in a real project" trips up more people than the sensor's simplicity suggests. This guide covers how the HC-SR04 family actually works, the wiring and timing details that determine whether your readings are noise or signal, and when to reach for the waterproof JSN-SR04T or step up to a time-of-flight sensor instead.

How Ultrasonic Ranging Works

The sensor has two transducers: one emits a burst of 40kHz ultrasonic pulses, the other listens for the echo bouncing back off whatever's in front of it. The module measures the round-trip time between sending the pulse and detecting the echo, and since the speed of sound in air is a known, roughly constant value, that time converts directly to distance. The core formula is simple: distance = (time × speed of sound) / 2, dividing by two because the measured time covers the round trip, out and back.

Wiring the HC-SR04

The HC-SR04 uses four pins: VCC (5V — this is important, see below), GND, Trig, and Echo. The Trig pin needs a brief 10-microsecond HIGH pulse to fire a measurement; the Echo pin then goes HIGH for a duration proportional to the distance, which your microcontroller times.

PinConnects ToNotes VCC5VThe HC-SR04 is a 5V part — do not run it directly off 3.3V, it won't reliably trigger GNDGroundCommon ground with your microcontroller TrigAny GPIO (output)10µs HIGH pulse starts a measurement EchoAny GPIO (input) — through a level shifter on 3.3V boardsGoes HIGH for the round-trip duration; this is a 5V signal

The 3.3V Problem on ESP32 and Raspberry Pi

This is the single most common HC-SR04 mistake. The sensor's Echo pin outputs a 5V logic signal, but ESP32 and Raspberry Pi GPIO pins are only rated for 3.3V input. Wiring Echo directly into a 3.3V GPIO works often enough in a quick test to fool people into thinking it's fine, but it stresses the pin over time and can produce flaky readings or, eventually, damage the input. Use a simple resistor divider (a 1kΩ and 2kΩ resistor in series from Echo to ground, with the GPIO tapped at the midpoint, gives roughly 3.3V from a 5V signal) or a proper logic-level shifter module — the same approach covered in this site's logic level shifter guide. Arduino boards running natively at 5V (Uno, Mega, Nano) don't have this problem and can wire Echo straight to a digital pin.

Timing the Echo Pulse in Code

On Arduino, the built-in pulseIn() function handles the timing directly — it blocks until Echo goes HIGH, then returns the duration it stays HIGH in microseconds, which you convert to distance. On ESP32 with the Arduino core, pulseIn() works the same way but is less precise under FreeRTOS task scheduling jitter than on a bare-metal AVR; for tighter timing, use a GPIO interrupt on both edges of Echo and calculate the duration from two timestamped micros() calls instead of relying on the blocking function. In MicroPython, the machine.time_pulse_us() function provides the same blocking-timeout behavior as Arduino's pulseIn().

Common Sources of Bad Readings

When to Use the JSN-SR04T Instead

The JSN-SR04T is a waterproof-probe variant built for outdoor and liquid-level applications the exposed HC-SR04 PCB can't survive — rain gauges, tank level monitoring, outdoor auto-watering systems. It typically runs at 5V like the HC-SR04, uses the same trigger/echo timing model (some breakout versions consolidate Trig and Echo onto a single pin, so check your specific module's documentation), and has a longer minimum range (usually 20-25cm) and a narrower beam angle due to its probe form factor. If your project pairs naturally with this site's automated plant watering or ESP32 auto-watering guides, the JSN-SR04T for a water tank level check is a direct, low-cost addition.

When to Step Up to Time-of-Flight Instead

Ultrasonic sensing has real limits: it struggles with soft/absorbent targets, has a comparatively wide beam angle that makes precise small-object detection difficult, and its useful range tops out around 4 meters on typical hobby modules. If your project needs millimeter-level accuracy, works with reflective or IR-transparent materials ultrasonic handles poorly, or needs a narrower detection cone for precise object presence sensing, a laser time-of-flight sensor like the VL53L0X or VL53L1X (covered in this site's time-of-flight sensor guide) is the better tool, at a higher unit cost.

The HC-SR04 remains one of the best components to actually learn timing-based sensing on, precisely because its failure modes are visible and its wiring is simple enough to debug with a multimeter and an oscilloscope trace on the Echo pin. Get the 5V level-shifting right, filter your readings with a rolling median, and it's a genuinely reliable sensor for the range of projects it's suited to.