martes, 14 de septiembre de 2021

Midiendo distancias con un sensor HC-SR04

 Un complemento imprescindible para muchos de robots o vehículos controlados a distancia es un sensor que nos permita saber la distancia libre de obstáculos para movernos. Si las distancias van a ser pequeñas podemos emplear sensores de infrarrojos, pero si queremos movernos en áreas grandes y poder medir distancias en un rango de varios metros el complemento perfecto es un sensor de ultrasonidos. ¿Y porque hacer una entrada sobre un sensor sobre el que se han escrito miles de entradas? Pues por que la inmensa mayoría de entradas y revisiones sobre este sensor no se complican la vida y recurren a una librería para sacar el dato de la distancia. A ver, el uso de librerías está bien, es casi obligatorio para todo hardware minimamente complejo, pero este no es el caso ¿para que utilizar una librería cuando tan sólo hace falte un poco de ingenio y una sencilla operación matemática? Además repasaremos un concepto muy simple de física aplicada que no nos vendrá mal como argumento de que estudiar sirve para muchas cosas (además de no ser un ignorante).

Funciona exactamente igual que un radar, de hecho es un pequeño radar. Emite un pulso de sonido a una frecuencia tan alta que es imperceptible para el oído humano y cronometra el tiempo que el sonido tarda en llegar a un obstáculo, rebotar y volver al sensor. Así que tenemos 2 datos: la velocidad del sonido (343.2 m/s) y el tiempo, atención que ahora viene lo chulo, tal como aprendimos en el instituto en el nivel más básico de Física, que es la cinemática (ahora veréis como si que sirve de algo el haber estudiado) echamos mano de una conocidísima formula (e = v * t) y calculamos la distancia recorrida por el sonido. Parece fácil ¿verdad?... por que lo es y no hace falta recurrir a una librería para hacer una simple multiplicación.

Utilizaremos un sensor de ultrasonidos HC-SR04, conocidísimo, cuyo rango de medida va desde los 3cm a los 3m, suficiente para cualquier proyecto de robótica y que sólo necesita de 2 pines para  hacerlo funcionar:

El sensor de ultrasonidos sólo tiene 4 pines, uno de alimentación, uno de masa, uno de disparo (Triger) y, el último, el pin Echo por el cual nos dará la lectura del tiempo.  

A través del pin Triger enviaremos una señal de activación al sensor y para ello lo activaremos durante 10 microsegundos, es decir, le enviaremos un pulso muy corto, no necesita más. Luego transladaremos nuestra atención en el pin Echo, por este pin el sensor nos dará el tiempo que el sonido a tardado en ir, rebotar  y volver al sensor. Esto lo haremos cada vez que necesitemos tomar una media, que en el código de ejemplo será cada segundo.

La señal de salida del sensor será un pulso de la misma duración que el tiempo cronometrado, es decir, si el sonido tardó 10 microsegundos en ir del sensor al objeto y volver al sensor nos devolverá un pulso de una duración de 10 microsegundos. Así que será fácilmente medible mediante la función pulseIn(). También hay que tener en cuenta que ese tiempo es de ida y vuelta, por lo que tenemos que dividirlo por la mitad a la hora de hacer el cálculo.

Así que sin más preámbulos vamos a programar:

long tiempo;

int disparador = 7;   // triger

int entrada = 8;      // echo

float distancia;


void setup(){

  pinMode(disparador, OUTPUT);

  pinMode(entrada, INPUT);

  Serial.begin(9600);

}

            

void loop(){

  // lanzamos un pequeño pulso para activar el sensor

  digitalWrite(disparador, HIGH);

  delayMicroseconds(10);

  digitalWrite(disparador, LOW);

  

  // medimos el pulso de respuesta

  tiempo = (pulseIn(entrada, HIGH)/2); // dividido por 2 por que es el 

                                       // tiempo que el sonido tarda

                                       // en ir y en volver

  // ahora calcularemos la distancia en cm

  // sabiendo que el espacio es igual a la velocidad por el tiempo

  // y que la velocidad del sonido es de 343m/s y que el tiempo lo 

  // tenemos en millonesimas de segundo

  distancia = float(tiempo * 0.0343);

  // y lo mostramos por el puerto serie una vez por segundo

  Serial.println(distancia);

  delay(1000);

}

Así de fácil es este ejemplo. Dentro de un proyecto sería aun mas sencillo pues no necesitaríamos sacar los datos por el puerto serie (al menos no los dos) y podríamos meter todo el procedimiento dentro de una función de modo que con tan solo llamarla nos diera la distancia. De hecho yo he modificado el código para mostrar el dato de distancia en el Micro-micro y me ha quedado tal que así:


Dentro del código hay que prestar atención a los distintos tipos de datos ya que trabajamos con un unsigned long y con un float y además tenemos que hacer operaciones entre ellos, lo cual puede ser delicado.

Terminaré comentando que haciendo las pruebas con el sensor y el código del ejemplo me sorprendió lo precisas que resultan las mediciones siempre que la superficie y el sensor estuviesen bien perpendiculares, si no el rebote del sonido o los ecos parásitos podían generar medidas erróneas.

Y nada más que añadir….. bueno si, quiero hacer hincapié en que las librerías están bien para muchos casos pero en otros como este es mejor, en mi opinión, utilizar los conocimientos que hemos adquirido en otras disciplinas, como física.





No hay comentarios: