Learn
Measuring Distance with an HC-SR04 Ultrasonic Sensor on a Raspberry Pi 4B
Wire an HC-SR04 ultrasonic distance sensor to a Raspberry Pi 4B, trigger a real pulse-timing measurement in Python, and read back the distance — wiring, the real trigger/echo timing pattern, and the 5V→3.3V wiring risk to know about.
Note: the HC-SR04 Ultrasonic Sensoris a Premium-tier component in the simulator — you’ll need a Premium or VIP plan to use it there.
Try this directly in the free Raspberry Pi 4B simulator — no hardware or signup required. New to the GPIO header? Start with the interactive pinout guide.
What you’ll need
- Raspberry Pi 4B
- HC-SR04 Ultrasonic Distance Sensor
- 2 Resistors (for the divider — optional but recommended)
Step by step
- Drag Raspberry Pi 4B onto the Canvas.
- Drag the HC-SR04 onto the Canvas — a real 4-pin module, connects via drawn wires (it doesn't mount into a breadboard).
- Hover over its 4 pins to confirm the labels, left to right: VCC, TRIG, ECHO, GND.
- Wire VCC → a Pi 5V pin (a real HC-SR04 needs 5V, not 3.3V) and GND → a Pi GND pin.
- Wire TRIG → any Pi GPIO pin you'll configure as an output (e.g. physical pin 37).
- Wire ECHO → any Pi GPIO pin you'll configure as an input (e.g. physical pin 38) — for now, wire it directly, no divider yet.
- Click the sensor to select it, then open its settings panel and set a Distance (cm) value — this is the distance the sensor will report back when triggered, anywhere from 2 to 400.
- Go to the Code tab and write a script using the standard real-world HC-SR04 pattern — a short trigger pulse, then timing how long Echo stays high:
import RPi.GPIO as GPIOimport timeimport asyncio GPIO.setmode(GPIO.BOARD)TRIG = 37 # adjust to match your wiringECHO = 38 # adjust to match your wiring GPIO.setup(TRIG, GPIO.OUT)GPIO.setup(ECHO, GPIO.IN)GPIO.output(TRIG, False) while True: GPIO.output(TRIG, True) time.sleep(0.00001) # a real ~10 microsecond trigger pulse GPIO.output(TRIG, False) while GPIO.input(ECHO) == 0: pulse_start = time.time() while GPIO.input(ECHO) == 1: pulse_end = time.time() pulse_duration = pulse_end - pulse_start distance = pulse_duration * 17150 distance = round(distance, 2) print(f"Distance: {distance} cm") await asyncio.sleep(1)- Click Start.
Check the Console — you should see a warning about ECHO reading close to 5V on an input pin. This is intentional: a real HC-SR04's Echo pin genuinely outputs a 5V logic signal, and a real Raspberry Pi's GPIO pins are only rated for 3.3V — wiring Echo directly to a Pi input, as you just did, is exactly the mistake that risks damaging real hardware. Nothing here can actually be damaged, but the simulator flags it the same way a multimeter would on a real board.
- To fix it the real way: add two resistors between ECHO and the Pi's input pin as a voltage divider — ECHO → a resistor (e.g. 1kΩ) → the node wired to the Pi's input pin → a second resistor (e.g. 2kΩ) → a Pi GND pin. This divides the 5V signal down to a safe ~3.3V before it reaches the Pi.
- Click Start again.
What “working correctly” looks like
- The Console prints a distance reading roughly once per second, matching the value you set in the sensor's own settings panel, within a small rounding tolerance.
- Wired directly (no divider), the Console shows the 5V-on-an-input-pin warning once per run — it doesn't reappear on every read, and it doesn't block the reading itself.
- Wired through a correctly-sized divider (bringing ECHO down to 3.3V or less), the warning does not appear at all, and the distance reading still works exactly the same.
If something’s wrong
- Distance never prints, or the script seems to hang → double-check TRIG and ECHO aren't swapped, and that ECHO is actually configured GPIO.IN, not GPIO.OUT.
- Distance reads 0 or an unexpected number → confirm the settings-panel Distance value is actually set (it defaults to 50cm) and that you're reading the correct pin's value back — a stray extra digit in the pin number is an easy typo here.