Sensor ultrassônico HC-SR04 com Raspberry Pi Pico usando MicroPython

Tempo de leitura: 11 minutes

Este tutorial mostra como fazer a interface de sensores ultrassônicos HC-SR04 com Raspberry Pi Pico para medição de distância sem contato usando MicroPython. Primeiro, aprenderemos a fazer a interface do HC-SR04 com o Raspberry Pi Pico. Depois disso, veremos o código de exemplo do MicroPython para medir a distância e exibi-lo no terminal MicroPython. Em segundo lugar, veremos um exemplo do MicroPython para exibir a distância medida (cm) em um OLED SSD1306.

 

Pré-requisitos

Antes de começarmos esta lição, certifique-se de que você esteja familiarizado e tenha a versão mais recente do Python 3 em seu sistema, tenha configurado o MicoPython no Raspberry Pi Pico e tenha um Ambiente de Desenvolvimento Integrado (IDE) em execução no qual faremos a programação. Usaremos o mesmo Thonny IDE que usamos anteriormente quando aprendemos a piscar e perseguir LEDs em micro-python.

 

Introdução ao Sensor Ultrassônico HC-SR04

Para fazer a interface do sensor ultrassônico HC-SR04 com o Raspberry Pi Pico, devemos conhecer a funcionalidade de cada pino do sensor ultrassônico. Conhecendo a funcionalidade dos pinos de entrada e saída, poderemos identificar quais pinos GPIO do Raspberry Pi Pico devem ser usados para interface com o HC-SR04.

Pinagem HC-SR04

A figura abaixo mostra a configuração dos pinos de um sensor ultrassônico. Consiste em quatro pinos a saber; Vcc, terra, gatilho e pino de eco.

Vcc e terra são usados para alimentar o sensor. Devemos fornecer 5 volts ao pino Vcc e conectar o pino GND ao terminal terra da fonte de alimentação.

Trigger: É um pino de entrada. Um pino de gatilho é usado para iniciar o sensor ultrassônico para iniciar a medição de distância ou variação de distância. Quando os usuários desejam obter medições de distância do sensor, aplicamos um pulso de 10µs a este pino.

Echo: Este é um pino de saída de pulso. O pino de eco produz um pulso como saída. A largura do pulso ou on-time do pulso depende da distância entre o sensor ultrassônico e o obstáculo que é colocado na frente do sensor HC-SR04. Em condições ociosas, este pino permanece em um nível baixo ativo.

Mais detalhes sobre o funcionamento do sensor ultrassônico são fornecidos na próxima seção.

Como funciona o sensor HC-SR04?

O sensor ultrassônico HC-SR04 mede a distância usando ondas sonoras ultrassônicas inaudíveis de frequência de 40KHz. Assim como as ondas sonoras, as ondas ultrassônicas viajam pelo ar e, se houver algum obstáculo à sua frente, elas refletem de acordo com seu ângulo de incidência. Além disso, se um objeto é colocado paralelamente a um transmissor ultrassônico, as ondas ultrassônicas refletem exatamente em um ângulo de 180 graus. Portanto, para medição de distância com sensor HC-SR05, colocamos o objeto em teste exatamente em posição paralela com um sensor ultrassônico conforme mostrado na figura abaixo.

O sensor ultrassônico HC-SR05 consiste em dois módulos básicos, como transmissor ultrassônico e módulo receptor ultrassônico. O circuito transmissor converte um sinal elétrico em uma explosão de 40 KHz de 8 pulsos de onda de sonar. O sinal elétrico de entrada para o circuito transmissor é uma entrada de pulso de 10µs para o pino de disparo do sensor HC-SR04. Como mencionamos anteriormente, aplicamos esse sinal de entrada do gatilho através do Raspberry Pi Pico ou de qualquer microcontrolador. Por outro lado, o circuito receptor ultrassônico ouve essas ondas ultrassônicas que são produzidas pelo circuito transmissor.

Medir o tempo de pulso de eco do HC-SR04 com Raspberry Pi Pico

  • Para começar a variar com o HC-SR04, primeiro aplicamos um pulso de 10µs ao pino de disparo do sensor HC-SR04 do pino de saída digital Raspberry Pi Pico.
  • Assim que o sinal de disparo de entrada de 10µs torna-se ativo baixo, o circuito transmissor produz uma rajada de 8 pulsos de sonar ultrassônico. Ao mesmo tempo, o pino Echo também faz uma transição de um nível lógico baixo para um nível lógico alto.
  • Quando o pino Echo fica alto, começamos a medir o tempo com a função de medição de duração do Raspberry Pi Pico.
  • Essas ondas viajam pelo ar e se houver algum objeto colocado em paralelo ao sensor, essas ondas refletem de volta após uma colisão com o objeto.
  • Assim que as ondas ultrassônicas recebidas pelo circuito receptor após atingirem um objeto, o pino de eco fica baixo. O Raspberry Pi Pico detecta essa transição do sinal de saída de eco de alto ativo para um nível baixo ativo e interrompe a medição.

Resumindo, medindo o tempo de ativação do sinal de pulso de saída Echo, podemos medir a distância. A figura a seguir ilustra o sinal de saída de eco em relação ao sinal de disparo de entrada e 8 pulsos de sonar.

 

A duração pela qual o sinal de saída de eco permanece alto depende da distância entre o sensor ultrassônico e o objeto que colocamos na frente do sensor. Quanto maior a distância, maior o tempo que as ondas do sonar levarão para chegar de volta ao circuito do receptor ultrassônico. Porque as ondas ultrassônicas viajam pelo ar com a velocidade do som e a velocidade permanece constante.

Como converter a duração do tempo em distância

Na próxima seção, veremos como medir a duração do pulso usando o Raspberry Pi Pico. Vamos supor que medimos o pulso de saída no tempo (t) com Raspberry Pi Pico. Agora a questão é como converter esse tempo medido em distância.

Bem, esta é a parte mais óbvia deste tutorial. No ensino médio, todos estudamos uma conhecida equação distância-tempo que é S = vt. Podemos converter a duração do pulso (t) na distância (S) usando esta equação.

Distância (S) = Velocidade (v) * t //distância em metros

Aqui v é a velocidade das ondas ultrassônicas no ar. A velocidade das ondas ultrassônicas no ar é igual à velocidade do som, que é 340 m/s (metro por segundo).

A equação acima dará saída de distância em unidades de metro. Mas, se você quiser a distância em unidades de centímetros, multiplique 340 por 100. Assim, a equação acima se torna:

S = 34000 * t // distância em cm

O tempo dado na fórmula acima também deve ser dividido por dois. Porque as ondas ultrassônicas viajam do transmissor para o obstáculo e depois refletem de volta ao circuito receptor percorrendo a mesma distância. Queremos encontrar apenas a distância entre HC-SR04 e o objeto. Portanto, a fórmula para calcular a distância torna-se

S = 17000 * t // distância em cm

Nota: Você não precisa se preocupar com esses cálculos, pois usaremos a biblioteca MicroPython para o sensor ultrassônico HC-SR04 para fazer medições de distância.

 

Como fazer a interface do sensor ultrassônico HC-SR04 com o Raspberry Pi Pico?

Até agora vimos o funcionamento do sensor ultrassônico e os detalhes dos pinos. Agora sabemos que fazer a interface de um sensor HC-SR04 com Raspberry Pi Pico. Precisamos de quatro pinos, dos quais dois são pinos de fonte de alimentação e dois são pinos de saída de entrada digital. Um pino GPIO do Raspberry Pi Pico será usado como pino de saída digital para fornecer um sinal de disparo ao sensor ultrassônico. Da mesma forma, um pino GPIO será usado como um pino de entrada digital para capturar o sinal de saída de eco do sensor de saída.

Agora faça a conexão do Raspberry Pi Pico com o sensor HC-SR04 de acordo com este diagrama de conexão.

HC-SR04Raspberry Pi Pico
VCCVSYS (5V)
GNDGND
TriggerGP2
EchoGP3

 

Biblioteca MicroPython HC-SR04

Por padrão, o MicroPython não possui uma implementação do sensor HC-SR04. Mas, MicroPyhon fornece API I2C que pode ser usada para ler valores do sensor HC-SR04. Felizmente, há uma biblioteca disponível que é desenvolvida pela Adafruit e pode ser baixada neste link. Baixe a seguinte biblioteca e carregue-a na placa Raspberry Pi Pico com o nome de hcsr04.py na pasta lib.

import machine, time
from machine import Pin

__version__ = '0.2.0'
__author__ = 'Roberto S鐠嬶箯chez'
__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

MicroPython HC-SR04 Sensor Ultrassônico Raspberry Pi Pico Code

Após o upload da biblioteca HC-SR04 para a placa Raspberry Pi Pico, agora podemos usar as funções disponíveis na biblioteca HC-SR04 para obter as leituras dos sensores.

Exemplo de MicroPython HC-SR04

Agora vamos ver o script MicroPython para HC-SR04 para obter leituras de distância. Copie o código a seguir para o arquivo main.py e carregue o arquivo main.py para o Raspberry Pi Pico.

Este script MicroPython lê a distância do sensor HC-SR04 e imprime no console do shell MicroPython.

from hcsr04 import HCSR04
from time import sleep

sensor = HCSR04(trigger_pin=2, echo_pin=3, echo_timeout_us=10000)

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

Como o Código Funciona?

Importando Bibliotecas

Primeiramente, importamos o módulo hcsr04 e sleep para que possamos acessar seus métodos através de suas classes definidas.

from hcsr04 import HCSR04
from time import sleep

Definindo Pinos GPIO Raspberry Pi Pico para HC-SR04

Agora, inicializamos os pinos gpio do Raspberry Pi Pico para o sensor HC-SR04. O primeiro argumento especifica o pino GPIO para o pino de disparo. Isso é dado como GPIO2. O segundo parâmetro especifica o pino GPIO para o pino de eco. Isso é dado como GPIO3. O último argumento é o tempo máximo de viagem da onda sonora.

HC-SR04 cria um objeto do método HCSR04() da classe hcsr04 com o nome de “sensor”.

sensor = HCSR04(trigger_pin=2, echo_pin=3, echo_timeout_us=10000)

Obtendo Valores do Sensor HC-SR04

Dentro do loop while, obtenha a leitura do sensor usando um objeto “sensor” em distance_cm() e salve o valor na variável distance.

distance = sensor.distance_cm()

Depois disso, imprima os valores de distância no console do shell MicroPython após cada segundo.

print('Distance:', distance, 'cm')
sleep(1)

 

Demonstração

Para testar o script MicroPython para HC-SR04 com Raspberry Pi Pico, carregue o arquivo main.py em sua placa.

Você verá o valor da distância sendo impresso no console do shell após cada segundo da seguinte forma:

 

MicroPython: Exibindo os valores do sensor HC-SR04 no display OLED

Nesta seção, veremos como exibir a leitura da distância medida em um display OLED 0,96 SSD1306 usando MicroPython e Raspberry Pi Pico.

Você pode encontrar mais informações sobre OLED com Raspberry Pi Pico aqui:

Biblioteca MicroPython de exibição OLED SSD1306

Para um display OLED, também precisaremos carregar uma biblioteca para o Raspberry Pi Pico.

  • Para fazer isso com sucesso, abra seu Thonny IDE com seu Raspberry Pi Pico conectado ao seu sistema. Vá para Tools > Manage Packages. Isso abrirá o Thonny Package Manager.

Pesquise “ssd1306” na barra de pesquisa digitando seu nome e clicando no botão “Search on PyPI”.

  • A partir dos seguintes resultados de pesquisa, clique no destacado abaixo: micropython-ssd1306

Instale esta biblioteca.

Após alguns momentos, esta biblioteca será instalada com sucesso. Agora estamos prontos para programar nosso Raspberry Pi Pico com display OLED.

 

Conectando a tela OLED SSD1306 com Raspberry Pi Pico e HC-SR04

Precisaremos dos seguintes componentes para conectar nosso Raspberry Pi Pico ao display OLED e HC-SR04.

  • Raspberry PI Pico
  • HC-SR04
  • Tela OLED SSD1306
  • Fios de conexão

O display OLED possui 4 terminais que iremos conectar com o Raspberry Pi Pico. Como o display OLED requer uma tensão de operação na faixa de 3,3-5V, conectaremos o terminal VCC com 5V que será em comum com a placa e o HC-SR04. O SCL do display será conectado com o pino SCL do módulo e o SDA do display será conectado com o SDA do módulo. O aterramento de todos os três dispositivos será mantido em comum.

As conexões entre os três dispositivos que estamos usando podem ser vistas abaixo.

SSD1306 OLED DisplayRaspberry Pi Pico
VCC5V
SDAGP0 (I2C0 SDA)
SCLGP1 (I2C0 SCL)
GNDGND
HC-SR04Raspberry Pi Pico
VCC5V
GNDGND
TriggerGP2
EchoGP3

 

Esquema Raspberry Pi Pico com OLED e HC-SR04

Siga o diagrama esquemático abaixo e conecte-os de acordo.

Raspberry Pi Pico com diagrama de conexão HC-SR04 e OLED
Raspberry Pi Pico com diagrama de conexão HC-SR04 e OLED

 

Código MicroPython: Exibindo a distância HC-SR04 no display OLED

from machine import Pin, I2C
from hcsr04 import HCSR04
from time import sleep
from ssd1306 import SSD1306_I2C

sensor = HCSR04(trigger_pin=2, echo_pin=3, echo_timeout_us=10000)

i2c=I2C(0,sda=Pin(0), scl=Pin(1), freq=400000)    #initializing the I2C method 
oled = SSD1306_I2C(128, 64, i2c)

while True:
  oled.fill(0)
  distance = str(sensor.distance_cm())

  oled.text("Distance", 0,15)
  oled.text(distance +" cm", 0,35)
  oled.show()
  sleep(1)

 

Como funciona o código?

Na seção, explicamos apenas a parte do código Micropython que é usada para exibir os valores do sensor HC-SR04 no OLED. Porque o resto do código é o mesmo que usamos na seção anterior para exibir as leituras de distância no console do shell.

Importaremos o ssd1306, que é a biblioteca de exibição OLED que instalamos anteriormente. Isso nos ajudará a acessar todas as funções definidas dentro dele. Além disso, estaremos importando a classe Pin e a classe I2C do módulo da máquina. Isso ocorre porque temos que especificar o pino para comunicação I2C.

from machine import Pin, I2C
from ssd1306 import SSD1306_I2C

Em seguida, inicializaremos os pinos I2C GPIO para SCL e SDA, respectivamente. Usamos os pinos I2C0 SCL e I2C0 SDA.

Criamos um método I2C() que recebe quatro parâmetros. O primeiro parâmetro é o canal I2C que estamos usando. O segundo parâmetro especifica o pino I2C GPIO da placa que está conectada à linha SDA. O terceiro parâmetro especifica o pino I2C GPIO da placa que está conectada à linha SCL. O último parâmetro é a conexão de frequência.

Estamos configurando o SCL no pino 1 e o SDA no pino 0.

i2c=I2C(0,sda=Pin(0), scl=Pin(1), freq=400000)    #initializing the I2C method

Agora, vamos criar um objeto ‘oled’ de SSD1306_I2C que usa a largura, altura e o objeto i2c como parâmetros.

oled = SSD1306_I2C(128, 64, i2c)

Limpa o display OLED com a rotina led.fill().

oled.fill(0)

Por fim, exiba o texto junto com a leitura da distância no OLED a cada 1 segundo.

distance = str(sensor.distance_cm())

oled.text("Distance", 0,15)
oled.text(distance +" cm", 0,35)
oled.show()
sleep(1)

No final, chame o método show() no método oled para que as alterações sejam exibidas no OLED.

oled.show()

 

Demonstração

Carregue o código acima como arquivo main.py para Raspberry Pi Pico. Você obterá as leituras do HC-SR04 no display OLED da seguinte forma: