Sensor de Distância Ultrassônico HC-SR04: Manual Técnico Completo

HC-SR04 — manual técnico completo

Introdução

Neste tutorial, será apresentado como instalar, configurar e utilizar o módulo sensor de distância ultrassônico HC-SR04. Se desejar adquirir este sensor, clique aqui.

Descrição geral do produto

O que é o HC-SR04?

O HC-SR04 é um módulo sensor de distância ultrassônico capaz de medir distâncias de 2 cm a 4 m com ótima precisão e baixo preço. Diferente de sensores de distância por infravermelho (como o Sharp GP2Y0A21), ele usa ondas sonoras de alta frequência para detectar obstáculos independentemente da cor, textura ou iluminação do alvo.

O módulo já vem com um circuito pronto com emissor e receptor acoplados e apenas 4 pinos (VCC, Trigger, ECHO, GND) para medição — não é necessário montar o circuito de excitação do transdutor, como ocorreria com transdutores ultrassônicos avulsos.

Para que serve?

O HC-SR04 mede a distância até o primeiro obstáculo à frente e entrega essa informação ao microcontrolador. É aplicado em projetos como:

  • Robôs móveis com desvio de obstáculos e navegação autônoma;
  • Estacionamento inteligente e sensores de ré com alarme de proximidade;
  • Controle de nível de tanques, silos e caixas d’água (medição sem contato).

Por que devo usar?

  • Medição sem contato: detecta objetos a até 4 m sem tocar no alvo, ideal para líquidos e superfícies de difícil acesso;
  • Independência da luz: funciona no escuro total, ao contrário de sensores por reflexão infravermelha;
  • Baixo custo e fácil integração: interface digital simples de 2 pinos (Trigger e ECHO), com exemplos prontos para Arduino, ESP32 e Raspberry Pi.

Quando devo usar?

O HC-SR04 é indicado quando:

  • É necessário medir distâncias de 2 cm a 4 m com precisão de até 3 mm;
  • O alvo é uma superfície plana e rígida, perpendicular ao sensor;
  • Basta uma medição local com fiação curta e custo baixo.

Não é a melhor escolha quando:

  • O objeto é macio ou absorve som (tecidos, espuma, cortinas) — o eco retorna fraco ou não retorna;
  • A precisão exigida é sub-milimétrica ou a medição precisa de grande ângulo de cobertura (preferir sensores a laser/LIDAR);
  • O ambiente tem muita turbulência de ar ou vibração que desvia as ondas sonoras.

Como funciona a medição por ultrassom

O módulo mede distância pelo princípio do tempo de voo (time-of-flight) do som. Para iniciar uma medição é necessário alimentar o módulo e colocar o pino Trigger em nível alto por mais de 10 µs. O sensor então emite uma rajada de ondas sonoras em 40 kHz que, ao encontrar um obstáculo, rebate de volta em direção ao módulo.

Durante o tempo entre a emissão e a recepção do eco, o pino ECHO permanece em nível alto. A distância é calculada a partir do tempo em que o pino ECHO ficou em nível alto após o Trigger:

Fórmula: Distância = (Tempo ECHO em nível alto × Velocidade do Som) / 2

A divisão por 2 é necessária porque a onda sonora percorre duas vezes a distância procurada (ida e volta). Considerando a velocidade do som de aproximadamente 343 m/s a 20 °C, a distância em centímetros pode ser obtida diretamente do tempo em microssegundos:

Distância (cm) = Tempo (µs) / 58

💡 Dica: a velocidade do som varia com a temperatura (≈ 331,4 + 0,6 × T°C m/s). Em aplicações de precisão em ambientes com temperatura controlada, considere compensar esse fator no cálculo.

Especificações técnicas

Principais especificações

ParâmetroValor
Tensão de alimentação (VCC)5V DC
Corrente de operação2 mA
Frequência de operação40 kHz
Alcance de medição2 cm a 4 m
Precisão3 mm
Ângulo de efeito15°
Sinal de disparo (Trigger)Pulso TTL de 5V (mín. 10 µs)
Sinal de resposta (ECHO)Nível alto proporcional ao tempo (pulso TTL de 5V)
Dimensões típicas do módulo45 × 20 × 15 mm

Faixa de medição e precisão

CondiçãoValor
Distância mínima2 cm
Distância máxima4 m
Precisão típica±3 mm
Ângulo de abertura do feixe15°

⚠️ ATENÇÃO: a precisão declarada vale para superfícies planas e rígidas posicionadas perpendicularmente ao sensor. Objetos macios, inclinados ou com cantos arredondados reduzem a força do eco e aumentam o erro de medição.

Tempo de resposta

SituaçãoTempo típico
Período mínimo entre medições60 ms (recomendado)
Máximo do pulso de eco (4 m)23 ms

💡 Dica: o datasheet recomenda aguardar pelo menos 60 ms entre cada disparo para evitar que ecos “fantasma” de medições anteriores interfiram na leitura atual.

Pinagem e descrição dos terminais

Pinos do módulo HC-SR04

PinoNomeFunção
1VCCAlimentação 5V DC
2TriggerEntrada — recebe o pulso de disparo (nível alto ≥ 10 µs)
3ECHOSaída — fica em nível alto durante o retorno do eco
4GNDTerra (0V)

⚠️ OBRIGATÓRIO: o pino ECHO envia 5V na volta do eco. Em microcontroladores de 3,3V (ESP32, ESP8266, Raspberry Pi) isso excede o limite das entradas — use um divisor de tensão (ex.: resistor de 1 kΩ em série + 2 kΩ para o GND) ou o pino do microcontrolador pode ser danificado.

ATENÇÃO: nunca inverta VCC e GND, nem aplique mais que 5V ao pino VCC — o circuito do módulo pode ser danificado permanentemente.

Por que o ECHO em 5V exige divisor de tensão

O pino ECHO é a saída de um circuito TTL alimentado a 5V: quando o eco retorna, ele puxa o pino para nível alto de 5V pelo tempo proporcional à distância. Entradas digitais de 3,3V suportam no máximo ~3,6V — aplicar 5V constantemente pode degradar ou queimar o pino do microcontrolador.

Regra prática:

  • Arduino (5V): ligar o ECHO direto ao pino digital — sem divisor.
  • ESP32/ESP8266/Raspberry Pi (3,3V): sempre usar divisor de tensão de 2 resistores (ex.: 1 kΩ em série no sinal + 2 kΩ entre o pino e o GND), resultando em ~3,3V.
  • Uma alternativa simples é usar o HY-SRF05, que já traz saída com controle de tensão.

Instalação e conexão

Requisitos de hardware

  • Microcontrolador: Arduino Uno/Mega/Nano, ESP32, ESP8266 ou similar (ou Raspberry Pi)
  • Módulo HC-SR04 (RB0002)
  • Protoboard e jumpers (4 vias ou cabos fêmea-fêmea)
  • Fonte de alimentação: 5V DC (o módulo precisa de 5V no VCC)

Passo a passo da instalação

  1. Desligue o circuito antes de qualquer conexão.
  2. Conecte o VCC ao pino de 5V do microcontrolador (ou à trilha de 5V na protoboard).
  3. Conecte o GND ao terra (GND).
  4. Conecte o Trigger ao pino digital escolhido (ex.: D9 no Arduino, GPIO5 no ESP32).
  5. Conecte o ECHO ao pino digital escolhido — no Arduino direto; em 3,3V, sempre com o divisor de tensão.
  6. Energize o circuito e carregue um código de exemplo para confirmar a leitura.
  7. Se a leitura não responder, verifique a alimentação de 5V e se o Trigger está recebendo o pulso de 10 µs.

Conexão com microcontroladores

HC-SR04Arduino UnoESP32ESP8266
VCC5V5V (pino VIN/5V)VU (5V)
GNDGNDGNDGND
TriggerD9GPIO5GPIO2 (D4)
ECHOD10GPIO18 (com divisor)GPIO4 (D2, com divisor)

💡 ESP8266: evite usar o GPIO0 e o GPIO15 para o ECHO — eles têm funções de boot. Prefira GPIO2 e GPIO4. Lembre-se de que o ESP8266 trabalha em 3,3V, então o divisor de tensão no ECHO é obrigatório.

Alimentação do módulo

  • VCC em 5V (recomendado): o módulo é projetado para operar com 5V no VCC — é a configuração padrão do datasheet e garante a potência correta do emissor e o nível TTL do ECHO.
  • VCC em 3,3V (não recomendado): alguns módulos funcionam com 3,3V no VCC, mas o alcance pode cair e o ECHO passa a emitir ~3,3V. Teste antes de usar em projeto crítico.

Conclusão prática: prefira sempre alimentar o HC-SR04 com 5V. A tensão do ECHO é resolvida com o divisor de tensão — não é preciso reduzir a alimentação do módulo.

Configuração de software

Código básico de leitura

#define PINO_TRIGGER 9                // pino digital do Trigger (disparo)
#define PINO_ECHO 10                  // pino digital do ECHO (eco)

void setup() {
  Serial.begin(9600);                 // inicia comunicação serial
  pinMode(PINO_TRIGGER, OUTPUT);      // Trigger é saída (envia o pulso)
  pinMode(PINO_ECHO, INPUT);          // ECHO é entrada (recebe o eco)
}

void loop() {
  digitalWrite(PINO_TRIGGER, LOW);    // garante Trigger em nível baixo
  delayMicroseconds(2);               // espera 2 µs para estabilizar
  digitalWrite(PINO_TRIGGER, HIGH);   // coloca Trigger em nível alto
  delayMicroseconds(10);              // mantém alto por 10 µs (pulso de disparo)
  digitalWrite(PINO_TRIGGER, LOW);    // finaliza o pulso de disparo

  long duracao = pulseIn(PINO_ECHO, HIGH);  // mede o tempo em que o ECHO fica alto
  float distancia = duracao / 58.0;   // converte o tempo em centímetros

  Serial.print("Distancia: ");        // imprime texto no Monitor Serial
  Serial.print(distancia);            // imprime o valor medido
  Serial.println(" cm");              // imprime a unidade e pula linha

  delay(100);                         // aguarda 100 ms antes da próxima medição
}

💡 O valor duracao é o tempo (em microssegundos) que o ECHO ficou em nível alto. A divisão por 58 converte diretamente para centímetros, considerando a velocidade do som.

Usando a biblioteca NewPing (recomendada)

A biblioteca NewPing simplifica a leitura, gerencia os tempos de espera e evita travamentos com pulseIn:

#include <NewPing.h>                  // biblioteca NewPing

#define PINO_TRIGGER 9                // pino digital do Trigger
#define PINO_ECHO 10                  // pino digital do ECHO
#define DISTANCIA_MAXIMA 400          // distância máxima em centímetros

NewPing sonar(PINO_TRIGGER, PINO_ECHO, DISTANCIA_MAXIMA);  // cria objeto do sensor

void setup() {
  Serial.begin(9600);                 // inicia comunicação serial
}

void loop() {
  unsigned int cm = sonar.ping_cm();  // dispara o sensor e retorna a distância em cm
  Serial.print("Distancia: ");        // imprime texto no Monitor Serial
  Serial.print(cm);                   // imprime o valor medido
  Serial.println(" cm");              // imprime a unidade e pula linha
  delay(100);                         // aguarda 100 ms antes da próxima medição
}

Lendo com correção do ECHO (3,3V)

Em ESP32/ESP8266, além do divisor de tensão no ECHO, o código é o mesmo — apenas os pinos mudam:

#define PINO_TRIGGER 5                // pino GPIO5 como Trigger
#define PINO_ECHO 18                  // pino GPIO18 como ECHO (com divisor)

void setup() {
  Serial.begin(115200);               // inicia comunicação serial do ESP32
  pinMode(PINO_TRIGGER, OUTPUT);      // Trigger é saída
  pinMode(PINO_ECHO, INPUT);          // ECHO é entrada
}

void loop() {
  digitalWrite(PINO_TRIGGER, LOW);    // garante Trigger em nível baixo
  delayMicroseconds(2);               // espera 2 µs para estabilizar
  digitalWrite(PINO_TRIGGER, HIGH);   // coloca Trigger em nível alto
  delayMicroseconds(10);              // mantém alto por 10 µs (pulso de disparo)
  digitalWrite(PINO_TRIGGER, LOW);    // finaliza o pulso

  long duracao = pulseIn(PINO_ECHO, HIGH);  // mede o tempo do eco em µs
  float distancia = duracao / 58.0;   // converte o tempo em centímetros

  Serial.print("Distancia: ");        // imprime texto no Monitor Serial
  Serial.print(distancia);            // imprime o valor medido
  Serial.println(" cm");              // imprime a unidade e pula linha

  delay(100);                         // aguarda 100 ms antes da próxima medição
}

💡 Com o divisor de tensão, o pino ECHO recebe ~3,3V e a leitura funciona normalmente. Sem ele, o pino do ESP32 pode ser danificado.

Integração com Raspberry Pi

Na Raspberry Pi, o controle do Trigger é igual ao Arduino, mas o ECHO em 5V exige o divisor de tensão antes do GPIO. Em Python:

import RPi.GPIO as GPIO   # biblioteca de acesso aos pinos GPIO
import time               # biblioteca de tempo

PINO_TRIGGER = 23         # pino GPIO23 como Trigger
PINO_ECHO = 24            # pino GPIO24 como ECHO (com divisor)

GPIO.setmode(GPIO.BCM)    # define a numeração dos pinos (BCM)
GPIO.setup(PINO_TRIGGER, GPIO.OUT)  # Trigger é saída
GPIO.setup(PINO_ECHO, GPIO.IN)      # ECHO é entrada

while True:
    GPIO.output(PINO_TRIGGER, False)  # garante Trigger em nível baixo
    time.sleep(0.01)                  # espera 10 ms para estabilizar

    GPIO.output(PINO_TRIGGER, True)   # coloca Trigger em nível alto
    time.sleep(0.00001)               # mantém alto por 10 µs (pulso de disparo)
    GPIO.output(PINO_TRIGGER, False)  # finaliza o pulso

    while GPIO.input(PINO_ECHO) == 0:  # aguarda o eco começar
        inicio = time.time()           # registra o tempo inicial
    while GPIO.input(PINO_ECHO) == 1:  # aguarda o eco terminar
        fim = time.time()              # registra o tempo final

    duracao = fim - inicio             # calcula a duração do eco em segundos
    distancia = (duracao * 34300) / 2  # converte para centímetros (velocidade do som)

    print(f"Distancia: {distancia:.1f} cm")  # imprime a distância com 1 casa decimal
    time.sleep(1)                     # aguarda 1 segundo antes da próxima medição

⚠️ ATENÇÃO: sem o divisor de tensão, o GPIO da Raspberry Pi (3,3V) recebe 5V do ECHO e pode ser queimado. Use sempre o divisor de 1 kΩ + 2 kΩ antes de conectar ao GPIO.

Exemplos de aplicação

  • Sensor de ré com buzzer: aumente a frequência do alarme conforme o obstáculo se aproxima;
  • Robô desvia-obstáculos: acione motores para desviar quando a distância for menor que um limite;
  • Medidor de nível de tanque: monte o sensor acima da superfície do líquido e converta a distância em volume;
  • Monitoramento IoT — ESP32 + MQTT: publique a distância em um broker MQTT e consuma com dashboards (Node-RED, Grafana, Home Assistant).

Sensor de ré com buzzer (Arduino)

#define PINO_TRIGGER 9                // pino digital do Trigger
#define PINO_ECHO 10                  // pino digital do ECHO
#define PINO_BUZZER 8                 // pino do buzzer
#define DISTANCIA_LIMITE 100          // distância de alerta em centímetros

void setup() {
  pinMode(PINO_TRIGGER, OUTPUT);      // Trigger é saída
  pinMode(PINO_ECHO, INPUT);          // ECHO é entrada
  pinMode(PINO_BUZZER, OUTPUT);       // buzzer é saída
}

void loop() {
  digitalWrite(PINO_TRIGGER, LOW);    // garante Trigger em nível baixo
  delayMicroseconds(2);               // espera 2 µs para estabilizar
  digitalWrite(PINO_TRIGGER, HIGH);   // coloca Trigger em nível alto
  delayMicroseconds(10);              // mantém alto por 10 µs (pulso de disparo)
  digitalWrite(PINO_TRIGGER, LOW);    // finaliza o pulso

  long duracao = pulseIn(PINO_ECHO, HIGH);  // mede o tempo do eco em µs
  float distancia = duracao / 58.0;   // converte o tempo em centímetros

  if (distancia < DISTANCIA_LIMITE) {  // se o obstáculo estiver perto
    digitalWrite(PINO_BUZZER, HIGH);   // liga o buzzer
  } else {                             // se estiver longe
    digitalWrite(PINO_BUZZER, LOW);    // desliga o buzzer
  }

  delay(100);                         // aguarda 100 ms antes da próxima medição
}

💡 Para um efeito de “bip proporcional à distância”, troque o digitalWrite do buzzer por tone() com intervalo inversamente proporcional à distância — quanto mais perto, mais rápido o bip.

Monitoramento de nível com ESP32 + MQTT

Monte o sensor no topo de um reservatório apontando para a superfície do líquido. A distância medida é usada para estimar o nível restante:

#include <WiFi.h>                  // biblioteca de conexão WiFi do ESP32
#include <PubSubClient.h>          // biblioteca do protocolo MQTT

#define PINO_TRIGGER 5             // pino GPIO5 como Trigger
#define PINO_ECHO 18               // pino GPIO18 como ECHO (com divisor)
#define ALTURA_TANQUE 100          // altura do tanque em centímetros

const char* ssid  = "SEU_WIFI";    // nome da rede WiFi
const char* senha = "SUA_SENHA";   // senha da rede WiFi
const char* broker = "IP_DO_SEU_BROKER";  // endereço do broker MQTT

WiFiClient wifiCliente;            // cliente TCP para a conexão WiFi
PubSubClient mqtt(wifiCliente);    // cliente MQTT sobre o WiFi

float medirDistancia() {           // função que dispara o sensor e mede a distância
  digitalWrite(PINO_TRIGGER, LOW); // garante Trigger em nível baixo
  delayMicroseconds(2);            // espera 2 µs para estabilizar
  digitalWrite(PINO_TRIGGER, HIGH); // coloca Trigger em nível alto
  delayMicroseconds(10);           // mantém alto por 10 µs (pulso de disparo)
  digitalWrite(PINO_TRIGGER, LOW); // finaliza o pulso
  long duracao = pulseIn(PINO_ECHO, HIGH);  // mede o tempo do eco em µs
  return duracao / 58.0;           // retorna a distância em centímetros
}

void setup() {
  Serial.begin(115200);            // inicia comunicação serial
  pinMode(PINO_TRIGGER, OUTPUT);   // Trigger é saída
  pinMode(PINO_ECHO, INPUT);       // ECHO é entrada
  WiFi.begin(ssid, senha);         // inicia a conexão WiFi
  while (WiFi.status() != WL_CONNECTED) {  // aguarda conectar à rede
    delay(500);                    // espera meio segundo
    Serial.print(".");             // imprime ponto de progresso
  }
  Serial.println("WiFi conectado"); // confirma a conexão
  mqtt.setServer(broker, 1883);    // define o broker e a porta padrão
}

void loop() {
  if (!mqtt.connected()) mqtt.connect("esp32-hcsr04-01");  // reconecta se cair
  mqtt.loop();                     // mantém o cliente MQTT ativo

  float distancia = medirDistancia();  // obtém a distância até a superfície
  float nivel = ALTURA_TANQUE - distancia;  // calcula o nível do líquido

  mqtt.publish("robobuilders/hcsr04/distancia", String(distancia).c_str());  // publica a distância
  mqtt.publish("robobuilders/hcsr04/nivel", String(nivel).c_str());  // publica o nível

  delay(10000);  // 1 leitura a cada 10 segundos
}

💡 Na RoboBuilders você encontra módulos HC-SR04 e placas ESP32 prontas para projetos de monitoramento remoto. Para dashboards, combine o broker MQTT com Node-RED ou Home Assistant.

Conclusão

Este manual abordou de forma completa o módulo sensor de distância ultrassônico HC-SR04, desde os conceitos básicos até aplicações avançadas:

  • O que é e como funciona: medição por tempo de voo do som, emissão em 40 kHz, cálculo da distância pela fórmula (Tempo × Velocidade do Som) / 2, com conversão prática Tempo (µs) / 58.
  • Pinagem e instalação: 4 pinos (VCC, Trigger, ECHO, GND), esquemas de ligação para Arduino, ESP32 e ESP8266 e o divisor de tensão obrigatório no ECHO para sistemas de 3,3V.
  • Configuração de software: leitura com pulseIn, biblioteca NewPing, código para ESP32/ESP8266 e integração com Raspberry Pi em Python.
  • Exemplos práticos: sensor de ré com buzzer, desvio de obstáculos, medidor de nível de tanque e monitoramento IoT com ESP32 + MQTT.

Com alimentação de 5V, superfície de reflexão adequada e o divisor de tensão correto no ECHO, o HC-SR04 entrega medições confiáveis de 2 cm a 4 m — de um sensor de ré simples a sistemas de telemetria de nível conectados à internet.

Solução de problemas

Olá! Sou o assistente técnico da RoboBuilders. Descreva seu problema com o Sensor de Distância Ultrassônico HC-SR04: Manual Técnico Completo e eu ajudarei a encontrar a solução.

O assistente usa IA e pode errar. Confirme informações críticas no datasheet oficial do fabricante.