Ultrasonic LED Distance Indicator ESP32 MicroPython is a runnable microcontroller simulation example on SensBench — open the wired circuit, inspect the code, and compile real firmware in your browser, no install needed. Last updated Aug 14, 2026.

FREE SIMULATOR EXAMPLE · BEGINNER

Ultrasonic LED Distance Indicator ESP32 MicroPython

This example builds an ultrasonic distance indicator on the ESP32 — the sensor’s echo timing becomes centimeters, and the LEDs light as objects approach. The parking-sensor pattern.

Board ESP32 DevKit (Xtensa LX6, 240 MHz)
Difficulty beginner
Category sensors
Libraries None — just the Arduino core
Runs in Sensbench browser simulator — free, no account
ESP32 ultrasonic distance indicator with LEDs in the Sensbench simulator

The exact circuit you get when you open this example — already wired, ready to run.

The sketch

# hcsr04.py
import machine, time
from machine import Pin

__version__ = '0.2.0'
__author__ = 'Roberto Sánchez'
__license__ = "Apache License 2.0. https://www.apache.org/licenses/LICENSE-2.0"

class HCSR04:
    """
    Driver to use the untrasonic sensor HC-SR04.
    The sensor range is between 2cm and 4m.
    The timeouts received listening to echo pin are converted to OSError('Out of range')
    """
    # echo_timeout_us is based in chip range limit (400cm)
    def __init__(self, trigger_pin, echo_pin, echo_timeout_us=500*2*30):
        """
        trigger_pin: Output pin to send pulses
        echo_pin: Readonly pin to measure the distance. The pin should be protected with 1k resistor
        echo_timeout_us: Timeout in microseconds to listen to echo pin. 
        By default is based in sensor limit range (4m)
        """
        self.echo_timeout_us = echo_timeout_us
        # Init trigger pin (out)
        self.trigger = Pin(trigger_pin, mode=Pin.OUT, pull=None)
        self.trigger.value(0)

        # Init echo pin (in)
        self.echo = Pin(echo_pin, mode=Pin.IN, pull=None)

    def _send_pulse_and_wait(self):
        """
        Send the pulse to trigger and listen on echo pin.
        We use the method `machine.time_pulse_us()` to get the microseconds until the echo is received.
        """
        self.trigger.value(0) # Stabilize the sensor
        time.sleep_us(5)
        self.trigger.value(1)
        # Send a 10us pulse.
        time.sleep_us(10)
        self.trigger.value(0)
        try:
            pulse_time = machine.time_pulse_us(self.echo, 1, self.echo_timeout_us)
            return pulse_time
        except OSError as ex:
            if ex.args[0] == 110: # 110 = ETIMEDOUT
                raise OSError('Out of range')
            raise ex

    def distance_mm(self):
        """
        Get the distance in milimeters without floating point operations.
        """
        pulse_time = self._send_pulse_and_wait()

        # To calculate the distance we get the pulse_time and divide it by 2 
        # (the pulse walk the distance twice) and by 29.1 becasue
        # the sound speed on air (343.2 m/s), that It's equivalent to
        # 0.34320 mm/us that is 1mm each 2.91us
        # pulse_time // 2 // 2.91 -> pulse_time // 5.82 -> pulse_time * 100 // 582 
        mm = pulse_time * 100 // 582
        return mm

    def distance_cm(self):
        """
        Get the distance in centimeters with floating point operations.
        It returns a float
        """
        pulse_time = self._send_pulse_and_wait()

        # To calculate the distance we get the pulse_time and divide it by 2 
        # (the pulse walk the distance twice) and by 29.1 becasue
        # the sound speed on air (343.2 m/s), that It's equivalent to
        # 0.034320 cm/us that is 1cm each 29.1us
        cms = (pulse_time / 2) / 29.1
        return cms

# main.py
from hcsr04 import HCSR04
from machine import Pin
from time import sleep

# LED setup
green_led = Pin(12, Pin.OUT)
red_led = Pin(13, Pin.OUT)

THRESHOLD = 20  # cm

# ESP32
sensor = HCSR04(trigger_pin=5, echo_pin=18, echo_timeout_us=10000)


while True:
    distance = sensor.distance_cm()
    print('Distance:', distance, 'cm')

    if distance > THRESHOLD:
        green_led.on()
        red_led.off()
    else:
        green_led.off()
        red_led.on()

    sleep(1)

How it works

The firmware triggers the ultrasonic sensor, times the echo pulse, and computes the distance in centimeters. The distance then maps to the LED indicator — each LED a distance band, lighting up as the object approaches.

The echo timing is the physics: the pulse’s round trip at 343 m/s means 29 microseconds per centimeter, and the firmware’s division encodes that constant. The LED banding turns the number into the glanceable interface.

Before you build it for real

The HC-SR04 is a 5 V sensor — the ESP32’s 3.3 V pins need the sensor powered at 5 V with a divider on ECHO, or the pin takes 5 V it was never rated for. The echo timeout must be handled — an object beyond range or a soft surface that absorbs the pulse returns no echo, and the firmware must not hang waiting for it. And the sensor’s beam is 30 degrees wide — the distance reading is to the nearest thing in the cone, not necessarily what the user thinks they are pointing at.

Get the parts

Related examples

FAQ

How does the ultrasonic sensor measure distance?

The sensor fires an ultrasonic pulse and times the echo — sound travels at 343 m/s, so the round-trip time converts directly to distance. The firmware triggers the pulse and measures the echo duration, then maps the result to the LED bar.

Why LEDs for distance?

A distance readout as lit LEDs is the parking-sensor interface: more LEDs lit means closer, readable in a glance without reading numbers. The mapping from centimeters to lit-count is the interface design.