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.

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. Como la velocidad de propagación del sonido en el aire es un dato bien conocido (343.2 m/s) 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.

Utilizaremos un sensor de ultrasonidos TS601P01 cuyo rango de medida va desde los 3cm a los 3m, suficiente para cualquier proyecto de robótica y que tiene la gran ventaja de necesitar un único pin de nuestro Arduino para hacerlo funcionar:

sensor ultrasonidos arduino ping

¿Como puede funcionar con un solo pin? ¿acaso no necesitamos uno para mandarle una señal y otro para recibir la respuesta?. Pues no, se puede hacer todo por el mismo y de una forma nada complicada lo que también nos servirá, de paso, para disipar una de las dudas más comunes entre los principiantes: la inamovilidad de la declaración de pines como entrada o salidas.

En todos los ejemplos de código que nos encontraremos en la web oficial de Arduino y en las demás se utiliza el bloque setup() del Sketch para hacer declaraciones pinMode() y establecer los pines que vayamos a utilizar como entradas o como salidas. En todos estos ejemplos se busca la sencillez y estas declaraciones no se cambian a lo largo del código y esto da lugar a que muchos usuarios tengan la errónea creencia de que sólo se pueden declarar pines como entradas o salidas en el setup() y que una vez establecido un pin como entrada o salida ya no se puede cambiar…. FALSE, los podemos declarar en cualquier punto del código y cambiarlos tantas veces como queramos. PERO no lo haremos a nos ser que sea estrictamente necesario ya que saltarnos a la torera las reglas de estilo al escribir código puede suponernos un fuerte dolor de cabeza a la hora de depurar un Sketch y generara un código muy guarro que luego nadie quiera utilizar por ser incomprensible (y recordemos que a veces somos nosotros mismos los que lo tenemos que interpretarlo unos meses más tarde), así que cuanto mejor escrito y más claro mejor.

Volvamos al sensor de ultrasonidos: solo tiene tres pines, uno de alimentación, uno de masa y uno de señal. Alimentación a +5, masa a GND y señal a un pin digital (por ejemplo el 8).

Arduino sensor ultrasonidos

A través de este pin enviaremos una señal de activación al sensor y para ello lo pondremos como salida, lo activaremos durante 10 microsegundos y lo desactivaremos, luego cambiaremos el pin y lo dejaremos como entrada para escuchar la señal de respuesta del sensor… y 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 el comando 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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/* Sketch medidor ultrasonico */
/* Creado por Josemanu        */
/* para Ardumania.es          */

unsigned long pulso; // necesitamos una variable para medir el pulso
float distancia; // otra para calcular la distancia
int pin = 8;  // y otra para el pin

void setup()
{
Serial.begin(9600); // inicializamos el puerto serie
}
void loop()
{
pinMode(pin, OUTPUT); // ponemos el pin como salida
digitalWrite(pin, HIGH); // lo activamos
delayMicroseconds(10); // esperamos 10 microsegundos
digitalWrite(pin, LOW); // lo desactivamos
pinMode(pin, INPUT); // cambiamos el pin como entrada
pulso = pulseIn(pin, HIGH); // medimos el pulso de salida del sensor
Serial.print("tiempo = "); // lo pasamos a milisegundos y lo sacamos por
// el puerto serie
Serial.print(float(pulso/1000.0));
Serial.print("ms, distancia = "); // ahora calculamos la distancia en cm
// y al puerto serie
distancia = ((float(pulso/1000.0))*34.32)/2;
Serial.print(distancia);
Serial.println("cm");
delay(1000); // esperamos un segundo antes de hacer una nueva medida
}

Por el puerto serie obtendremos una serie de mediciones como esta:

sensor de ultrasonidos Arduino

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.

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.

Podéis  descargar el Sketch aquí y guardarlo es vuestra carpeta sketchbook, si optáis por copiar/pegar ojo a los signos como las comillas, que pueden dar problemas.


Si este tutorial te ha sido de utilidad puedes considerar hacerme un donativo, por pequeño que sea estarás contribuyendo a que siga con esta labor.