HC-SR04 with CircuitPython

Learn how to use the HC-SR04 ultrasonic sensor with CircuitPython. Step-by-step tutorial with code and wiring diagram.

Jan. 2, 2026

HC-SR04 with CircuitPython

The HC-SR04 ultrasonic sensor is one of the most popular components for measuring distance in robotics and automation projects. Its simplicity and low cost make it ideal for both beginners and advanced users. In this tutorial, we will explore how to integrate it efficiently using CircuitPython, testing the project on a Raspberry Pi Pico.

The advantage of using CircuitPython here is the readability of the code and the vast amount of ready-to-use libraries, such as Adafruit's, which abstracts all the complexity of the trigger and echo pulses.

Necessary Materials

To follow this tutorial, you will need the following components:

  • Development Board: Raspberry Pi Pico (or any other CircuitPython-compatible board).
  • Ultrasonic Sensor: HC-SR04 (Standard 5V version) or the modern HC-SR04P / HC-SR04+ versions (which operate at 3.3V).
  • Logic Level Converter: Mandatory only if you are using the standard 5V sensor with the Raspberry Pi Pico.
  • Jumper Wires: 10 units (if using a logic converter) or 4 units (direct connection).
  • Breadboard: 400 points (and an auxiliary 170-point breadboard if using the converter).
  • Software: circup (for libraries) and mpremote (for execution).

HC-SR04 Versions: 3.3V vs 5V

Before connecting the wires, it is crucial to identify which version of the sensor you have.

  • HC-SR04 (Old Standard): Operates strictly at 5V. Since the Raspberry Pi Pico (and most modern boards) works with 3.3V on the GPIO pins, you cannot connect the sensor's "Echo" pin directly to the board, as the 5V return signal can burn out the microcontroller's port. In this case, it is necessary to use a logic level converter or a voltage divider.
  • HC-SR04P or HC-SR04+: These are updated versions that operate over a wider voltage range (usually 3V to 5.5V). If you have one of these, you can connect it directly to the Raspberry Pi Pico's 3.3V pins without additional components.

Wiring Diagram and Pinout

Below, we describe the pinout for both scenarios.

Scenario A: HC-SR04P / HC-SR04+ (3.3V)

If your sensor is 3.3V compatible, the connection is direct:

Direct wiring diagram for HC-SR04P 3.3V sensor on Raspberry Pi Pico

  • VCC: Connect to the 3V3 (OUT) pin on the Pico.
  • GND: Connect to any GND on the Pico.
  • Trig: Connect to GP17.
  • Echo: Connect to GP16.

Scenario B: Standard HC-SR04 (5V) with Level Converter

If your sensor is the classic 5V model, you must power the sensor with 5V (VBUS), but convert the communication signals to 3.3V:

Wiring diagram for HC-SR04 5V sensor on Raspberry Pi Pico with logic level converter

  • Sensor Power: VCC to VBUS (5V) on the Pico and GND to GND.
  • Logic Converter (HV Side - High Voltage): Connect to 5V (VBUS).
  • Logic Converter (LV Side - Low Voltage): Connect to 3V3 (OUT).
  • Signals (via Converter):
    • Trig: Pico GP17 -> LV3 -> HV3 -> Sensor Trig.
    • Echo: Sensor Echo -> HV4 -> LV4 -> Pico GP16.

Environment Setup

We will use two essential tools from the Python ecosystem for microcontrollers: circup to manage packages and mpremote to control the board.

Installing the Library

CircuitPython has an official Adafruit library specifically for this sensor, which makes the work much easier. Connect your board via USB and run the following in your terminal:

circup install adafruit_hcsr04

The command above will download the adafruit_hcsr04.mpy driver and automatically copy it to the lib folder on your board.

The Code

Copy the code below and save it as main.py (or another name of your preference) on your computer.

from time import sleep

from adafruit_hcsr04 import HCSR04
from board import GP16, GP17

with HCSR04(trigger_pin=GP17, echo_pin=GP16) as sonar:
    while True:
        print(f"{sonar.distance:.1f}cm")
        sleep(0.5)

Understanding the Script

  • Imports: We import the HCSR04 class from the library we installed and define pins GP16 and GP17 via the board module.
  • Context Manager (with): We use the with statement to initialize the sensor. This is a best practice in CircuitPython as it ensures hardware resources (the pins used) are correctly released if the code is interrupted or finished, preventing "pin in use" errors when restarting the script.
  • .distance Property: The reading is done by accessing sonar.distance. The library automatically calculates the sound's time of flight and returns the value already converted to centimeters (float).
  • Loop: The code reads the distance and prints it to the console every 0.5 seconds.

Running the Project

With the code saved and the board connected, use mpremote to run the script directly:

mpremote run main.py

You should see distance measurements updating in real-time in your terminal.

Conclusion

Using the HC-SR04 with CircuitPython is extremely straightforward thanks to the abstraction provided by the Adafruit library. Always remember to check your sensor's operating voltage to protect your Raspberry Pi Pico.

GIF demonstrating terminal displaying real-time distance measured by HC-SR04 sensor