A diferencia del artículo referente a la medida de distancias con el SRF04 o SRF05 en modo de funcionamiento 1, en esta ocasión se va a emplear el sensor de ultrasonidos SRF05 en el modo de funcionamiento 2, es decir, empleando el mismo pin como entrada del pulso de test y como salida para el pulso eco que nos dará la información de la distancia en función de su duración en tiempo.
Para conectar el sensor de ultrasonidos en este modo de funcionamiento, el pin de “modo” (sin conectar en SRF04 o SRF05 modo 1) debe llevarse a 0v. De esta forma, el pin empleado para dar el pulso de test será el que nos ofrezca igualmente el pulso ECO.
El proceso consiste en un ciclo que se repite cada vez que se toma una nueva medida.
Ahora, el programa continua esperando en la misma instrucción (While) en la que aguardaba a recibir el comienzo del pulso eco, hasta activarse de nuevo la interrupción, pero esta vez por la recepción del flanco de bajada. En ese mismo momento, volveremos a tomar el valor del registro CCP2. Además, memorizaremos que el pulso eco en curso ha finalizado y que por tanto, el próximo flanco será de subida por tratarse de un nuevo pulso eco.
Al indicar que el pulso eco ha finalizado, salimos del bucle while y se continúa con la ejecución del programa para calcular, a partir de los valores leídos del registro CCP, el valor de la distancia al objeto. Primero obteniendo los incrementos totales producidos en el contador del registro CCP2 (Timer 1) desde el flanco de subida hasta el de bajada.
Ahora, si multiplicamos este numero de incrementos por el tiempo (en microsegundos) que tarda en producirse cada uno de ellos, obtendremos el tiempo total del pulso eco. En este caso, al emplearse un oscilador para el PIC de 4 MHz, el tiempo de cada incremento es de 1uS, por lo que se multiplicará por 1.0
[+/-] Ver / Ocultar programa completo en C
En la animación se mestra el funcionamiento empleando el simulador del SRF05 para proteus.
Traducido al código de programación del PIC, primero
damos el pulso trigger o de disparo (mínimo 10 uS) con el pin RC1 (CCP2) como
salida y deshabilitada la interrupción...
disable_interrupts(INT_CCP2); //Deshabilitación
interrupción
modo comparación
trisc=0x00; //Puerto C todos los pines todo
salidas
BIT_TEST_ON; //Comienzo del
pulso de disparo
delay_us(10); //Tiempo del
pulso de disparo
BIT_TEST_OFF; //Fin del
pulso de disparo
...e inmediatamente después se vuelve a configurar dicho pin como entrada y
a habilitar la interrupción para detección de flanco...
trisc=0b00000010; //Pin RC1 como entrada para lectura eco
PIR2=0; //Reset del
flag de la interrupción
enable_interrupts(INT_CCP2); //Habilitación
interrupción para medida de pulso eco
.. y se espera la lectura del pulso eco...
while(NuevoEco==0)
{}
Como se ve, es imprescindible resetear el flag
de interrupción mediante su puesta a cero (PIR2=0).
Sino se hace, nos detectará interrupción por flanco de subida desde el mismo
momento de habilitar la interrupción.
Cuando,
esperando el flanco de subida del eco, se activa la interrupción, deberemos
guardar el valor que en ese momento se carga en el registro CCP2, y memorizar
que el próximo flanco será de bajada.
if(TipoFlanco==0){ //Si es flanco
de subida...
Contador_FS=CCP_2; //Guarda el
valor del registro CCP2
setup_ccp2(CCP_CAPTURE_FE); //Modo captura en flanco de bajada
TipoFlanco=1; //Próximo
flanco debe ser de bajada
}
Ahora, el programa continua esperando en la misma instrucción (While) en la que aguardaba a recibir el comienzo del pulso eco, hasta activarse de nuevo la interrupción, pero esta vez por la recepción del flanco de bajada. En ese mismo momento, volveremos a tomar el valor del registro CCP2. Además, memorizaremos que el pulso eco en curso ha finalizado y que por tanto, el próximo flanco será de subida por tratarse de un nuevo pulso eco.
Contador_FB=CCP_2; //Guarda el
valor del registro CCP2
setup_ccp2(CCP_CAPTURE_RE); //Modo captura
en flanco de subida
TipoFlanco=0; //Próximo flanco debe ser de subida
NuevoEco=1; //Pulso eco
actual finalizado.
Al indicar que el pulso eco ha finalizado, salimos del bucle while y se continúa con la ejecución del programa para calcular, a partir de los valores leídos del registro CCP, el valor de la distancia al objeto. Primero obteniendo los incrementos totales producidos en el contador del registro CCP2 (Timer 1) desde el flanco de subida hasta el de bajada.
Contador_FT=(Contador_FB-Contador_FS);
//Valor
entre flanco de subida y bajada.
Ahora, si multiplicamos este numero de incrementos por el tiempo (en microsegundos) que tarda en producirse cada uno de ellos, obtendremos el tiempo total del pulso eco. En este caso, al emplearse un oscilador para el PIC de 4 MHz, el tiempo de cada incremento es de 1uS, por lo que se multiplicará por 1.0
T_PulsoEco=Contador_FT*1.0; //Valor pulso leido en us de 100u a
25ms
Para saber el tiempo de
cada incremento del contador en función del oscilador empleado, partimos de
esta expresión:
T
= Tcm * Preescaler
Tcm
es el ciclo máquina y que corresponde con 4 ciclos del oscilador (4/Frec.Reloj)
Preescaler
es la escala empleada para el Timer1. En este caso Preescaler=1
T
= (4/4.000.000) * 1
De
donde obtenemos que el tiempo T es de 1uS para una frecuencia de reloj de 4MHz.
Para
obtener la distancia en centímetros en función del tiempo del eco, lo dividimos
por 58.3
Distancia = T_PulsoEco/58.3; //Distancia del obstáculo en cm
Esta
constante es siempre fija y nos da el resultado en cm. La proporciona el
fabricante del sensor en la hoja de características pero se podría obtener
considerando la velocidad del sonido en el aire (340m/s) y que éste recorre el
doble del espacio medido, puesto que dicho trayecto es de ida y vuelta.
Finalizado
el cálculo, volvemos a dejar el pin RC2 como salida y deshabilitamos
temporalmente la interrupción para que no nos detecte el propio pulso de
disparo. Y avisamos de que queda listo para una nueva media.
NuevoEco=0; //Listo para
recibir nuevo pulso eco
disable_interrupts(INT_CCP2);
trisc=0b00000000; //Pin RC1 como
salida para nuevo disparo
[+/-] Ver / Ocultar programa completo en C
En la animación se mestra el funcionamiento empleando el simulador del SRF05 para proteus.
Todos los archivos del proyecto en este enlace de descarga:
El proyecto contenido en el artículo ha sido diseñado con la versión v4.084 de CCS PIC C COMPILER
Última revisión del artículo: Agosto 2013
8 comentarios:
& EN QUE REGISTRO GUARDA LA MEDIDA EN DECIMAL CENTIMETROS?
Brxan, la variable "distancia" primero toma el tiempo del impulso recibido. Después divide ese valor para 58 para obtener el equivalente a cm. y lo vuelve a guardar en la misma variable "distancia".
Hola que tal me podría explicar como es que logra el tiempo exacto de pulso eco de 100u a 25 ms al multiplicar por 1.0 y dividir entre 58
Hola Axel.
Aquí se multiplica por 1 pero se podría evitar esa multiplicación en este caso concreto. Este valor depende de la frecuencia del cristal resonador que emplees. El valor del ccp se incrementa cada 4 ciclos de reloj. Considerando, que el periodo es el inverso de la frecuencia y que la frecuencia de reloj es 4 Mhz, el tiempo que tarda cada incremento del registro ccp será:
(1/4MHz) * 4 = 0,000001 seg.
Como el pulso eco recibido nos viene referenciado en microsegundos ese valor hay que convertirlo a microsegundos:
0,000001seg. * 1000000 = 1
La división por 58 es un factor que ofrece el fabricante del sensor para obtener la distancia en centímetros en función del tiempo del pulso en uS.
Excelente muchas gracias ahora entiendo la razón del por qué no me salía la medida ya que yo estoy trabajando con una frecuencia de reloj de 12 mhz
El programa corre y me marca las medidas en la pantalla pero no me sale el valor correcto, estoy usando un sensor diferente al propuesto por usted, tiene características similares y en teoría debería funcionar es el ping de parallax, ya utilicé el mismo oscilador pero difiere la medida no tendrá idea del por qué? Gracias de antemano saludos
Hola Axel.
Creo que ambos sensores trabajan igual. Debería funcionarte.
Sí la verdad no sé a qué se deba, intentaré cambiando el Pic creo que por ahí tengo otro.
Saludos
Publicar un comentario