Sensores
Prueba del sensor PING))) de distancia
por ultrasonidos de Parallax manejado con PIC

por Eduardo J. Carletti

Ver también: Medidores de distancia
ultrasónicos - Sensores de ultrasonido

Presento aquí una prueba de laboratorio realizada con un sensor de distancia PING))) de la empresa Parallax conectado a un microcontrolador PIC16F628A.

Para obtener una visualización sencilla de los valores obtenidos, se conectó el PIC16F628A al puerto serie de una PC, de modo que se observan los valores en la PC utilizando un programa básico de recepción de datos serie, tal como Hyperterminal (incluido en algunos sistemas operativos Windows, pero no en Vista, donde ofrecen una opción nueva llamada WinRS, que no he probado porque no uso Vista).

Para minimizar componentes, el microcontrolador PIC16F628A lo utilizo en el modo interno de generación de reloj (_INTRC_OSC_NOCLKOUT), que nos aporta una frecuencia de reloj de 4 MHz bastante estable y exacta con 5 Volts de alimentación en VDD.

A continuación se puede observar el circuito que he utilizado para estas pruebas.

Conexión del Sensor PING))) con el PIC16F628A y la PC

Programa en ASM

La sección que se ocupa de la lectura del sensor es muy simple: es la subrutina llamada "distancia". Dentro de esta rutina también está, al final, la parte que se ocupa de dar forma y enviar el resultado.

El resto de las líneas de programa son de inicialización y para comunicarse con la PC por la línea serie.

Para obtener una lectura, se pulsa la letra "d" en la pantalla del programa Hyperterminal (o en un utilitario similiar).

El resultado obtenido es un valor de 16 bits, la cuenta que se realizó dentro del lazo de espera hasta que el sensor detectó el eco. Este es un valor hexadecimal. Para verlo en centímetros, por ejemplo, se deberían hacer una serie de operaciones sobre el resultado. Sin embargo, para uso interno en un robot no es necesario: el número logrado es más que suficiente para manejarnos.

El programa utilizado es el que sigue:


;***********************************************************************************
; MANEJO DEL SENSOR PING))) DE PARALLAX - Programa Básico 1
; PRUEBA QUE ENTREGA DATOS A UNA PC POR EL PUERTO SERIAL O USB
; Por Eduardo J. Carletti, Robots Argentina, 2008
;***********************************************************************************

	list      p=16F628A	; definir procesador

#include <p16F628A.inc>		; definiciones de variables específicas del procesador

	ERRORLEVEL 1;-302	; para evitar los mensajes de cambio de
				; banco en el resultado del compilador

	_CONFIG   _CP_OFF & _WDT_OFF & _LVP_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF

;***** VARIABLES

	CBLOCK 0x20
	contador		; variable momentánea
	comando			; byte recibido por serie
	bajo			; byte bajo del resultado
	alto			; byte alto del resultado
	uni			; unidad
	dec			; decena
	cen			; centena
	datopr			; momentáneo
	ENDC

;***********************************************************************************

		org	0x000
		goto	principal

;***********************************************************************************
; INICIALIZA
;***********************************************************************************

principal	movlw b'00000111' 	; deshabilita comparadores. Esto es
		movwf CMCON		; algo importante en el PIC16F628A

		clrf PORTA		; inicia valor en puertos
		clrf PORTB		; inicia valor en puertos

		bsf STATUS,RP0		; apunta a banco 1

		movlw b'11111110' 	; PORTA 
		movwf	TRISA		; todas entradas excepto 0 que es salida

		MOVLW b'11111011' 	; PORTB 
		movwf	TRISB		; entradas, menos TB2 que es TX

;***********************************************************************************
; BAUD RATE para la comunicación serie y otras definiciones para USART
;***********************************************************************************
; Baud Rate = 9600, No Parity, 1 Stop Bit

	        movlw 0x19              ; 0x19=9600 bps (0x0C=19200 bps)
	        movwf SPBRG
	        movlw b'00100100'       ; BRGH en alto (2)
	        movwf TXSTA             ; habilita transmisión asincrónica, BRGH a 1
	        bcf STATUS,RP0          ; apunta a banco 0
	        movlw b'10010000'       ; habilita recepción asincrónica
	        movwf RCSTA

;***********************************************************************************
; MENSAJE DE BIENVENIDA
;***********************************************************************************

		call bienvenida        	; envía mensaje de bienvenida
		clrf comando		; limpia el byte de comando recibido

;***********************************************************************************
; LAZO PRINCIPAL
;***********************************************************************************

lazo		clrf comando
		btfsc PIR1,RCIF         ; (5) se fija si hay dato RS232
		call recibeRS232	; sí, hay

		; chequeo del comando
		movlw 'd'		; chequea comando "d"
		xorwf comando,w
		btfsc STATUS,Z
		call distancia		; mide la distancia

		goto lazo

;***********************************************************************************
; TABLA DE DATOS PARA MENSAJE
;***********************************************************************************

msgbienv	ADDWF PCL, F
		DT "Sensor PING))), Robots Argentina, 2008", 0x0D, 0x0A, 0x00

;***********************************************************************************
; SUBRUTINA DISTANCIA
;***********************************************************************************

distancia	clrf contador

		; pulso de arranque
		bsf PORTA,0		; pulso de arranque de unos uS
		nop
		nop
		nop
		bcf PORTA,0		; apaga pulso de arranque

		; cambia el pin del sensor a entrada
		bsf STATUS,RP0		; apunta a banco 1
		bsf TRISA,0		; PORTA bit0 a entrada
		bcf STATUS,RP0		; Apunta a banco 0

		; espera unos 750 uS para dar tiempo a la salida y regreso del pulso
		clrf bajo
atras		decf bajo,f
		bnz atras

		clrf alto		; prepara para el conteo en alto y bajo

		; espera contando el tiempo en alto y bajo, 
		; que serán los valores de salida
espera		incf bajo,f		; lo hacemos con un lazo simple
		btfsc STATUS,Z		; aunque se puede utilizar un timer
		incf alto,f
		btfsc PORTA,0
		goto espera

		; cambia el pin sensor a salida
		bsf STATUS,RP0		; apunta a banco 1
		bcf TRISA,0		; PORTA bit0 a salida
		bcf STATUS,RP0		; apunta a banco 0

		; muestra el valor en la PC
		movlw '='
		call enviaRS232
		movlw ' '
		call enviaRS232
		movf alto,w		; envía el byte alto
		call print_hexa
		movf bajo,w		; envía el byte bajo
		call print_hexa
		goto msgCR		; envía salto de línea y sale

;***********************************************************************************
; COMUNICACION RS232
;***********************************************************************************

recibeRS232	;recibir de PC
		movf RCREG,W            ; guarda comando en comando
		movwf comando		; guarda
		call enviaRS232		; eco a la PC
		return

enviaRS232	movwf TXREG             ; enviar dato en W
TransWt		bsf STATUS,RP0		; apunta a banco 1
WtHere		btfss TXSTA,TRMT        ; (1) transmision completa si es alto
		goto WtHere
		bcf STATUS,RP0          ; apunta a banco 0
		return

;***********************************************************************************
; MENSAJES
;***********************************************************************************

bienvenida	clrf contador		; limpia el puntero de caracter
b1		movf contador, W
		call msgbienv		; apunta el index hacia un caracter
		addlw 0			; se hace para chequear el flag Z
		btfsc STATUS, Z
		return			; el caracter fue 00, termina el mensaje
		call enviaRS232		; envía el caracter al puerto serie
		incf contador, F	; siguiente caracter
		goto b1

msgCR		movlw 0x0D		; caracter RETURN
		call enviaRS232		; envía el caracter al puerto serie
		movlw 0x0A		; caracter LINE FEED
		goto enviaRS232		; envía el caracter al puerto serie

;***********************************************************************************
; SUBRUTINA PARA MOSTRAR DATOS POR LINEA SERIE
;***********************************************************************************

print_hexa	movwf datopr
		swapf datopr,w		; toma parte alta
		call ph_pr		; imprime
		movf datopr,w		; toma parte baja
		call ph_pr		; imprime
		return
ph_pr		andlw 0x0F		; limpia lo que no sirve
		movwf uni		; la salva momentaneamente
		sublw 0x09		; hace literal - w
		btfsc STATUS,C
		goto ph_0a9		; es 0 a 9
		movf uni,w		; es mayor que 9, rescata valor
		addlw 0x37		;
		goto enviaRS232
ph_0a9		movf uni,w		; es 0 a 9, rescata valor
		addlw 0x30
		goto enviaRS232

		END


Bajar el programa en formato ASM (puede usar el botón derecho de su mouse)
Bajar el programa en formato HEX (puede usar el botón derecho de su mouse)

Algunas cosas que observé

  • La distancia mínima de detección, con estas constantes, es de unos 4 a 5 cm.
  • El sensor, colocado a 10 cm de altura sobre una mesa y apuntando en sentido horizontal, con los transductores uno al lado del otro (plaquetita base en posición horizontal, con el conector abajo), detecta la superficie de la mesa a unos 30 centímetros de distancia. Esto se debe a que la emisión del sensor Ping))) se abre unos grados, incluso en sentido vertical (aunque menos que en sentido horizontal).
  • El sensor se debe apuntar, entonces, hacia arriba, o colocarlo a un nivel más alto respecto al suelo.


Datos adicionales:

Al efecto de conocer más sobre el sensor, es conveniente leer nuestro artículo Medidores de distancia ultrasónicos - Sensores de ultrasonido, y las hojas de datos de este módulo en el sitio de Parallax.

Conexión entre el PIC16F628A y la PC

Recomiendo, para mayores detalles, ver nuestro artículo Prueba de conexión serie entre un PIC y una PC