sábado, 5 de febrero de 2011

Sensor de Distancia con Sensor de Ultrasonido SFR05

A quien le pueda interesar...

Bueno siendo esta mi primera entrada de este blogg quiero transmitir los conocimientos que he adquirido mientras realizo un proyecto. Cual es la idea??, quiero hacer un sensor de nivel para un tanque y realizar pruebas de control con él, pero primero es necesario la construcción del sensor y luego pretendo hacer el elemento final de control que es una servo-válvula.

El sensor que estoy trabajando es el SFR05, por qué??, la verdad fue el que primero que vi en la tienda de electrónica de mi ciudad, sin saber como era el funcionamiento me metí de lleno y empece a trabajarlo. El cuento es muy sencillo para quienes hayan tenido un acercamiento con los microcontroladores y los sistemas digitales.




Este señor de la imagen es el sujeto que me puso a pensar y a investigar, el SFR05 esta compuesto por un emisor que envía una onda y en el momento en que choca con algún objeto u obstáculo, esta retorna inmediatamente y la recoge el receptor, el tiempo que demora esta onda en regresar es proporcional a la distancia.





El sensor tiene 5 pines en ambos lados, uno de ellos es para la programacion del micro que posee el impreso, esos no se deben tocar, los otros 5 son los que vamos a cablear, existen dos modos de conexionado, uno en que la comunicación se realiza a una sola linea y la otra es por separado, me explico, el sensor debe recibir un pulso por lo menos de 10µs al cual llamaremos DISPARO, el sensor convierte el disparo en una onda y la envía, luego se debe medir el tiempo en que el sensor pone activa la salida, esto se llama el ECO.

Para la conexión en modo 1, el disparo y el eco son pines separados, pin3 y pin2 respectivamente, pin1 es la alimentación a 5v, pin5 la tierra 0v, y el pin4 no se conecta. 
Modo de conexión 1, Disparo y Eco por lineas separadas.
Si este ultimo es conectado a tierra, el sensor interpreta que es conectado en el modo 2, que es donde el disparo y el eco comparten el pin3. 


El modo en el que estoy trabajando es en el primero, por facilidad en el control con el micro, ahora, hay varias cosas que se deben tener en cuenta:
  1. Es necesario que el disparo sea de por lo menos de 10µs como se menciono anteriormente.
  2. La medición de la duración del eco determina en parte la precisión del sensor.
  3. Se debe esperar por lo menos 20ms para realizar otra medición, esto para asegurar la estabilidad del sensor.
Ahora, existe un factor externo que muy pocos tienen en cuenta si lo que quieren es precisión y exactitud, es la temperatura ambiente, que pasa, como la onda sonora que se emite viaja por el ambiente a la velocidad del sonido, la temperatura influye directamente en la propagación de este, un ambiente caliente hace que aumente la frecuencia con que interactuan las partículas que transportan las vibraciones, esta actividad hace que aumente la velocidad. La siguiente ecuacion va a determina el factor de conversión entre el tiempo de eco y la distancia que vamos a obtener.


Para mi caso, en la ciudad de Bello, Antioquia, la temperatura promedio es de 26°C, entonces la velocidad del sonido a 26°C es de 347.1 m/s o 347100mm/s para tomarlo como factor de resolución le sacamos el inverso 2.881µs/mm. Ahora como la onda sonora fue enviada y retornada la velocidad del sonido es el doble 5.762µs/mm, la precisión entonces se espera que sea milimétrica.

Hacer la programación fue lo que mas se me dificulto porque se requiere que la medición del tiempo sea con la mayor exactitud posible, el micro que utilizo es el 16f88, este es el micro con el que mejor me entiendo, hice varias pruebas para medir el eco una de ellas fue simplemente una interrupción por RB0 pero arrojo datos muy imprecisos. Investigando encontre que los microcontroladores tienen varios modulos de interrupciones: Timer0 (RB0,RB0 a Rb4...), Timer1(temporizador a 16bits)  y Timer2(pwm). Como la cuenta del tiempo varia entre 100µs(1.7cm) y 25ms(431cm) en milimetros el numero es muy grande, por eso utilice el Timer1.

A continuación expongo el codigo en CCS:


#INCLUDE <16F88.H>
#USE DELAY(CLOCK=4000000)
#DEFINE LCD_ENABLE_PIN PIN_B1
#DEFINE LCD_RS_PIN PIN_B2
#DEFINE LCD_RW_PIN PIN_B3
#DEFINE LCD_DATA0 PIN_B4
#DEFINE LCD_DATA1 PIN_B5
#DEFINE LCD_DATA2 PIN_B6
#DEFINE LCD_DATA3 PIN_B7
#INCLUDE <LCD.C>
#FUSES XT,MCLR,NOPROTECT,NOWDT,NOBROWNOUT,NOLVP,WRT
#BYTE PORTB=6
#BYTE PORTA=5
#DEFINE ECO PIN_A0
#DEFINE DISPARO PIN_A1

FLOAT DISTANCIA(VOID)//funcion que mide la distancia por TIMER1
{
LONG VALOR_MEDIDO;//variable de 16bits
FLOAT DISTANCIA_MM;//variable de 32bits
OUTPUT_HIGH(DISPARO);//envio el disparo
DELAY_US(20);//espero 20us 
OUTPUT_LOW(DISPARO);//pongo de nuevo en cero al disparon
WHILE(!INPUT_STATE(ECO)){};//se queda preguntando por el inicio del eco
SET_TIMER1(0);//inicio el temporizador TIMER1, lleva la cuenta del tiempo incrementando cada 1us
WHILE(INPUT_STATE(ECO)){};//pregunto si termina el eco 
VALOR_MEDIDO=GET_TIMER1();//cuando finaliza, obtengo el dato del TIMER1 que equivale al tiempo
DELAY_MS(30);//espero 30ms para una nueva medida
DISTANCIA_MM=(VALOR_MEDIDO/5.762);//Hago la conversion y tengo la distacia en mm.
RETURN DISTANCIA_MM;
}


VOID MAIN()
{
FLOAT DIST_MM=0;
BYTE J;
SETUP_TIMER_1(T1_INTERNAL|T1_DIV_BY_1);//establezco el TIMER1
SET_TRIS_B(0); //defino puerto b como salidas para el LCD
SET_TRIS_A(0X01);//pongo RA0 como entrada del eco
PORTA=0;//inicializo puerto a
LCD_INIT();//inicializo lcd
J=16;
   WHILE(J>0)
   {
   LCD_PUTC("\f");
   LCD_GOTOXY(J,1);
   LCD_PUTC("   SENSOR DE   ");
   LCD_GOTOXY(J,2);
   LCD_PUTC("DISTANCIA SFR_05");
   DELAY_MS(150);
   J--;
   }
   DELAY_MS(1000);
   J=16;
   WHILE(J>0)
   {
   LCD_PUTC("\f");
   LCD_GOTOXY(J,1);
   LCD_PUTC("ING. EN CONTROL ");
   LCD_GOTOXY(J,2);
   LCD_PUTC("  ANDRES MAYA Q ");
   DELAY_MS(150);
   J--;
   }
   DELAY_MS(1000);
   LCD_PUTC("\f");
   LCD_GOTOXY(1,1);
   LCD_PUTC("   DISTANCIA    ");
   WHILE(TRUE)
   {
   DIST_MM=DISTANCIA();
   IF(DIST_MM<=2.0)
  {
   LCD_GOTOXY(1,1);
   LCD_PUTC(" EL OBJETO ESTA ");
   LCD_GOTOXY(1,2);
   LCD_PUTC("   MUY CERCANO  ");
   }
   ELSE
   {
   LCD_GOTOXY(1,1);
   LCD_PUTC("   DISTANCIA    ");
   LCD_GOTOXY(1,2);
   PRINTF(LCD_PUTC,"    %f mm   ",DIST_MM);
   DELAY_MS(100);
   }
   }
   }

Muy bien ahora muestro el vídeo con el sensor funcionando correctamente:


Esta es la primera versión, ahora estoy probando para que el sensor tenga la opción de que también cumpla como sensor de nivel y se auto-sintonice, ademas como los sensores industriales, tengan una salida analógica, en mi próxima entrada haré una conversión Digital-Análoga por medio de un PWM y un filtro pasa bajos.

Espero que a alguien le pueda servir esta pequeña información, y pueda salir de dudas...







9 comentarios:

  1. Hola, me gustaría saber qué IDE (MPLAB, ccs pcwh) utilizaste?
    Y si tienes un esquemático del montaje.

    ResponderEliminar
  2. buenas, gracias por ver mi blog, el programa esta hecho en PICC SSC, pues normal, el programa me crea el proyecto y con él mismo me comunico con el MPlab y lo programo uso el pickit3 y el micro 16f88,ahora, a lo que refiere al esquematico te puedo pasar la nueva version del sensor, que pronto lo posteare, y es con salida de 0 a 5v proporcional a la distancia que sensa el sfr05, y eso lo tengo en el proteus, ahora estoy provando ya montado en la PCB, regalame tu correo y te facilito la info

    ResponderEliminar
    Respuestas
    1. podras enviarmelo ami correo. emmanuel-marin98@hotmail.com

      Eliminar
  3. Hola! mira estoy trabajando haciendo un especie de robot, para eso tengo 4 sensores srf05, uno lo ubico adelante, otro atras, otro a derecha y otro a izquierda, quiero programar el pic de tal manera q si por ejemplo el robot va hacia adelante se active el sensor del frente, si gira a derecha se active el de derecha, pero no se como hacer esto ya que este sensor tiene emisor y receptor, please ayudame si sabes porfaaa.
    (Somos vecinos, yo tambien vivo en Bello :P)

    ResponderEliminar
  4. HOLA, SI ME VAS A RESPONDER A LA ANTERIOR PREGUNTA RESPONDEME PLEASE AL CORREO julian.andres.ml@gmail.com (todo en minuscula), es q ocurrio un pequeño error y ese correo q aparece de seminario es un correo de la universidad, please que pena contigo, gracias.

    ResponderEliminar
  5. Hola!! yo he estado haciendo un programa que me calcule la distancia, utilizando un SRF05 y no he podido, quise probar tu programa para mirar si me funcionaba y monte el circuito con un pic 16F873A y con el led, de modo tal que cuando la distancia fuera menor que 5cm se me prendiera el led, pero no me funcionó, me podrias decir que cristal usaste y como podria yo cambiar tu programa para poder usar ese pic y un led. Gracias!

    ResponderEliminar
  6. MUCHAS GRACIAS.... en un vehículo un carrito de juguete sabes como se podría implementar??

    ResponderEliminar
  7. hola, y como haria para programar 2 ó 3 modulos en un solo pic he intentado usando el mismo timer1 para 2 modulos pero no se puede, tambien he intentado un timer para cada modulo y no tuve exito, haber si podrian darme una ayuda.

    ResponderEliminar