bclose

Circuito con sensor de distancia

Arduino y los sensores de distancia

Objetivos

 

 

    • Sensor ultrasónico de distancia.
    • Más sobre medir el tiempo: delayMicroseconds ().
    • Más funciones disponibles: PulseIn ().
    • Importando una librería externa.
 

Material requerido.

 

  Tienda España Tienda Mexico
Vista principal de un arduino uno Arduino UNO Arduino UNO
Protoboardconexiones Una Protoboard mas  cables. Una Protoboard mas  cables.
Ping range finder Sensor de distancia HC-SR04 Sensor de distancia HC-SR04
 componentecomponente  diodo LED y resistencia.  Diodo LED y resistencia.

 

 

Como funciona un sensor ultrasónicode distancia

 

Hemos visto, en los documentales, que los murciélagos son capaces de volar en completa oscuridad y sin embargo, sortear obstáculos o atrapar insectos en vuelo. Sabemos que lo hacen, pero rara vez pensamos como.

Tenemos una vaga idea de que se llama ecolocalización y que más o menos tiene que ver con unos sonidos agudos que emiten y que después recogen con esas enormes orejas que Dios les ha dado, pero rara vez nos planteamos cómo es esto posible.

Delfines y ballenas utilizan un sistema similar para atrapar a sus presas, y hasta hemos visto que, en cualquier película de submarinos, en el momento álgido el capitán ordena emitir un pulso único de sonar para localizar al enemigo.

El concepto básico, es siempre el mismo, sabiendo a qué velocidad viaja el sonido, si emitimos un pulso sónico corto y escuchamos cuanto tiempo tarda en regresar el eco podemos calcular la distancia a la que se encuentra el objeto en el que ha rebotado la señal.

 
  • El radar funciona de modo similar aunque usando ondas de radio frecuencia muy cortasy con una problemática propia descomunal. Un pulso de radiofrecuencia se emite desde la antena y se recoge el eco que vuelve a la velocidad de la luz.
 

Lo que haremos en esta sesión es utilizar un sensor de distancia sencillo HC-SR04 (y muy parecido a los sensores de aparcamiento de los coches modernos), que nos permite enviar estos pulsos ultrasónicos y escuchar el eco de retorno. Midiendo este tiempo, podemos calcular la distancia hasta el obstáculo.

 
  • El oído humano no percibe sonidos por encima de 20kHz. Por eso, a las ondas de mayor frecuencia las llamamos ultrasonidos ( mas allá del sonido).  Los sensores de ultrasonidos funcionan sobre los 40 kHz.
  • No son perfectos, les influye la temperatura ambiente, la humedad y los materiales en los que reflejan, lo que genera una cierta incertidumbre. Pero a cambio son baratos y efectivos hasta un poco más de 3 metros en condiciones normales si la precisión no es un problema determinante
 

 

Diagrama de conexión

 

Veamos como conectar uno de esto detectores a nuestros Duinos. Aquí está el esquema eléctrico y de protoboard por cortesía de Fritzing:

Esquema

Y de nuevo, el diagrama de conexión de la protoboard

Protoboard

El Programa de control

 

Vamos con el programa, empezamos definiendo algunos valores:

#define trigPin 13
#define echoPin 12
#define led 2

Hasta ahora habíamos visto que podíamos definir una variable como int, por ejemplo, y también como una constante (const int pin). Aquí utilizamos otro método, el #define que es una directiva para el compilador.

Esto solo significa que el compilador (en rigor el pre procesador) cambiará todas las ocurrencias de estos #define en nuestro programa por su valor antes de compilar. Esta es la forma clásica de C de hacer esto y tiene la virtud de que no ocupa memoria definiendo una variable (y con un Arduino UNO, que va muy corto de memoria, esto puede ser crítico en ocasiones).

void setup()
   {    
       Serial.begin (9600);
       pinMode(trigPin, OUTPUT);
       pinMode(echoPin, INPUT);
       pinMode(led, OUTPUT);
   }

Ya estamos más que habituados a la función delay(milis), pero el reloj interno de Arduino uno mide en microsegundos y tenemos otra función parecida delayMicroseconds(µs) que simplemente congela Arduino el número especificado de microsegundos.

Para dar un pulso ultrasónico lo que hacemos es activar el pin Trigger durante unos microsegundos y para ello lo ponemos en HIGH, antes de escuchar el eco:

digitalWrite(trigPin, LOW);     // Nos aseguramos de que el trigger está desactivado
delayMicroseconds(2);           // Para estar seguros de que el trigger ya está LOW
digitalWrite(trigPin, HIGH);    // Activamos el pulso de salida
delayMicroseconds(10);          // Esperamos 10µs. El pulso sigue active este tiempo
digitalWrite(trigPin, LOW);     // Cortamos el pulso y a esperar el echo

Para escuchar el pulso vamos a usar otra función, pulseIn() ( Oh sí, hay muchas, muchísimas). Para leer el manual de pulseIn()  buscad en google Arduino pulseIn y vereis que pronto lo encontrais.

Básicamente lo que hace es escuchar el pin que le pasamos, buscando una señal que pase de LOW a HIGH ( si le pasamos HIGH como parámetro) y cuenta el tiempo que tarda en volver a bajar desde que sube.

long duracion, distancia ;
duracion = pulseIn(echoPin, HIGH) ;

Ahora ya sabemos el tiempo que tarda en volver el eco en µs. Como la velocidad del sonido es de 343 metros / segundo, Necesitamos 1/343 = 0,00291 segundos para recorrer un metro.

Para usar una medida más cómoda podemos pasar esto  a microsegundos por centímetro:

formula velocidad sonido

Como nuestro eco mide el tiempo que tarda el pulso en ir y venir la distancia recorrida será la mitad:

formula distancia sonido

Así que el programa queda parecido a esto ( Prog_18_1) : Descargar ejemplo 18_1:

     #define trigPin 13
     #define echoPin 12
     #define led 2

     void setup()
        {   Serial.begin (9600);
            pinMode(trigPin, OUTPUT);
            pinMode(echoPin, INPUT); 
            pinMode(led, OUTPUT);
        }

     void loop()
        {   long duracion, distancia ;
            digitalWrite(trigPin, LOW);        // Nos aseguramos de que el trigger está desactivado
            delayMicroseconds(2);              // Para asegurarnos de que el trigger esta LOW
            digitalWrite(trigPin, HIGH);       // Activamos el pulso de salida
            delayMicroseconds(10);             // Esperamos 10µs. El pulso sigue active este tiempo
            digitalWrite(trigPin, LOW);        // Cortamos el pulso y a esperar el echo
            duracion = pulseIn(echoPin, HIGH) ;
            distancia = duracion / 2 / 29.1  ;
            Serial.println(String(distancia) + " cm.") ;
            int Limite = 200 ;                  // Medida en vacío del sensor
            if ( distancia < Limite)
                 digitalWrite ( led , HIGH) ;
            else
                 digitalWrite( led , LOW) ;
            delay (500) ;                  // Para limitar el número de mediciones
        }

Para convertir esto en un detector de movimiento hemos creado  una variable un poco menor de la medida que el sensor recibe en vacio (en mi caso unos 200 cm). Si la distancia medida cae por debajo este valor es que algo se ha interpuesto y por tanto encendemos una alarma, en nuestro caso un humilde LED.

Después de este ejercicio de física y matemáticas, que sin duda causará furor entre los estudiantes aplicados, vamos a hacer el mismo programa pero usando una librería externa, que alguien se ha molestado en escribir, paras esas pocas personas que no disfrutan de los problemas de ciencias y que así, podamos ver la diferencia.

Podeís descargar la librería de aquí, Descargar, o bien de la web del autor en  code.google.com/p/arduino-new-ping.

Para instalar una librería externa no incluida en el IDE de Arduino tenemos que importarla con el menú Programa \ Importar librería\Añadir librería:

Captura menu

En la ventana que sale, buscad el fichero NewPing_v1.5.zip que habéis descargado y seleccionadlo.

Ya está. Arduino ha importado la librería y los ejemplos que incluye. Si ahora volvéis a Programa\ImportarLibrería, veréis que al final de la lista ya está disponible como NewPing, y además el zip incluye varios ejemplos de uso. Vamos a cargar el equivalente del programa anterior. Haced :

Archivo \ Ejemplos \ NewPing \ NewPingExample

 Arduino cargara un programa de ejemplo. Las instrucciones claves son primero inicializar la librería con:

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE) ;

Y después medir la distancia:

unsigned int uS = sonar.ping() ;

Aqui os copio el ejemplo para vuestra referencia:

     #include <NewPing.h>

     #define TRIGGER_PIN 12 // Arduino pin tied to trigger pin on the ultrasonic sensor.    
     #define ECHO_PIN 11    // Arduino pin tied to echo pin on the ultrasonic sensor.
     #define MAX_DISTANCE 200 
     
     NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance
 
     void setup() 
        {
           Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results.
        }
 
     void loop()
       {
           delay(50); 
           unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS)
           Serial.print("Ping: ");
           Serial.print(uS / US_ROUNDTRIP_CM); 
           Serial.println("cm");
       }

Como veis la librería se encarga de inicializar los pines necesarios, enviar los pulsos, escuchar el eco de retorno  y de hacer los cálculos. No está mal.

 
  • Fijaros, que el ejemplo, utiliza diferentes pines a los que nosotros hemos usado,así que tendreís que modificarlos. Igualmente, el ejemplo inicializa la puerta serie a 115.200. Es imprescindible igualar esta velocidad con la que recibe la consola o veréis muchas cosas raras en pantalla.
  • Los alumnos avispados se habrán dado cuenta de que Arduino viene forrado de ejemplos que pueden cargar y usar. Os invito a que investiguéis y juguéis con estos ejemplos  cuanto queráis.
 

Resumen de la sesión

 

 
    • Hemos conocido los sensores ultrasónicos de distancia.
      • Sabemos que sirven para medir algo menos de 3 0 4 metros
      • Sabemos que no son perfectos pero son útiles y baratos.
    • Más sobre medir el tiempo: delayMicroseconds ().
    • Más funciones disponibles: PulseIn ().
    • Importando una librería externa, de nuevo,algo que en las próximas sesiones iremos haciendo cada vez más, a medida que los elementos a usar se vayan sofisticando.

 

 

 

 

 

 

 

Para porder realizar consultas a nuestros expertos, tienes que ser suscriptor. Suscribiendote nos ayudas a mantener este proyecto en marcha.

¡ Quiero Suscribirme !

Si ya eres premium y no puedes comentar haz login. Hacer login

(91) Comments

  • Avatar for Charly
    • Jorge

    hola buenas tardes, disculpa ¿como hago que en vez de un led, suene una alarma cuando detecte algo cercano( como menos de 4 metros)?

  • Avatar for Charly
    • Ivan Uriarte

    Sólo tienes que meter aquí un segundo led (y en el circuito claro):

    if ( distancia < Limite) digitalWrite ( led1 , HIGH) ; digitalWrite ( led2 , LOW) ; else digitalWrite( led1 , LOW) ; digitalWrite ( led2 , HIGH) ; delay (500) ; // Para limitar el número de mediciones

  • Avatar for Charly
    • Kenny centeno

    hola Ivan, quisiera usar dos led’s, una verde que se encienda cuando detecte algo, y una roja que se encienda cuando no detecte nada

  • Avatar for Charly
    • Ivan Uriarte

    Hola Domingo, a veces el sensor da algún valor un poco raro, sobre todo cuando la superficie está demasiado lejos. Igual rebota contra algún material que absorbe las ondas?

  • Avatar for Charly

    De vez en cuando me da valores en torno a 2300 cm.

  • Avatar for Charly
    • Ivan Uriarte

    Hola Jose María, no sé que quieres hacer con los leds. Que se enciendan al detectar algo delante?

  • Avatar for Charly
    • Jose Maria Ramirez Quiroz

    hola que tal tengo una duda con el sketch quiero hacer que funcione el mismo programa pero con 2 led alli que puedo hacer

  • Avatar for Charly
    • Ivan Uriarte

    Hola! Pruébalos por separado por si acaso uno no funcione, o lo tengas mal conectado o algo por el estilo.

  • Avatar for Charly

    hola, he intentado hacer un programa con dos sensores pero uno de ellos no me mide la distancia y no se encontrar el error, espero que me puedas ayudar. Gracias
    #define trigPin 9
    #define trigPin2 7
    #define echoPin 11
    #define echoPin2 8
    #define led 2

    void setup()
    { Serial.begin (9600);
    pinMode(trigPin, OUTPUT);
    pinMode(trigPin2, OUTPUT);
    pinMode(echoPin, INPUT);
    pinMode(echoPin2, INPUT);
    pinMode(led, OUTPUT);

    }

    void loop()
    { long duracion, distancia, duracion2, distancia2; ;

    digitalWrite(trigPin, LOW);
    digitalWrite(trigPin2, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin, HIGH);
    digitalWrite(trigPin2, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);
    digitalWrite(trigPin2, LOW);
    duracion = pulseIn(echoPin, HIGH) ;
    distancia = duracion / 2 / 29.1 ;
    duracion2 = pulseIn(echoPin2, HIGH) ;
    distancia2 = duracion2 / 2 / 29.1 ;
    Serial.println(String(distancia) + » cm.») ;
    Serial.println(String(distancia2) + » cm.») ;
    int Limite = 50;
    int Limite2 = 50;
    if ( distancia < Limite && distancia2 < Limite2)
    digitalWrite ( led , HIGH) ;
    else
    digitalWrite( led , LOW) ;
    delay (500) ;
    }

  • Avatar for Charly
    • Juan carlos macho mangas

    Hola Xabier,
    No estoy seguro de cual es el problema pero si entiendo bien, lo que quieres es simplemente medir la distancia con el ping, asi que puedes usar este codigo, que es el 2º ejemplo de nuestra pagina sobre el tema:

    #include

    void loop()
    {
    delay(50);
    unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS)
    Serial.print(«Ping: «);
    Serial.print(uS / US_ROUNDTRIP_CM);
    Serial.println(«cm»);
    }

  • Avatar for Charly
    • Xabier

    Buenas,

    Estoy intentando hacer cosas con el sensor de distancia. Me gusta uno de los ejemplos en los que chequea si el ping ha sido recibido porque da resultados muy estables, pero no sé cómo sacar de la función la variable distancia para seguir usándola en el programa principal.

    El código establece un criterio que llama a la función ping cada x milisegundos:
    sonar.ping_timer(echoCheck);
    Luego se declara una función echoCheck para verificar si se ha leído correctamente la respuesta con el comando:
    sonar.check_timer(), que si es verdadero entra dentro de un if:

    void echoCheck() { // Timer2 interrupt calls this function every 24uS where you can check the ping status.
    // Don’t do anything here!
    if (sonar.check_timer()) { // This is how you check to see if the ping was received.
    distancia = sonar.ping_result / US_ROUNDTRIP_CM; //Esto es mio
    Serial.print(«Ping: «);
    Serial.print(sonar.ping_result / US_ROUNDTRIP_CM); // Ping returned, uS result in ping_result, convert to cm with US_ROUNDTRIP_CM.
    Serial.println(«cm»);
    }
    // Don’t do anything here!
    }

    Obviamente escribe el resultado correcto en el puerto serie pero no puedo sacar de la función la variable distancia que es la que quiero usar en el procedimiento principal. ¿Cómo podría sacar este valor para hacer cosas con él?

    Gracias de antemano.

  • Avatar for Charly
    • Ivan Uriarte

    Hola Reymer, el circuito y la programación debería funcionarte igual sin estar conectado a un ordenador, siempre que la batería sea suficiente para alimentar el Arduino.

  • Avatar for Charly
    • Reymer

    Hola me gustaria saber como puedo usar mi sensor solo conectandolo a la bateria
    Estoy asiendo un proyecto pero solo me funciona si lo uso en mi pc
    Lo conecto a una bateria de 9v y solo me funciona una vez despues no me.vuelve a u funcionar

  • Avatar for Charly
    • Ivan Uriarte

    Hola Reinaldo, El sensor funciona correctamente. Parece que este tipo de sensor si tiene algo demasiado lejos lo interpreta como 0 ya que no recibe la respuesta de la onda. Si lo que quieres es hacer por ejemplo un detector de obstáculos, para que esquivarlos con un robot por ejemplo, lo que puedes hacer es incluir un !=0 en el if donde detectes la distancia mínima. Un saludo.

  • Avatar for Charly
    • Reinaldo

    Hola,

    realice el esquema y programa tal cual como indicas y me dice en el monitor serial el valor 0 cm, 0 cm, todo el rato, y eso que lo tengo apuntado al techo y la distancia no es menor a lo indicado, que podria ser? como puedo probar de manera simple que el sensor esta bueno y asi descartarlo?

    saludos,

  • Avatar for Charly
    • Alvaro

    Hola,

    Quiero saber el nivel de un pozo de agua. Este sensor mide bien las distancias con el agua?

    Y si el pozo es más alto que los 3.6 metros que mide el sensor… Existe otro sensor que mida mayores distancias?

    Saludos y gracias!

  • Avatar for Charly
    • Ivan Uriarte

    Hola Álvaro, el problema de estos sensores es que les afecta la deriva térmica, aunque hay maneras de compensarla. Sino tienes los SHARP que son por infrarrojos y además de que me parece que tienen mayor alcance no les afecta la deriva térmica, al menos no tanto. Un saludo.

  • Avatar for Charly

    Hola,

    Quiero saber el nivel de un pozo de agua. Este sensor mide bien las distancias con el agua?

    Y si el pozo es más alto que los 3.6 metros que mide el sensor… Existe otro sensor que mida mayores distancias?

    Saludos y gracias!

  • Avatar for Charly
    • Admin

    No se si te entiendo cano. EL sensor tiene un limite de unos 3.6 metros

  • Avatar for Charly

    Hola. ¿Como podría hacer para que el valor limite lo fije el mismo sensor en la primera medida?

Para porder realizar consultas a nuestros expertos, tienes que ser suscriptor. Suscribiendote nos ayudas a mantener este proyecto en marcha.

¡ Quiero Suscribirme !

Si ya eres premium y no puedes comentar haz login. Hacer login