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

  1. Drag Raspberry Pi 4B onto the Canvas.
  2. Drag the HC-SR04 onto the Canvas — a real 4-pin module, connects via drawn wires (it doesn't mount into a breadboard).
  3. Hover over its 4 pins to confirm the labels, left to right: VCC, TRIG, ECHO, GND.
  4. Wire VCC → a Pi 5V pin (a real HC-SR04 needs 5V, not 3.3V) and GND → a Pi GND pin.
  5. Wire TRIG → any Pi GPIO pin you'll configure as an output (e.g. physical pin 37).
  6. 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.
  7. 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.
  8. 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 GPIO
import time
import asyncio
 
GPIO.setmode(GPIO.BOARD)
TRIG = 37 # adjust to match your wiring
ECHO = 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)
  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.

  1. 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.
  2. 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.