Sensor de ultrasonidos HC-SR04

El sensor de ultrasonidos se enmarca dentro de los sensores para medir distancias o superar obstáculos, entre otras posibles funciones.


Un sensor de ultra sonidos es un dispositivo para medir distancias. Su funcionamiento se base en el envío de un pulso de alta frecuencia, no audible por el ser humano. Este pulso rebota en los objetos cercanos y es reflejado hacia el sensor, que dispone de un micrófono adecuado para esa frecuencia

Los sensores de ultrasonidos son sensores baratos, y sencillos de usar. Este sensor en concreto tiene un rango de distancias sensible entre 1,7 cm y 4,5 m con una precisión de 3mm.

Los sensores de ultrasonidos son sensores de baja precisión. La orientación de la superficie a medir puede provocar que la onda se refleje, falseando la medición. Además, no resultan adecuados en entornos con gran número de objetos, dado que el sonido rebota en las superficies generando ecos y falsas mediciones. Tampoco son apropiados para el funcionamiento en el exterior y al aire libre. 

Pese a esta baja precisión, que impide conocer con precisión la distancia a un objeto, los sensores de ultrasonidos son ampliamente empleados. En robótica es habitual montar uno o varios de estos sensores, por ejemplo, para detección de obstáculos, determinar la posición del robot, crear mapas de entorno, o resolver laberinto.

Características
  • Dimensiones del circuito: 43 x 20 x 17 mm
  • Tensión de alimentación: 5 Vcc
  • Frecuencia de trabajo: 40 KHz
  • Rango máximo: 4.5 m
  • Rango mínimo: 1.7 cm
  • Duración mínima del pulso de disparo (nivel TTL): 10 μS.
  • Duración del pulso eco de salida (nivel TTL): 100-25000 μS.
  • Tiempo mínimo de espera entre una medida y el inicio de otra 20 mS.
¿Qué recibimos en el sensor?

El tiempo que transcurre entre el envío y la recepción de un pulso sonoro.

¿Cómo vamos a traducir dicho tiempo en distancia?

Aprovechando que la velocidad de dicho ultrasonido en el aire es de valor 340 m/s, o 0,034 cm/microseg (ya que trabajaremos con centímetros y microsegundos). Para calcular la distancia, recordaremos que v=d/t (definición de velocidad: distancia recorrida en un determinado tiempo).

De la fórmula anterior despejamos d, obteniendo d=v·t, siendo v la constante anteriormente citada y t el valor devuelto por el sensor a la placa Arduino.


También habrá que dividir el resultado entre 2 dado que el tiempo recibido es el tiempo de ida y vuelta.


Pines de conexión
  • Vcc.
  • Trig (Disparo ultrasonido).
  • Echo (Recepción de ultrasonido)
  • GND
 Montaje en una protoboard




Programa

Para activar el sensor necesitamos generar un pulso eléctrico en el pin Trigger (disparador) de al menos 10us. Previamente, pondremos el pin a Low durante 4us para asegurar un disparo limpio. 

Posteriormente usamos la función “pulseIn” para obtener el tiempo requerido por el pulso para volver al sensor. Finalmente, convertimos el tiempo en distancia mediante la ecuación correspondiente. 

Observar que intentamos emplear siempre aritmética de enteros, evitando usar números en coma flotante. Esto es debido a que las operaciones en coma flotante ralentizan mucho el procesador, y suponen cargar un gran número de librerías en memoria.

Empezamos a programar nuestro sketch, explicaremos paso a paso el código para sea más comprensible:

Primero configuramos los pines y la comunicación serial a 9600 baudios

const int EchoPin = 5;
const int TriggerPin =6;
long distancia;
long tiempo;

void setup(){

Serial.begin(9600);
pinMode(TriggerPin, OUTPUT); /*activación del pin 9 como salida: para el pulso ultrasónico*/
pinMode(EchoPin, INPUT); /*activación del pin 8 como entrada: tiempo del rebote del ultrasonido*/
}

Ahora en el bucle void loop() empezamos enviando un pulso de 5 us al Trigger del sensor para estabilizar el sensor:


digitalWrite(TriggerPin,LOW); /* Por cuestión de estabilización del sensor*/
delayMicroseconds(5);


A continuación enviaremos un pulso de 10 us al Trigger del sensor para al Trigger del sensor:


delayMicroseconds(10);
digitalWrite(TriggerPin, LOW);

Seguidamente recibimos el pulso de respuesta del sensor por el pin Echo, para medir el pulso usamos la función pulseIn(pin, value)

tiempo=pulseIn(EchoPin, HIGH); /* Función para medir la longitud del pulso entrante. Mide el tiempo que transcurrido entre el envío del pulso ultrasónico y cuando el sensor recibe el rebote, es decir: desde que el pin 12 empieza a recibir el rebote, HIGH, hasta que deja de hacerlo, LOW, la longitud del pulso entrante*/

La variable t, almacena el tiempo que tarda en llegar el eco del ultrasonido, el siguiente paso  es calcular la distancia entre el sensor de ultrasonidos y el objeto.


 Partimos de la siguiente formula:
Donde  Velocidad es la velocidad del sonido 340m/s, pero usaremos las unidades en cm/us pues trabajaremos en centímetros y microsegundos, tiempo es el tiempo que demora en llegar el ultrasonido al objeto y regresar al sensor, y la distancia recorrida es dos veces la distancia hacia el objeto, reemplazando en la formula tenemos:
Finalmente enviamos al monitor serie el valor de la distancia y terminamos estableciendo una pausa de 100ms, que es superior a los 60ms  recomendado por los datos técnicos del sensor.




const int EchoPin = 5;
const int TriggerPin =6;
long distancia;
long tiempo;

void setup(){

Serial.begin(9600);
pinMode(TriggerPin, OUTPUT); /*activación del pin 9 como salida: para el pulso ultrasónico*/
pinMode(EchoPin, INPUT); /*activación del pin 8 como entrada: tiempo del rebote del ultrasonido*/
}

void loop(){

digitalWrite(TriggerPin,LOW); /* Por cuestión de estabilización del sensor*/
delayMicroseconds(5);
digitalWrite(TriggerPin, HIGH); /* envío del pulso ultrasónico*/
delayMicroseconds(10);
digitalWrite(TriggerPin, LOW);

tiempo=pulseIn(EchoPin, HIGH); /* Función para medir la longitud del pulso entrante. Mide el tiempo que transcurrido entre el envío del pulso ultrasónico y cuando el sensor recibe el rebote, es decir: desde que el pin 12 empieza a recibir el rebote, HIGH, hasta que deja de hacerlo, LOW, la longitud del pulso entrante*/
distancia= tiempo/59; /*fórmula para calcular la distancia obteniendo un valor entero*/
/*Monitorización en centímetros por el monitor serial*/
Serial.println("Distancia ");
Serial.println(distancia);
Serial.println(" cm");
delay(100);
}

Para resumir el código y no tener que repetir tantas instrucciones cada vez que queramos realizar una medida vamos a escribir el sketch utilizando una función:

Vamos a crear una función medirDistancia(), la cual nos devolverá la distancia.

Como ejemplo práctico hemos diseñado un circuito que incorpora un sensor y su finalidad será la de controlar el funcionamiento de un motor, de tal manera que cuando se encuentre un objeto en una distancia menor a 20 cm del sensor, el motor dejará de girar, si la distancia es mayor de 20 cm el motor girará.

Circuito eléctrico


Sketch

#define E1 13 // Enable Pin para el motor 1
#define I1 12 // Control pin 1 para el motor 1
#define I2 11 // Control pin 2 para el motor 1

const int EchoPin = 2;
const int TriggerPin =3;
long distanciaAlObjeto;

void setup()
{
  pinMode (E1, OUTPUT);
  pinMode (I1, OUTPUT);
  pinMode (I2, OUTPUT);
  pinMode (EchoPin,INPUT);
  pinMode (TriggerPin,OUTPUT);
  Serial.begin(9600);
 }

void loop()
{
  distanciaAlObjeto=medirDistancia();
  if(distanciaAlObjeto>20)
  {
   girarMotor();
  }
  else
  {
    digitalWrite (E1, LOW); //Parar el motor 1
  }
}
long medirDistancia()
{
long distancia;
long tiempo;
digitalWrite(TriggerPin,LOW); /* Por cuestión de estabilización del sensor*/
delayMicroseconds(5);
digitalWrite(TriggerPin, HIGH); /* envío del pulso ultrasónico*/
delayMicroseconds(10);
digitalWrite(TriggerPin, LOW);
tiempo=pulseIn(EchoPin, HIGH); /* Función para medir la longitud del pulso entrante. Mide el tiempo que transcurrido entre el envío del pulso ultrasónico y cuando el sensor recibe el rebote, es decir: desde que el pin 12 empieza a recibir el rebote, HIGH, hasta que deja de hacerlo, LOW, la longitud del pulso entrante*/
distancia= tiempo/59; /*fórmula para calcular la distancia */
/*Monitorización en centímetros por el monitor serial*/
Serial.println("Distancia ");
Serial.println(distancia);
Serial.println(" cm");
return(distancia);
}

void girarMotor()
{
  digitalWrite (E1, HIGH); //Activar el motor 1
  digitalWrite (I1, HIGH);  //Iniciar el giro
  digitalWrite (I2, LOW);
}

No hay comentarios: