Skip to Content

Cómo usar un sensor de distancia ultrasónico HC-SR04 con Arduino

Cómo usar un sensor de distancia ultrasónico HC-SR04 con Arduino

El HC-SR04 es un sensor de distancia ultrasónico económico y fácil de usar, con un rango de 2 cm a 400 cm. Se utiliza comúnmente en robots que evitan obstáculos y en proyectos de automatización. En este tutorial, aprenderás cómo funciona el sensor y cómo usarlo con Arduino.

He incluido 5 ejemplos con un diagrama de conexiones y código para que puedas empezar a experimentar con tu sensor. Primero veremos un ejemplo que no utiliza una librería de Arduino. Luego, te mostraré cómo usar la librería NewPing para crear un código más compacto.

Materiales

Componentes de hardware

hc-sr04HC-SR04 sensor× 1Amazon
Arduino Uno Rev 3Arduino Uno Rev3× 1Amazon
Breadboard× 1Amazon
Jumper wires~ 10Amazon
USB cable type A/B× 1Amazon
lcd20×4 character I2C LCD (opcional)× 1Amazon
DHT11 sensor (opcional)× 1Amazon

Software

Arduino IDEArduino IDE

Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.

¿Cómo funciona un sensor de distancia ultrasónico?

Los sensores ultrasónicos funcionan emitiendo ondas sonoras con una frecuencia demasiado alta para que el oído humano las perciba. Estas ondas viajan por el aire a la velocidad del sonido, aproximadamente 343 m/s. Si hay un objeto frente al sensor, las ondas sonoras se reflejan y el receptor del sensor ultrasónico las detecta. Midiendo el tiempo que pasa entre el envío y la recepción de las ondas, se puede calcular la distancia entre el sensor y el objeto.

How Ultrasonic Sensors Work Maxbotix
Principio de funcionamiento de los sensores de distancia ultrasónicos. Fuente: https://www.maxbotix.com/

A 20°C, la velocidad del sonido es aproximadamente 343 m/s o 0.034 cm/µs. Supongamos que el tiempo entre el envío y la recepción de las ondas es de 2000 microsegundos. Si multiplicas la velocidad del sonido por el tiempo que viajaron las ondas, obtienes la distancia total recorrida por las ondas.

Distancia = Velocidad × Tiempo

Pero ese no es el resultado que buscamos. La distancia entre el sensor y el objeto es en realidad solo la mitad de esa distancia porque las ondas viajaron del sensor al objeto y luego de regreso al sensor. Por eso, debes dividir el resultado entre dos.

Distancia (cm) = Velocidad del sonido (cm/µs) × Tiempo (µs) / 2

Y para el ejemplo, esto se convierte en:

Distancia (cm) = 0.0343 (cm/µs) × 2000 (µs) / 2 = 34.3 cm

Dependencia de la velocidad del sonido con la temperatura

La velocidad del sonido depende en gran medida de la temperatura y en menor medida de la humedad del aire. Wikipedia indica que la velocidad del sonido aumenta aproximadamente 0.6 m/s por cada grado Celsius. En la mayoría de los casos, a 20°C puedes usar 343 m/s, pero si quieres obtener lecturas más precisas, puedes calcular la velocidad del sonido con la siguiente fórmula:

V (m/s) = 331.3 + (0.606 × T)

V = Velocidad del sonido (m/s)
T = Temperatura del aire (°C)

Esta fórmula no incluye la humedad, ya que su efecto en la velocidad del sonido es muy pequeño.

A continuación puedes encontrar un tutorial sobre cómo usar un DHT11 sensor de temperatura y humedad para calibrar la velocidad del sonido y obtener una lectura de distancia más precisa con el HC-SR04.

Cómo funciona el HC-SR04

En la parte frontal del sensor HC-SR04, puedes encontrar dos cilindros plateados (transductores ultrasónicos), uno es el transmisor de las ondas sonoras y el otro es el receptor. Para que el sensor genere un pulso sónico, debes poner el pin Trig en alto durante al menos 10 µs. El sensor entonces crea un pulso de 8 ciclos de ultrasonido a 40 kHz.

Este pulso sónico viaja a la velocidad del sonido, rebota y es recibido por el receptor del sensor. El pin Echo entonces emite el tiempo que las ondas sonoras viajaron en microsegundos.

Puedes usar la pulseIn() función en el código Arduino para leer la duración del pulso del pin Echo. Después, puedes usar la fórmula mencionada arriba para calcular la distancia entre el sensor y el objeto.

Especificaciones del HC-SR04

Voltaje de operación5 V
Corriente de operación15 mA
Frecuencia40 kHz
Rango de medición2 – 400 cm
Resolución3 mm
Ángulo de medición15 grados
Señal de entrada TriggerPulso alto de 10 µs
PrecioCheck price

Para más información puedes consultar la hoja de datos a continuación:

Conexiones – Cómo conectar el HC-SR04 al Arduino UNO

El diagrama de conexiones a continuación muestra cómo conectar el sensor HC-SR04 al Arduino.

HC-SR04-ultrasonic-distance-sensor-with-Arduino-wiring-diagram-schematic-tutorial
Diagrama de conexiones del HC-SR04 con Arduino

Los ejemplos de código usan los pines digitales 2 y 3 para el pin trigger y echo respectivamente, pero por supuesto puedes cambiarlo a cualquier pin digital que desees.

Conexiones del HC-SR04

HC-SR04Arduino
VCC5 V
TrigPin 2
EchoPin 3
GNDGND

Código de ejemplo para HC-SR04 con Arduino

Ahora que has conectado el sensor, es momento de conectar el Arduino al ordenador y subir algo de código. Puedes subir el siguiente código de ejemplo a tu Arduino usando el IDE de Arduino. Luego te explicaré cómo funciona el código.

/* Example code for HC-SR04 ultrasonic distance sensor with Arduino. 
   No library required. More info: https://www.makerguides.com */

// Define Trig and Echo pin:
#define trigPin 2
#define echoPin 3

// Define variables:
long duration;
int distance;

void setup() {
  // Define inputs and outputs:
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  //Begin Serial communication at a baudrate of 9600:
  Serial.begin(9600);
}

void loop() {
  // Clear the trigPin by setting it LOW:
  digitalWrite(trigPin, LOW);
  delayMicroseconds(5);

  // Trigger the sensor by setting the trigPin high for 10 microseconds:
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Read the echoPin, pulseIn() returns the duration (length of the pulse) in microseconds:
  duration = pulseIn(echoPin, HIGH);
  // Calculate the distance:
  distance = duration * 0.034 / 2;

  // Print the distance on the Serial Monitor (Ctrl+Shift+M):
  Serial.print("Distance = ");
  Serial.print(distance);
  Serial.println(" cm");

  delay(50);
}

Cómo funciona el código

Primero, se definen el pin trigger y el pin echo. Los llamo trigPin y EchoPin. El pin trigger está conectado al pin digital 2 y el pin echo al pin digital 3 del Arduino.

La instrucción #define se usa para dar un nombre a un valor constante. El compilador reemplazará cualquier referencia a esta constante con el valor definido cuando se compile el programa. Así que donde menciones trigPin, el compilador lo reemplazará por el valor 2 al compilar el programa.

// Define Trig and Echo pin:
#define trigPin 2
#define echoPin 3

Luego definí dos variables:  duration y distance. Duration almacena el tiempo entre el envío y la recepción de las ondas sonoras. La variable distance se usa para guardar la distancia calculada.

// Define variables:
long duration;
int distance;

En el setup(), comienzas configurando trigPin como salida y echoPin como entrada. Luego inicializas la comunicación serial a una velocidad de 9600 baudios. Más adelante mostrarás la distancia medida en el monitor serial, que se puede abrir con Ctrl+Shift+M o Herramientas > Monitor Serial. Asegúrate de que la velocidad también esté configurada a 9600 en el monitor serial.

void setup() {
  // Define inputs and outputs:
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  //Begin Serial communication at a baudrate of 9600:
  Serial.begin(9600);
}

En el loop(), activas el sensor poniendo trigPin en ALTO durante 10 µs. Nota que para obtener una señal limpia, primero limpias trigPin poniéndolo en BAJO durante 5 microsegundos.

void loop() {
  // Clear the trigPin by setting it LOW:
  digitalWrite(trigPin, LOW);
  delayMicroseconds(5);

  // Trigger the sensor by setting the trigPin high for 10 microseconds:
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

Luego, necesitas leer la duración del pulso enviado por echoPin. Uso la función pulseIn() para esto. Esta función espera a que el pin pase de BAJO a ALTO, comienza a medir el tiempo, luego espera a que el pin vuelva a BAJO y detiene la medición.

Después, puedes calcular la distancia usando la fórmula mencionada en la introducción de este tutorial.

// Read the echoPin, pulseIn() returns the duration (length of the pulse) in microseconds:
duration = pulseIn(echoPin, HIGH);
// Calculate the distance:
distance = duration * 0.034 / 2;

Finalmente, la distancia calculada se imprime en el monitor serial.

// Print the distance on the Serial Monitor (Ctrl+Shift+M):
Serial.print("Distance = ");
Serial.print(distance);
Serial.println(" cm");

delay(50);

Código de ejemplo HC-SR04 con Arduino y librería NewPing

La librería NewPing escrita por Tim Eckel puede usarse con muchos sensores ultrasónicos. La última versión de esta librería puede descargarse aquí en bitbucket.org. Notarás que el código a continuación, que usa la librería NewPing, es mucho más corto que el código que usamos antes. Además, la librería NewPing incluye otras funciones útiles. Permite establecer una distancia máxima para leer, no se queda colgada un segundo completo cuando no recibe eco y tiene un filtro mediano incorporado.

Puedes instalar la librería yendo a Sketch > Include Library > Add .ZIP Library en el IDE de Arduino.

La librería incluye algunos ejemplos que puedes usar, pero tendrás que modificarlos para que coincidan con tu configuración de hardware. He incluido un ejemplo modificado a continuación que puede usarse con la misma conexión que antes.

/* HC-SR04 ultrasonic distance sensor with 
   NewPing library example code. 
   More info: www.www.makerguides.com */

// Include the library:
#include "NewPing.h"

// Define pins and max distance:
#define trigPin  2
#define echoPin  3
#define MAX_DISTANCE 350 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

NewPing sonar(trigPin, echoPin, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
float duration, distance;

void setup() {
  Serial.begin(9600); // Open serial monitor at 9600 baud to see ping results.
}

void loop() {
  delay(50); // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
  
  duration = sonar.ping();
  distance = (duration / 2) * 0.0343;
  
  Serial.print("Distance = ");
  Serial.print(distance); // Distance will be 0 when out of set max range.
  Serial.println(" cm");
}

También puedes usar distance = sonar.ping_cm() o distance = sonar.ping_in() que devuelve la distancia medida en centímetros o pulgadas enteras. Con esta función no necesitas medir la duración ni calcular la distancia.

Interfaz de sensores ultrasónicos en modo de 3 pines

La librería NewPing también facilita la interfaz con sensores ultrasónicos usando solo 1 pin I/O. Esto puede ser útil si tienes muy pocos pines I/O disponibles o si quieres usar un sensor ultrasónico de 3 pines como el Parallax Ping.

Para crear una configuración de 3 pines (GND, 5V y SIG) debes conectar tanto el pin trigger como el pin echo al mismo pin digital del Arduino. En el código, lo único que debes cambiar es la línea 6-7 y definir el mismo pin para trigPin y echoPin. Por ejemplo, el pin digital 2.

//Define Trig and Echo pin
#define trigPin 2
#define echoPin 2

Cómo usar el filtro digital ping_median()

Lo que más me gusta de la librería NewPing es que tiene un filtro mediano incorporado. Este filtro puede mejorar mucho la precisión de tus lecturas con el HC-SR04. La función ping_median() toma muchas mediciones de duración seguidas, descarta las lecturas fuera de rango y luego promedia las restantes. Por defecto toma 5 lecturas, pero puedes especificar cuántas debe tomar. Reemplaza la línea 19 con las líneas siguientes.

int iterations = 5;
duration = sonar.ping_median(iterations);

Código de ejemplo HC-SR04 con LCD I2C y Arduino

Para mostrar la distancia medida en un 20041602 LCD I2C, solo tienes que hacer las siguientes conexiones y subir el código a continuación. El sensor HC-SR04 se conecta igual que antes.

HC-SR04 with I2C LCD and Arduino UNO wiring
Diagrama de conexiones HC-SR04 con Arduino y LCD I2C.

Conexiones LCD I2C

LCD I2CArduino
GNDGND
VCC5 V
SDAA4
SCLA5

Si no usas un Arduino Uno, los pines SDA y SCL pueden estar en otra ubicación. Un Arduino UNO con el diseño R3 (pinout 1.0) también tiene los pines SDA (línea de datos) y SCL (línea de reloj) cerca del pin AREF. Consulta la tabla a continuación para más detalles.

PlacaSDASCL
Arduino UnoA4A5
Arduino NanoA4A5
Arduino Micro23
Arduino Mega 25602021
Arduino Leonardo23
Arduino Due2021
Ubicación de pines I2C para diferentes placas Arduino

El código usa la librería LiquidCrystal_I2C que puedes descargar en GitHub. ¡Asegúrate de tener instalada esta librería exacta! También incluye la librería Wire.h que permite comunicarte con dispositivos I2C. Esta librería debería venir preinstalada con el IDE de Arduino.

Si quieres aprender más sobre cómo controlar un LCD I2C con Arduino, puedes consultar nuestro tutorial sobre How to control a character I2C LCD with Arduino.

/* HC-SR04 ultrasonic distance sensor with 
   Arduino and I2C LCD example code.
   More info: https://www.makerguides.com
*/

#include "Wire.h"
#include "LiquidCrystal_I2C.h"

// Define Trig and Echo pin:
#define trigPin 2
#define echoPin 3

// Define SDA and SCL pin for LCD:
#define SDAPin A4 // Data pin
#define SCLPin A5 // Clock pin

// Connect to LCD via I2C, default address 0x27 (A0-A2 not jumpered):
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27,20,4); //Change to (0x27,16,2) for 1602 LCD 

// Define variables:
long duration;
int distance;

void setup() {
  // Define inputs and outputs:
  pinMode(trigPin, OUTPUT); 
  pinMode(echoPin, INPUT); 

  // Initiate the LCD:
  lcd.init();
  lcd.backlight();
}

void loop() {
  // Clear the trigPin by setting it LOW:
  digitalWrite(trigPin, LOW);
  delayMicroseconds(5);

  // Trigger the sensor by setting the trigPin high for 10 microseconds:
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Read the echoPin. This returns the duration (length of the pulse) in microseconds:
  duration = pulseIn(echoPin, HIGH);

  // Calculate the distance:
  distance = duration*0.034/2;

  // Display the distance on the LCD:
  lcd.setCursor(0,0); // Set the cursor to column 1, line 1 (counting starts at zero)
  lcd.print("Distance = "); // Prints string "Display = " on the LCD
  lcd.print(distance); // Prints the measured distance
  lcd.print(" cm  "); // Prints "cm" on the LCD, extra spaces are needed to clear previously displayed characters
  
  delay(50);
}

Ten en cuenta que usé un display LCD 20 x 4. Si tienes un LCD de otro tamaño (16 x 2 también es común) debes cambiar la línea 20 a LiquidCrystal_I2C lcd(0x27,16,2);. Si tu LCD no tiene la dirección I2C por defecto, 0x27, consulta el tutorial completo de I2C donde explico cómo descubrir cuál es la dirección.

Código de ejemplo HC-SR04 con sensor de temperatura DHT11 y Arduino

Como mencioné antes, la velocidad del sonido depende mucho de la temperatura del aire. Si quieres medir distancias largas (3-4 m) puede ser buena idea añadir un sensor DHT11 o DHT22 de temperatura y humedad a tu configuración. Esto te permitirá calibrar la velocidad del sonido en tiempo real y así aumentar la precisión de tus mediciones.

Agregar un sensor DHT11 es muy sencillo. El diagrama de conexiones a continuación muestra qué conexiones debes hacer. Ten en cuenta que uso un DHT11 con placa adaptadora, así que solo necesito conectar 3 pines. Asegúrate de revisar la etiqueta del sensor, el orden de los pines puede variar según el fabricante. El sensor HC-SR04 se conecta igual que antes.

HC-SR04 with DHT11 and Arduino UNO wiring
Diagrama de conexiones HC-SR04 con Arduino y DHT11.

Conexiones DHT11

DHT11Arduino
VCC (+)5 V
Señal (s)Pin 4
GND (-)GND

El código a continuación usa la librería Adafruit DHT Humidity & Temperature Sensor que puedes descargar en GitHub. Esta librería solo funciona si también tienes instalada la librería Adafruit_Sensor, que también está disponible en GitHub. También puedes descargar ambas librerías haciendo clic en los botones a continuación:

Puedes hacer clic en el botón en la esquina superior derecha del campo de código para copiar el código.

/* HC-SR04 ultrasonic distance sensor with 
   DHT11 and Arduino example code.
   More info: https://www.makerguides.com */

#include "Adafruit_Sensor.h" //https://github.com/adafruit/Adafruit_Sensor
#include "DHT.h" //https://github.com/adafruit/DHT-sensor-library

// Define Trig pin, Echo pin and DHTPin:
#define trigPin 2
#define echoPin 3
#define DHTPin 4

// Define DHT sensor type:
#define DHTType DHT11

// Define variables:
long duration;
int distance;
float speedofsound;

// Create a DHT sensor object:
DHT dht = DHT(DHTPin,DHTType);

void setup() {
  // Define inputs and outputs:
  pinMode(trigPin, OUTPUT); 
  pinMode(echoPin, INPUT); 

  dht.begin();

  // Begin Serial communication:
  Serial.begin(9600); // Starts the serial communication
}

void loop() {
  //  Clear the trigPin by setting it LOW:
  digitalWrite(trigPin, LOW);
  delayMicroseconds(5);

  // Trigger the sensor by setting the trigPin high for 10 microseconds:
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Read the echoPin. This returns the duration (length of the pulse) in microseconds:
  duration = pulseIn(echoPin, HIGH);

  // Read the temperature:
  float temperature = dht.readTemperature();

  // Calculate speed of sound in m/s:
  speedofsound = 331.3+(0.606*temperature);

  // Calculate the distance in cm:
  distance = duration*(speedofsound/10000)/2;

  // Print the distance and temperature on the Serial Monitor:
  Serial.print("Temperature = ");
  Serial.print(temperature);
  Serial.print(" Celsius");
  Serial.print(", Distance = ");
  Serial.print(distance);
  Serial.println("cm");
  delay(100);
}

Código de ejemplo HC-SR04 con DHT11 y LCD I2C

HC-SR04 with DHT11, I2C LCD and Arduino UNO wiring
Diagrama de conexiones HC-SR04 con Arduino, DHT11 y LCD I2C.

El código a continuación puede usarse para combinar los 3 ejemplos anteriores. Muestra la temperatura, la velocidad del sonido y la distancia medida en el LCD.

/* HC-SR04 ultrasonic distance sensor with 
   DHT11, I2C LCD and Arduino example code.
   More info: https://www.makerguides.com */

#include "Adafruit_Sensor.h" // https://github.com/adafruit/Adafruit_Sensor
#include "DHT.h" // https://github.com/adafruit/DHT-sensor-library
#include "Wire.h" // Library for I2C communication
#include "LiquidCrystal_I2C.h" // Library for LCD

// Define Trig pin, Echo pin and DHTPin:
#define trigPin 2
#define echoPin 3
#define DHTPin 4

// Define SDA and SCL pin from LCD:
#define SDAPin A4 // Data pin
#define SCLPin A5 // Clock pin

// Connect to LCD via i2c, default address 0x27 (A0-A2 not jumpered):
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27,20,4);

// Define DHT sensor type:
#define DHTType DHT11

// Define variables:
long duration;
int distance;
float speedofsound;

// Create a DHT sensor object:
DHT dht = DHT(DHTPin,DHTType);

void setup() {
  // Define inputs and outputs:
  pinMode(trigPin, OUTPUT); 
  pinMode(echoPin, INPUT); 

  dht.begin();

  // Initiate the LCD:
  lcd.init();
  lcd.backlight();

  // Begin Serial communication at a baudrate of 9600:
  Serial.begin(9600);
}

void loop() {
  // Clear the trigPin by setting it LOW:
  digitalWrite(trigPin, LOW);
  delayMicroseconds(5);

  // Trigger the sensor by setting the trigPin high for 10 microseconds:
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Read the echoPin. This returns the duration (length of the pulse) in microseconds:
  duration = pulseIn(echoPin, HIGH);

  // Read the temperature:
  int temperature = dht.readTemperature();

  // Calculate speed of sound in m/s:
  speedofsound = 331.3+(0.606*temperature);

  // Calculate the distance in cm:
  distance = duration*(speedofsound/10000)/2;

  // Print the distance and temperature on the Serial Monitor:
  lcd.setCursor(0,0);
  lcd.print("Temperature: ");
  lcd.print(temperature);
  lcd.print(" " "\xDF" "C");
  lcd.setCursor(0,1);
  lcd.print("Speed: ");
  lcd.print(speedofsound);
  lcd.print(" m/s ");
  lcd.setCursor(0,2);
  lcd.print("Distance: ");
  lcd.print(distance);
  lcd.print(" cm  ");
  delay(100);
}

Dimensiones del HC-SR04

A continuación puedes encontrar las dimensiones del sensor ultrasónico HC-SR04. He notado que hay pequeñas diferencias entre fabricantes, así que recomiendo verificar con tu propio sensor.

HC-SR04 Dimensions
Dimensiones del HC-SR04

CAD del HC-SR04

He creado dibujos CAD básicos del sensor ultrasónico HC-SR04 que puedes descargar a continuación.

Conclusión

En este artículo, te he mostrado cómo funciona el sensor de distancia ultrasónico HC-SR04 y cómo usarlo con Arduino.

Proyecto personal: Hace un tiempo construí una instalación interactiva en una pared con algunos amigos. Usamos alrededor de 30 sensores ultrasónicos para detectar personas caminando frente a la pared. La pared incluía luces y efectos de sonido que cambiaban según la distancia a la que estaban las personas.

HC-SR04 Example AMS Prototypes
Foto: Guus Schoonewille

Los sensores ultrasónicos baratos son geniales, pero en algunos proyectos puede que necesites un sensor impermeable como el JSN-SR04T o un sensor IR que no se vea afectado por cambios de temperatura. En ese caso, los artículos a continuación pueden ser útiles:

Si tienes alguna pregunta, sugerencia o crees que falta algo en este tutorial, por favor deja un comentario abajo.