Imprimir

Cómo Medir Distancias con el Sensor Ultrasónico PING

Escrito por Raúl Alvarez.

 

Tutorial Sensor UltrasonicoLos sensores ultrasónicos permiten medir distancias desde los 2-3 centímetros hasta los 3-6 metros (para algunos modelos populares) sin la necesidad de un contacto físico, lo cual es muy útil en una amplia variedad de aplicaciones, desde la robótica y los sistemas de alarma, hasta aplicaciones industriales y por supuesto, también en proyectos de pasatiempo para los aficionados al bricolaje electrónico.

El Sensor Ultrasónico de Distancia PING (o "PING)))" como lo denomina el fabricante) tiene una interfaz simple de tres terminales y utiliza una sola linea para lograr una comunicación bidireccional con su dispositivo de control (típicamente un microcontrolador).

¿No estás muy seguro de cómo hacer las lecturas de distancia de este sensor? En este tutorial presentamos un sistema básico con un microcontrolador y un programa en lenguaje C para la interfaz con el sensor PING de Parallax. El microcontrolador lee el dato de la distancia del sensor y lo visualiza en una pantalla LCD genérica.

ACTUALIZACION 13/09/13: Hemos incluido un video en el que se explica en detalle el funcionamiento del sensor y el algoritmo para la interfaz con el mismo. En este video usamos el sensor ultrasónico HC-SR04 por ser un sensor muy conocido y de muy bajo costo, sin embargo el 99% de la explicación se aplica también al sensor PING y a otros sensores ultrasónicos de 3 y 4 terminales.

Video Demostrativo con el Sensor HC-SR04


Tecnologia Bolivia -  

Contenido del Video

  • Demostración del circuito funcionando (sensor HC-SR04 + PIC + LCD 16x2).
  • Conceptos teóricos básicos del funcionamiento del sensor.
  • Diagrama del circuito.
  • Algoritmo general para la interfaz con el sensor ultrasónico.

Diagrama de Circuito con el HC-SR04

Cómo Medir Distancias con Sensores Ultrasónicos

Descargas

Proyecto MPLAB X con el sensor HC-SR04. El proyecto ya está compilado y el código listo para ser grabado al microcontrolador, para recompilarlo es necesario tener el compilador Hi-Tech (Microchip) PICC v9.81 o superior.

El mismo código funciona con el sensor PING haciendo modificaciones mínimas y también con otros sensores similares.

Tenemos el Sensor Ultrasónico HC-SR04 a la venta.

---------------------------------------------------------------------------------------------

Características Principales del Sensor PING

Sensor Ultrasónico PINGEl sensor PING funciona mediante la transmisión de una ráfaga de ultrasonido en una frecuencia muy por encima del rango auditivo humano y provee un pulso de salida, el cual corresponde con el tiempo requerido por el eco (rebote) para retornar hasta el sensor. Al medir la duración de este pulso se puede calcular fácilmente la distancia al objetivo.

Las características más importantes del sensor PING son las siguientes:

  • Rango: 2 cm a 3 m
  • LED indicador de ráfaga que muestra la actividad del sensor
  • Interfaz bidireccional por pulso, en un único pin de E/S para comunicación con microcontroladores TTL (5V) o CMOS (3.3V)
  • Disparo de entrada: pulso TTL positivo, 2 μs  mínimo, 5 μs típico
  • Pulso eco de salida: pulso positivo TTL, 115 μs mínimo a 18.5 ms máximo.

Encuentra los detalles de este sensor en nuestra Tienda Virtual.

Descripción del Hardware

El hardware para este proyecto es muy similar al usado en el proyecto "Bus Serial I2C: Sensor de Temperatura MCP9800 con PIC16F628A y LCD" , se ha usado el mismo microcontrolador y también la pantalla LCD para visualizar la distancia leída. No explicaré en detalle la implementación de estos dos dispositivos ya que dicha información se la puede encontrar en el tutorial mencionado.

Microcontrolador PIC16F628A

El PIC se ha programado para trabajar con su oscilador interno de 4 MHz, minimizando así el conteo de componentes externos. El código de programa para la interfaz con el sensor ultrasónico es muy sencillo; el programa para el PIC está escrito en lenguaje C para el compilador PICC de Hi Tech, pero es fácilmente portable a otros compiladores, otros lenguajes o incluso al lenguaje ensamblador.

Pantalla de Cristal Líquido (LCD)

La interfaz con la pantalla LCD también se ha descrito con más detalle en el tutorial "Bus Serial I2C: Sensor de Temperatura MCP9800 con PIC16F628A y LCD" , es así que no ahondaré en el uso de este dispositivo. En este ejemplo también la pantalla LCD trabaja en la modalidad con cuatro líneas paralelas de datos y se ha usado la librería de conexión para LCDs genéricos provista por el compilador PICC de Hi Tech.

Diagrama del Circuito

Circuito con sensor ultrasónico PING

 

Sensor PING con PIC y LCD

Funcionamiento del Sensor Ultrasónico de Distancia PING

El sensor PING posee solamente tres terminales, dos de las cuales son para la alimentación de voltaje (VDD y GND) y la tercera (SIG) es usada para la comunicación bidireccional con el microcontrolador.

La comunicación con el sensor es realmente muy simple. Una vez que se ha entendido el protocolo, es fácil implementarlo.

Protocolo de Comunicación

El sensor PING detecta objetos mediante la emisión de una ráfaga ultrasónica y luego "escucha" el eco de retorno.

Bajo el control de un microcontrolador, el cual debe enviar un pulso corto de disparo, el sensor emite una corta ráfaga ultrasónica a una frecuencia de 40 KHz. La ráfaga viaja a través del aire, choca con un objeto y luego rebota hacia el sensor. El sensor PING provee un pulso de salida al microcontrolador, que inicia cuando la ráfaga es enviada y termina cuando el eco es detectado, de ahí que la longitud del pulso corresponda con la distancia al objeto.

Sensor ultrasónico PING

Protocolo de comunicación sensor PING


De la explicación arriba mencionada se puede resumir el siguiente algoritmo básico para la lectura del sensor:

  1. Configurar el pin de comunicación en el microcontrolador como salida.
  2. Escribir un "0" lógico al pin de comunicación.
  3. Esperar un tiempo corto para estabilizar la línea de comunicación (5 μs).
  4. Escribir un "1" lógico al pin de comunicación. (Inicio de pulso de disparo).
  5. Retardo de tiempo (2-5 μs) para lograr el ancho de pulso de disparo del sensor.
  6. Terminar el pulso de disparo escribiendo un "0" lógico al pin de comunicación.
  7. Configurar el pin de comunicación como entrada.
  8. Esperar hasta recibir un "1" lógico en el pin de comunicación. (Inicio del pulso de eco de salida del sensor).
  9. Activar el temporizador del PIC
  10. Esperara hasta recibir un "0" lógico en el pin de comunicación. (Fin del pulso de eco de salida del sensor).
  11. Desactivar el temporizador del PIC.
  12. Leer conteo efectivo en el temporizador en μs.
  13. Calcular la distancia en función a la duración del pulso de eco de salida del sensor.

Debido a que la duración del pulso provisto por el sensor contiene la información del tiempo que tarda la ráfaga en ir y volver desde el objetivo, esta duración se debe dividir por 2 para calcular la distancia, de otro modo estaríamos calculando el doble de la distancia (ida + vuelta).

Listado del Programa

El código está detalladamente comentado.

001./* *******************************************************************************
002. * Sensor Ultrasónico de Distancia PING (Parallax) con PIC16F6248A  y LCD Ver. 1.0
003. *
004. * Recibe la lectura de distancia del sensor PING (Parallax)
005. * y lo visualiza en un LCD genérico de 16x2.
006. * Para el uso del LCD hace uso de las librerías y código ejemplo provistos
007. * por el compilador PICC de HI-tech.
008. *
009. * Hardware:    PIC16F628A, Sensor PING))), LCD 16x2 genérico.
010. * Funciones:     Software ejemplo para el sensor ultrasónico PING))) de Parallax
011. * Versión:        1.0 (10 de Marzo de 2011)
012. * Autor:         Raul Alvarez Torrico (www.TecBolivia.com)
013. *
014. * Descargado de www.TecBolivia.com - Ingresa al sitio para más ejemplos similares.
015.**********************************************************************************/
016. 
017.#include <htc.h>
018.#include <stdlib.h>    // Necesario para la función itoa()
019.#include <stdio.h>    // Necesario para la función itoa()
020.#include "lcd.h"    // Librería para comunicación con el LCD incluida con el compilador PICC
021.#include "delay.h"    // Librería para retardos incluida con el compilador PICC
022. 
023./* Palabra de configuracion para el PIC16F628A, versión PICC 9.70 */
024.//__CONFIG(UNPROTECT & UNPROTECT & LVPDIS & BOREN & MCLREN & PWRTEN & WDTDIS & INTIO);
025. 
026./* Palabra de configuracion para el PIC16F628A para versiones del compilador PICC desde
027. la Version 9.81 en adelante */
028.__CONFIG(CPD_OFF & CP_OFF & LVP_OFF & BOREN_ON & MCLRE_ON & PWRTE_ON & WDTE_OFF & FOSC_INTOSCIO);
029. 
030./* A partir de la versión 9.81 del compilador PICC las definiciones de los bits de configuración
031. han sido cambiadas. Todas las definiciones para el PIC16F628A están ubicadas en el archivo:
032. (Directorio Archivos de Programa)\HI-TECH Software\PICC\9.xx\include\pic16f628a.h
033.*/
034. 
035.#define SENSOR_PIN    RB5
036.#define SENSOR_PIN_DIR    TRISB5
037. 
038.char aux;    // Variable auxiliar para depuración
039. 
040.void timer_init ();
041.void mostrar_distancia (unsigned int * distancia, char fila);
042. 
043.void main(void)
044.{    
045.     unsigned int conteoMSB = 0;    // Variable de 16 bits para almacenamiento de conteo total
046.     unsigned char conteoLSB = 0;    // Variable de 8 bits para almacenamiento LSB del conteo
047.    CMCON = 0x07;    // Configurar Puerto A como digital I/O
048.     TRISB = 0x00;    // Puerto B como salida
049.     /* OJO!!! Los pull-ups del Puerto B deben estar deshabilitados */
050.  
051.     lcd_init();    // Función de inicializacion del LCD
052.     timer_init();    // Función de inicializacion del Timer1
053.  
054.     SENSOR_PIN = 0;    // Inicializar el valor del pin de comunicación con el sensor
055.  
056.     while (1) {    // Ciclo infinito
057. 
058.         SENSOR_PIN_DIR = 0;    // Configurara SENSOR_PIN como salida
059.         SENSOR_PIN = 1;    // Inicia pulso de disparo
060.         DelayUs(5);    // Retardo de tiempo requerido s/g datasheet (mínimo 2 us)
061.         SENSOR_PIN = 0;    // Termina pulso de disparo
062.  
063.         SENSOR_PIN_DIR = 1;        // Configurara SENSOR_PIN como entrada
064.         TMR1H = 177;    // Carga inicial del timer1 registro MSB
065.         TMR1L = 224;    // Carga inicial del timer1 registro LSB    
066.         while (!SENSOR_PIN)    // Esperar el arribo del pulso de respuesta
067.             ;
068.         TMR1ON = 1;    // Llegó pulso eco de respuesta, activar Timer1
069.  
070.         while (SENSOR_PIN && !TMR1IF) // Esperar conclusion de eco de respuesta
071.             ;                    // o timeout TMR1IF de 20 ms
072.  
073.         /* Rango de duración de pulso provisto por el sensor: 115 us a 18.5 ms
074.          * Si el conteo sobrepasa los 18.5 ms y llega a 20 ms, se puede considerar
075.          * que se ha recibido un pulso no válido del sensor. Error de timeout. */
076.  
077.         //if (TMR1IF)    // Si el Timer pasa los 20 ms programados...
078.        // ubicar aquí algún código de error de timeout
079.  
080.        TMR1ON = 0;    // Desactivar Timer1
081.        TMR1IF = 0;        // Borrar bandera Timer1
082.  
083.         conteoMSB = TMR1H;    // Leer máximo conteo alcanzado por el Timer MSB
084.         conteoLSB = TMR1L;    // Leer máximo conteo alcanzado por el Timer LSB
085.  
086.         /* Conversión de 2 bytes a 1 word (16 bits):
087.          * Recorrer el MSB 8 posiciones a la izquierda (multipplizar por 256)
088.          * y luego sumarlo con el byte LSB */
089.         conteoMSB = conteoMSB*256;    //     Multiplicar por 256 para recorrer 8 posiciones
090.         conteoMSB = conteoMSB + conteoLSB;    // Sumar con el byte LSB
091.  
092.         /* Calculo de la distancia en función al ancho del pulso:
093.          * Restar primeramente el número de carga inicial del Timer (45536),
094.          * dividir por 29 (vel. sonido = 1/29 cm/us, calculado de vel. sonido = 345 m/s),
095.          * dividir por 2 debido a que el pulso provisto por el sensor representa el tiempo
096.          * total de ida y vuelta (eco) del ultrasonido. Solo necesitamos la mitad. */
097.         conteoMSB = (conteoMSB - 45536)/29/2;
098.         mostrar_distancia(&conteoMSB, 0);
099.  
100.         DelayMs(255);    // Pequeño retardo para no saturar la impresión en el LCD
101.     }
102.}
103. 
104./*******************************************************************************
105.*                     INICIALIZA EL TIMER1 DEL MICROCONTROLADOR
106.*
107.* Descripción    :    Inicializa el Timer1 del microcontrolador para funcionar con
108. reloj interno, sin prescalador, sin interrupción.
109.* Argumentos    :    Ninguno.
110.* Retorna        :    Nada
111.* Notas            :    
112.********************************************************************************/
113.void timer_init()
114.{
115.     TMR1IE = 0;    // Interrupción Timer1 desabilitada
116.  
117.     // Timer1 Prescalador = 1 - TMR1 Preset = 45536 (para un conteo máximo de 20 ms
118.     //Freq = 50.00 Hz - Periodo = 0.020000 seconds
119.     // Rango de duración de pulso provisto por el sensor: 115 us a 18.5 ms
120.     // Si el conteo sobrepasa los 18.5 ms y llega a 20 ms, se puede considerar
121.     // que se ha recibido un pulso no válido del sensor. Error de timeout.
122.  
123.     T1CKPS1 = 0;   // bits 5-4  Bits de selección de Prescalador
124.     T1CKPS0 = 0;   // bit 4
125.     TMR1CS = 0;    // bit 1 Timer1 Clock Source Select bit...0 = Internal clock (FOSC/4)
126.}
127. 
128./*******************************************************************************
129.*                     MUESTRA LA DISTANCIA EN EL LCD
130.*
131.* Descripción    :    Muestra en el LCD la distancia en centímetros
132.* Argumentos    :    unsigned int * distancia    puntero al word de la distancia
133.*                    char fila  la fila para la escritura de la temperatura
134.* Retorna        :    Nada
135.* Notas            :    
136.********************************************************************************/
137.void mostrar_distancia (unsigned int * distancia, char fila)
138.{
139.     char buf[3];    // Buffer temporal para conversión entero a cadena de caracteres
140.  
141.     lcd_goto(fila);    // Posicionar el cursor del LCD en la fila correspondiente
142.     lcd_puts("Distancia:");
143.     itoa(buf, *distancia, 10);    // Convertir word de distancia a cadena de caracteres
144.     lcd_puts(buf);        // Mandar a LCD
145.     lcd_puts(" cm");    // Escribir " cm"
146.}

Conclusión

Como se ha visto, el procedimiento para la lectura del Sensor Ultrasónico de Distancia PING))) es bastante sencillo. No es difícil imaginar varias posibilidades de aplicación para este sensor en áreas como la robótica, sistemas de navegación, sistemas de seguridad e incluso sistemas industriales; su interfaz simple hace que sea posible su uso con virtualmente cualquier microcontrolador, incluso con los más pequeños como el PIC10F200 de Microchip.

Raúl Alvarez Torrico
www.TecBolivia.com

Suscríbete a Nuestro Boletín de Noticias

Y te notificaremos de la publicación de otros artículos similares.

Nombre:

Correo Electrónico:


Productos Relacionados en Nuestra Tienda Virtual

Módulo Ultrasónico HC-SR04

hc-sr047

Detalles del Producto

$us 2.15

Módulo Ultrasónico sin Zona Ciega: SDM-IO

M__dulo_Ultras___4f18b5993c9ab.jpg

Detalles del Producto

$us 19.00

Sensor Ultrasónico de Distancia PING)))

Sensor_Ultras__n_4cc85f92ae46e.jpg

Detalles del Producto

$us 59.98

PIC16F876A-I/SP

PIC16F876A_I_SP_4bc0dcd33f116.jpg

Detalles del Producto

$us 9.50

Microcontrolador ATMEGA324PA-PU-ND

453-40-dip_sml

Detalles del Producto

$us 11.76