El sensor ultrasónico HC-SR04 es un viejo conocido, ampliamente utilizado en un sinnúmero de aplicaciones donde sea necesario realizar una medición de distancias, como en robots que esquivan obstáculos, detectores de personas o para medir el nivel de un líquido. Es sencillo de usar y también barato. En este artículo veremos como utilizarlo en Micropython.
El sensor HC-SR04
El HC-SR04 basa su funcionamiento en la propiedad de las ondas sonoras de rebotar contra las superficies y objetos. Consiste en un transmisor que emite un tren de señales ultrasónicas con una frecuencia de 40 KHz que de desplazan por el aire, rebotan contra el obstáculo que está al frente y son captadas por el receptor ubicado sobre el mismo sensor. A partir del tiempo que demora la señal en completar ese recorrido y conociendo la velocidad del sonido en el aire, se calcula la distancia a la que está el obstáculo.
El módulo tiene 4 pines, dos de alimentación y dos de señales:
Vcc: Tensión de alimentación (5V)
Trig: Trigger. Entrada al módulo. Dispara la transmisión de ultrasonidos.
Echo: Salida que indica la recepción de la señal rebote.
GND: Tierra de alimentación
Como vemos, el HC-SR04 debe alimentarse con 5 voltios. En este ejemplo, donde uso una placa D1 mini, los voy a tomar del pin 5V que deriva esa tensión de la interfaz USB, a partir de los cuales se obtienen los 3,3V del ESP8266. Esto implica que la salida Echo del sensor también nos va a entregar 5V. Aunque no hay información oficial sobre el tema, la experiencia con el ESP8266 demuestra que es capaz de tolerar 5V en sus entradas (las pruebas que yo hice lo confirman). Si quieren estar 100% seguros y bajar ese valor antes del entrar al micro, pueden intercalar un divisor resistivo formado por una resistencia de 2K7 y 1K5 como se ve a continuación.
En la entrada Trig del HC-SR04 vamos a aplicar una señal de 3,3V, pero esto no es un inconveniente, porque el sensor lo reconoce como un valor ALTO válido.
El circuito completo (sin divisor resistivo en Echo) quedaría como sigue:
Lectura en micropython
Veamos ahora como utilizar el sensor desde Micropython.
Entre las librerías estandar de Micropython (las que están incluidas con el intérprete) no hay ninguna que nos permita usar el HC-SR04. Sin embargo, afortunadamente hay muchos desarrolladores en la comunidad que realizan sus aportes para ampliar las posibilidades de este lenguaje y escriben módulos para distintas placas o sensores. Este es el caso del HC-SR04, del cual podemos encontrar en la red mas de un módulo disponible. En este artículo usaremos el que se puede encontrar en este repositorio
Para descargar el módulo debemos acceder al repositorio, hacer click en el botón CODE y descargar el archivo ZIP.
Una vez descargado, hay que descomprimir el ZIP y subir el módulo hcsr04.py a nuestra placa para que la pueda usar el intérprete Python que ya está grabado allí. Debemos guardar este archivo dentro de una carpeta lib, que primero debemos crear. Para hacerlo, debemos activar la visualización de archivos en Thonny yendo al menú Visualización y tildando la opción Archivos, con lo que empezaremos a tener una ventana con los archivos locales de nuestra computadora y los que están almacenados en la placa con micropython. Luego, hacemos click con el botón derecho en la zona de los archivos de la placa y elegimos Nuevo Directorio y le damos como nombre lib
Puede que ustedes no tengan un archivo main, y sólo boot, eso no importa, el procedimiento es exactamente el mismo.
Ahora, hay que abrir el archivo hcsr04.py que descargamos y descomprimimos en Thonny y luego guardar con Fichero – Guardar Como – Micropython Device y elegimos la carpeta lib que acabamos de crear. Debe quedar algo así:
Una vez copiado el módulo en la carpeta lib ya estamos en condiciones de utilizarlo desde el programa. Como siempre, lo primero es importarlo. En esta ocasión vamos a importar la clase HCSR04:
from hcsr04 import HCSR04
Luego, creamos o instanciamos un objeto de esa clase, usando el constructor:
medidor = HCSR04 (trigger_pin=D2 , echo_pin=D1 )
El constructor tiene el siguiente formato general:
sensor = HCSR04 (trigger_pin, echo_pin, echo_timeout_us)
Los parámetros son los siguientes:
trigger_pin: pin que se conecta a la entrada Trig del sensor
echo_pin: pin que se conecta a la salida Echo del sensor
echo_timeout: Tiempo máximo de espera antes de producir un error
Por omisión el timeout está fijado en 30.000 us (30 ms) pero se puede modificar especificando otro valor en el constructor.
Un objeto de la clase HCSR04 tiene dos métodos disponibles:
distance_cm (): Devuelve la distancia medida en centímetros como un número de punto flotante (con coma)
distance_mm (): Devuelve la distancia medida en milímetros como un número entero.
Ejemplo
El programa de pruebas puede verse a continuación. Luego de crear el objeto medidor, es un bucle sin fin donde se llama al método distance_cm en una estructura try-except (si no sabes como funciona, consulta la explicación aquí).
#Sensor de distancias HCS-R04
#Mapeo de GPIO de D1 Mini
D0 = 16
D1 = 5
D2 = 4
D3 = 0
D4 = 2
D5 = 14
D6 = 12
D7 = 13
D8 = 15
from hcsr04 import HCSR04
from time import sleep
medidor = HCSR04 (trigger_pin = D2 , echo_pin = D1)
while (True):
try:
distancia = medidor.distance_cm ()
print ("Distancia = ", distancia)
sleep (1)
except:
print ("Error!")
Al menos los sensores que pude probar nunca devolvieron el error de timeout. Cuando la distancia a medir supera los 4m, devuelven un valor cercano a 0 o negativo. Para filtrar estos errores y devolver un valor promediado que elimine pequeñas variaciones agregué una función que emplea sólo las lecturas de valores mayores que 0 para hacer un promedio de 16 medidas
#Sensor de distancias HCS-R04
#Mapeo de GPIO de D1 Mini
D0 = 16
D1 = 5
D2 = 4
D3 = 0
D4 = 2
D5 = 14
D6 = 12
D7 = 13
D8 = 15
from hcsr04 import HCSR04
from time import sleep
medidor = HCSR04 (trigger_pin = D2 , echo_pin = D1)
def midePromedio ():
suma=0
for i in range (0,16):
distancia = medidor.distance_cm ()
sleep (0.1)
if (distancia > 0):
suma+=distancia
return suma/16
while (True):
print ("Distancia = ", midePromedio ())
En el video puede verse el programa en funcionamiento:
Cualquier duda o sugerencia, pueden escribir en la sección de comentarios, así como sus experiencias con el timeout. Hasta la próxima!