Un sensor de estacionamiento que cabe en la palma de la mano

¿Alguna vez te fijaste en cómo tu auto sabe que estás a punto de chocar contra la pared del estacionamiento? Detrás de ese pitido está un sensor ultrasónico, exactamente la misma pieza que vas a controlar en este proyecto. La idea es simple: la Raspberry Pi Pico lanza un pulso de sonido inaudible, mide cuánto demora el eco en volver, y con ese tiempo calcula a cuántos centímetros está el objeto que tiene en frente.

Al terminar vas a tener un medidor de distancia funcionando que reporta los centímetros en el monitor serial, y, lo más importante, vas a entender dos cosas que muchos tutoriales saltan: por qué el HC SR04 puede dañar tu Pico si lo conectas directo, y cómo resolverlo con dos resistencias. Todo en MicroPython, sin instalar ninguna librería externa.

Cómo "ve" el HC SR04 sin tocar nada

El HC SR04 mide distancia con la misma física que usan los murciélagos: ecolocalización. Tiene dos cápsulas, una que emite y otra que escucha. Cuando le mandas un pulso por el pin Trig, dispara un tren de 8 ciclos de ultrasonido a 40 kHz. Ese sonido viaja, rebota en el primer obstáculo y vuelve. El sensor levanta el pin Echo a nivel alto durante exactamente el tiempo que el sonido estuvo en el aire, ida y vuelta.

El resto es aritmética. El sonido viaja a unos 343 m/s en aire a temperatura ambiente, así que cada microsegundo equivale a una fracción conocida de distancia. La cuenta clásica para el HC SR04 es dividir la duración del pulso de Echo (en microsegundos) entre 58 para obtener centímetros. Ese 58 no es magia: ya incluye la velocidad del sonido y el hecho de que el recorrido es de ida y vuelta (por eso no es ~29). Si alguna vez quieres trabajar en temperaturas extremas, ese número se puede ajustar, porque la velocidad del sonido sube con el calor.

Sensor ultrasónico HC SR04 con sus cuatro pines Vcc, Trig, Echo y Gnd

El detalle que protege tu Pico: 5V contra 3.3V

Acá está la trampa que arruina muchos montajes. La mayoría de los HC SR04 del mercado están pensados para Arduino y trabajan con 5 volts, tanto en la alimentación como en sus niveles lógicos. La Raspberry Pi Pico, en cambio, es de 3.3 volts: meterle 5V a un pin de entrada (GPIO) puede degradarlo o quemarlo con el tiempo.

La buena noticia es que no necesitas un conversor de nivel caro. El problema es solo el pin Echo, que es el único que sale del sensor hacia la Pico (Trig va en sentido contrario y no molesta). Con dos resistencias armas un divisor de tensión que baja esos 5V a un nivel seguro y cómodo para la Pico:

  • La resistencia de 1.2K va entre el pin Echo del sensor y el punto de medición.
  • La resistencia de 2.2K va desde ese mismo punto de medición a tierra (GND).
  • El nodo donde se unen las dos resistencias es de donde sale la señal de Echo, pero ya rebajada a unos 3.3V lógicos. Ese nodo es el que conectas al GPIO de la Pico.

Esta relación 1.2K / 2.2K no es arbitraria: con 5V de entrada entrega cerca de 3.2V en el nodo, justo dentro del rango que la Pico interpreta como nivel alto sin pasarse. Si solo tienes resistencias de otros valores, la regla es que la de abajo (a GND) sea un poco mayor que la de arriba para que el resultado caiga entre 3.0V y 3.3V.

Un par de cuidados durante el armado:

  • Alimenta el sensor con 5V, que en la Pico salen del pin VBUS (el que viene directo del USB). No lo alimentes con 3V3: a menos voltaje el HC SR04 se vuelve inestable o directamente no dispara.
  • Lleva GND de la Pico a los buses de alimentación del protoboard y desde ahí al sensor. Una tierra común mal hecha es la causa número uno de lecturas erráticas.
  • Respeta qué resistencia va dónde: la de 2.2K a tierra, la de 1.2K al pin Echo. Si las inviertes, el divisor entrega otro voltaje.

Diagrama de conexión del HC SR04 a la Raspberry Pi Pico con el divisor de tensión de dos resistencias

Montaje sobre protoboard

Con el diagrama claro, el armado físico toma pocos minutos. Una protoboard de 400 puntos sobra para este circuito:

  1. Coloca la Raspberry Pi Pico a horcajadas sobre el canal central de la protoboard, dejando una fila de contactos libre a cada lado.
  2. Lleva VBUS de la Pico al bus positivo (rojo) y un GND al bus negativo (azul). Estos dos buses alimentan todo.
  3. Conecta Vcc del HC SR04 al bus positivo (5V) y Gnd del sensor al bus negativo.
  4. Une Trig del sensor directo al GPIO 16 de la Pico. Trig va del micro al sensor, así que no necesita divisor.
  5. Arma el divisor para Echo: del pin Echo, la resistencia de 1.2K hacia un nodo libre; de ese nodo, la resistencia de 2.2K hacia GND; y del mismo nodo, un cable hacia el GPIO 15 de la Pico.

Protoboard de 400 puntos lista para montar el circuito de la Pico y el sensor

El código en MicroPython, sin librerías

La gracia de este ejemplo es que no usa ningún módulo especial para el HC SR04: se programa el protocolo a mano con los módulos estándar machine y time. Eso lo hace transparente y portable, y de paso entiendes qué pasa por dentro en vez de confiar en una caja negra.

La lógica es la que ya describimos: se da un pulso corto en Trig, se mide cuánto dura el nivel alto en Echo usando marcas de tiempo en microsegundos, y se convierte esa duración a centímetros. Carga este código en tu Pico con Thonny y observa el monitor serial.

Python
# GEEK FACTORY - Dale vuelo a tus proyectos
# https://www.geekfactory.mx
#
# Ejemplo para medir distancia con el sensor ultrasónico HC-SR04 y la Raspberry Pi Pico,
# el resultado de la medición se muestra en la terminal serial.
#
# importar los módulos de python necesarios para que este programa funcione
import machine, time
# pines "echo" y "trigger" para la interfaz con el sensor
pinecho = machine.Pin(15, machine.Pin.IN)
pintrig = machine.Pin(16, machine.Pin.OUT)
# Definir una función que realiza la medición de distancia con el sensor ultrasónico
# y retorna el resultado al código que la llama.
def read_ultrasonic():
    # esperar un poco antes de enviar el pulso de disparo
    pintrig(0)
    time.sleep_us(10)
    # enviar pulso de disparo de 10 uS
    pintrig(1)
    time.sleep_us(10)
    pintrig(0)
    
    # a continuación mediremos el puso de eco
    # esperamos mientras comienza el pulso alto
    while pinecho() == 0:
        pass
    # almacenar en una variable el tiempo en el que inicia el pulso en el pin "echo"
    toff = time.ticks_us()
    
    # esperamos mientras el pulso está en nivel alto
    while pinecho() == 1:
        pass
    # almacenar en una variable el tiempo en el que termina el pulso en el pin "echo"
    ton = time.ticks_us()
        
    # calcular la duración del pulso de eco
    elapsedtime = ton - toff
    
    # calcular la distancia en centímetros
    dist = elapsedtime / 58
    
    # devolvemos la distancia que acabamos de calcular dentro de la función
    return dist
while True:
    # llamamos a la función de medición
    distance = read_ultrasonic()
    # imprimimos la distancia
    print(f'Distancia medida: {distance} cm')
    # esperamos un segundo
    time.sleep(1)

Dos puntos clave para leer este código con criterio:

  • time.sleep_us(10) crea el pulso de disparo de 10 microsegundos que exige la hoja de datos del HC SR04. Más corto y el sensor no dispara; mucho más largo y no pasa nada malo, pero pierdes precisión en el timing.
  • Los dos bucles while pinecho() == ... son la forma manual de medir el ancho del pulso: el primero espera a que Echo suba, el segundo a que baje, y la resta de ticks_us() da la duración exacta. Es bloqueante (la Pico no hace otra cosa mientras mide), lo que está bien para un ejemplo, pero conviene saberlo si después lo integras a un proyecto con más tareas.

Pruebas y depuración

Apunta el sensor a una pared u objeto plano y mueve la mano frente a él: los centímetros en el monitor serial deberían seguir el movimiento. Si algo no calza, esta es la guía rápida:

  • Siempre lees 0 o un número gigante fijo: casi siempre es el divisor mal armado o la tierra suelta. Revisa que el nodo entre las dos resistencias sea el que va al GPIO 15, no el pin Echo directo.
  • Lecturas que saltan al azar: superficie demasiado inclinada o blanda (la tela y la espuma absorben el ultrasonido). Prueba contra algo plano y duro.
  • Nada en el monitor: confirma que el sensor recibe 5V desde VBUS y que la Pico está corriendo el script (no solo guardado).
  • El mínimo no baja de 2 cm: es normal, el HC SR04 tiene una zona ciega cercana; su rango útil va de unos 2 cm a 4 m.

Variantes y mejoras

Una vez que tienes la medición funcionando, el proyecto se presta para crecer:

  • Alarma de proximidad: agrega un buzzer a otro GPIO y haz que pite más rápido a medida que la distancia baja. Es, literalmente, el sensor de estacionamiento del auto a escala.
  • Pantalla sin PC: con una OLED SSD1306 por I2C puedes mostrar los centímetros directo en el montaje y soltar el cable USB. Cambias el print por una escritura a la pantalla.
  • Promediado para estabilizar: en vez de imprimir una sola lectura, toma 5 seguidas y promédialas. Suaviza los saltos sin agregar hardware.
  • Versión inalámbrica: si usas una Raspberry Pi Pico W, puedes publicar la distancia por WiFi a un panel web o a tu domótica. El código de medición no cambia, solo le sumas la parte de red.

Personalización para Chile

Este proyecto usa puro hardware estándar que consigues en stock local en MechatronicStore, sin importar nada:

  • Raspberry Pi Pico (RP2040) (SKU 22739): $7.990 CLP. Las versiones Pico W y Pico 2 también sirven y corren el mismo código.
  • Sensor ultrasónico HC SR04 (SKU G-413): $3.290 CLP. El mismo módulo del tutorial.
  • Breadboard 400 puntos (SKU C-301): $2.690 CLP. Suficiente para todo el circuito.
  • Pack cables macho macho para protoboard (SKU C-280): $3.490 CLP. Para todas las conexiones del montaje.

Las dos resistencias del divisor (1.2K y 2.2K, ¼ de watt) vienen en cualquier kit de resistencias surtidas; si no tienes esos valores exactos, cualquier par donde la de tierra sea algo mayor que la del pin Echo y el resultado quede entre 3.0V y 3.3V funciona igual.

Recursos

  • Tutorial original (en español): Sensor ultrasónico con Raspberry Pi Pico en MicroPython, publicado por Geek Factory. El código de ejemplo es de su autoría y se reproduce tal cual.
  • Documentación MicroPython: módulo machine y módulo time para la API de pines y los temporizadores en microsegundos.

Versión chilena con componentes en stock local en MechatronicStore, basada e inspirada en el tutorial de Geek Factory.