Vous êtes sur la page 1sur 11

Todo lo que tienes que saber sobre: HC-SR04 Sensor

Ultrasnico>>

El HC-SR04 es un sensor ultrasnico de bajo costo que no slo puede detectar si un


objeto se presenta, como un sensor PIR (PassiveInfrared Sensor), sino que tambin
puede sentir y transmitir la distancia al objeto.
Tienen dos transductores, bsicamente, un altavoz y un micrfono.
Ofrece una excelente deteccin sin contacto (remoto) con elevada precisin y
lecturas estables en un formato fcil de usar.
El funcionamiento no se ve afectado por la luz solar o el material negro como
telmetros pticos (aunque acsticamente materiales suaves como telas pueden ser
difciles de detectar).
La velocidad del sonido en el aire (a una temperatura de 20 C) es de 343 m/s. (por
cada grado centgrado que sube la temperatura, la velocidad del sonido aumenta en
0,6 m/s)
Caractersticas tcnicas:

o
o
o
o

Los mdulos incluyen transmisores ultrasnicos, el receptor y el circuito de control.


Nmero de pines:

VCC: Alimentacin +5V (4.5V min 5.5V max)


TRIG: Trigger entrada (input) del sensor (TTL)
ECHO: Echo salida (output) del Sensor (TTL)
GND

Corriente de reposo: < 2mA


Corriente de trabajo: 15mA
ngulo de medicin: 30
ngulo de medicin efectivo: < 15
Deteccin de 2cm a 400cm o 1" a 13 pies (Sirve a ms de 4m, pero el fabricante no
garantiza una buena medicin).
Resolucin La precisin puede variar entre los 3mm o 0.3cm.
Dimensiones: 45mm x 20mm x 15mm
Frecuencia de trabajo: 40KHz

Distancia en cm (centmetros) = Tiempo medido en us x 0.017


Nota:

Tener en cuenta, que la distancia que recorre la onda es dos veces (x2) la distancia
del objeto, al usar: distancia recorrida = velocidad x tiempo transcurrido
Conecte el pin GND primero antes de suministrar alimentacin a VCC.
Por favor, asegrese de que la superficie del objeto a detectar debe tener al menos
0,5m para un mejor rendimiento.

Modo de funcionamiento:
Para hacer una lectura con el HC-SR04 basta con seguir estos pasos:
1) enviar un pulso de minimo 10us por el pin TRIG (disparo) para iniciar la lectura.
2) el sensor enviara 8 pulsos de ultrasonido y colocara su salida ECHO a alto, debes
detectar este evento e iniciar un "conteo de tiempo"
3) la salida ECHO se mantendra en alto hasta recibir el eco reflejado por el obstaculo a lo
cual el sensor pondra su pin ECHO a bajo, es decir, terminas de "contar el tiempo"
4) La distancia es proporcional a la duracion del pulso y puedes calcularla con las
siguientes formulas:
Distancia en CM = tiempo medido en us * 0.0167
Distancia en PULGADAS = tiempo medido en us * 0.00675
Nota: si la duracion del pulso es mayor a 30ms entonces asumes que no hay obstaculo.

EJEMPLO
Naturalmente usaremos un PIC para manejar el sensor, el compilador que utilizaremos es
PICC Compiler de CCS, el PIC utilizado puede ser cualquiera de tu preferencia, la cabecera
del programa no la pondre porque puedes usar el PIC que tu quieras, esa es la ventaja de
PICC, la portabilidad de codigo.
Empezamos, lo mejor desde mi punto de vista es disear una funcion que se encargara de la
lectura del sensor, esta funciondebera ir fuera y antes de la funcion MAIN. Lo primero es
definir los pines de nuestro sensor
#definetrig pin_c6
#define echo input(pin_c7)
Renombrar pines facilita el entendimiento posterior del codigo y ademas permite que
cambies los pines que vas a usar con simplemente modificar las lineas de codigo anteriores
en lugar de buscarlas y modificarlas dentro del codigo.
Muy bien, sabemos que el sensor puede llegar a medir hasta 500cm, por lo cual
nuestra funciontendra un DATO DE SALIDA del tipo longunsigned ya que
sobrepasa los 255 de una variable unsigned normal, asi que nuestra funcion
comienza con un int16:
int16mide_distancia(void){
int16 centimetros; // creamos una variable local para los centimetros medidos
//codigo para medicion de distancia...
ahora comienza la secuencia, si recuerdas habremos de enviar un pulso de
almenos 10us por el pin TRIG, yo le puse 50us para no fallar:
output_high(trig); // pulso de disparo
delay_us(50);
output_low(trig);
luego hay que esperar el pulso del pin echo que de inicio esta en cero, asi que usaremos un
while que espera mientras el pin echo este en cero y continuara cuando el pin este en 1:

while(echo==0); //espera flanco de subida


Muy facil verdad, ahora comienza la medicion de la distancia, usaremos un ciclo while que
incrementa cada 60us la variable centimetros mientras el pin echo sea = uno. Los 60us es el
tiempo aproximado que tarda en viajar el sonido 2cm osea 1cm ida y vuelta:
while(echo==1){
centimetros++;

delay_us(58);
}
Este while termina cuando el pin echo a ido a cero, es decir ya termino la lectura, asi que
terminamos con una demora de 50ms, tiempo sugerido por el datasheet del sensor y
retornaremos con el valor de los centimetros medidos:
delay_ms(50);
return(centimetros);
}// fin de la funcion "mide_distancia"

Nuestra funcion completa queda entonces de la siguiente manera:


#definetrig pin_c6
#define echo input(pin_c7)
int16mide_distancia(void){
int16 centimetros=0;
//pulso de disparo:
output_high(trig);
delay_us(50);
output_low(trig);
//espera flanco de subida por el pin echo
while(echo==0);
//comienza a contar centimetros hasta que pin echo sea cero
while(echo==1){
centimetros++;
delay_us(58);
}
//demora de seguridad y retorna con el valor de centimetros contados
delay_ms(50);
return(centimetros);
}
Recuerda que esta funcionhabra de ir afuera y antes de la funcionMAIN, un ejemplo de uso
seria asi: Hacer un medidor de distancia con sensor ultrasonico y un lcd que marque la
distancia en CM y tenga un led que enciende cuando hay una lectura valida y apaga cuando
no hay una lectura valida o no haya objeto:
//********************************************************************
// Cabecera del programa, depende del pic que uses
//********************************************************************

//********************************************************************
// Funcion de mide distancia de sensor ultrasnico
#definetrig pin_c6
#define echo input(pin_c7)
int16mide_distancia(void){
int16 centimetros=0;
//pulso de disparo:
output_high(trig);
delay_us(50);
output_low(trig);
//espera flanco de subida por el pin echo
while(echo==0);
//comienza a contar centimetros hasta que pin echo sea cero
while(echo==1){
centimetros++;
delay_us(58);
}
//demora de seguridad y retorna con el valor de centimetros contados
delay_ms(50);
return(centimetros);
}
//********************************************************************
// Funcion principal del programa
voidmain( void ){
int16 distancia;
int8 i;
lcd_init(); // inicializa lcd
while (true){ // lazo infinito
distancia=mide_distancia(); // AQUI USAMOS NUESTRA PODEROSA FUNCION!!!
lcd_gotoxy(1,1);
if(distancia>500){ // si lectura > 500cm entonces no es valida, osea no hay objeto
lcd_putc('\f'); // Borra LCD
printf(lcd_putc,"NO DETECTED!");
output_low(pin_c0);
}
else{ // si distancia fue < 500cm es una distancia valida y la imprime en LCD
printf(lcd_putc,"%03lucm ",distancia);
output_high(pin_c0);
}
}// cierra lazo infinito
}// cierra main
//********************************************************************

*************************************************************
COMENARIOS SOBRE EL PROGRAMA DE EJEMPLO:
Este codigo de ejemplo tiene sus ventajas y sus desventajas, la gran ventaja es que es todo
por software por lo que no consume recursos de TIMERS del PIC.
La desventaja es que el tiempo de medicion de centimetros puede variar ya que depende de
la velocidad del PIC que estas trabajando, esto se refleja en que mide cm mas grandes, esto
se resuelve disminuyendo el valor del DELAY_US(58); hasta el valor que se ajuste a los
cm reales.

OTRO EJEMPLO DE APLICACIN


Usando timers del pic
#include<16F877.h>
#FUSES XT,NOWDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP
#use delay(clock=4000000)
#include<lcd.c>
int16 distancia, tiempo;
#define trig pin_B1
#define echo pin_B0
#USE standard_io(b)
voidmain()
{
lcd_init();
printf(LCD_PUTC, "\f Iniciando.");
delay_ms(500);
printf(LCD_PUTC, "\f Iniciando..");
delay_ms(500);
printf(LCD_PUTC, "\f Iniciando...");
delay_ms(500);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
while(1)
{
output_high(trig);
delay_us(20);
output_low(trig);
while(!input(echo))
{}
set_timer1(0);
while(input(echo))
{}
tiempo=get_timer1();
distancia=(tiempo*10)/(58.0);

printf(LCD_PUTC, "\fTiempo :%Lu \nDistancia = %Lu",tiempo,distancia);


delay_ms(500);
}
}

MEDIDOR DE DISTANCIA
This works on PIC16F873A so should work on PIC16F877A
Don't forget to pull MCLR high
@ DEVICE PIC16F873A, HS_OSC 'Xtal OSC
@ DEVICE PIC16F873A, WDT_OFF'WDT off
@ DEVICE PIC16F873A, PWRT_ON 'Power-up timer on
@ DEVICE PIC16F873A, BOD_OFF 'Brown-out detect off
ADCON1 = %00000110 'All PORTA digital
define osc 4
TRISA = %00000010
TRISB = %00000000
PORTB = %00000000
wvar word
r var word
avar word
trvar PORTA.0 'Trig pin
ecvar PORTA.1 'Echo pin
PORTB = %11111111 'Flash LED on PORTB
pause 500 'to check PIC running
PORTB = %00000000
w=0
lowtr
Main :
hightr
pauseus 10
lowtr
pulsin ec,1,w
r = w/58
if r < 10 then
PORTB = %11111111
else
PORTB = %00000000
endif
pause 200
goto main
end
Oh!! Thanks IT work
But edit code r = w/58 >> r = ((w*10)/58)

MEDIDOR DE DISTANCIA RECTIFICADO


This works on PIC16F873A so should work on PIC16F877A
Don't forget to pull MCLR high
@ DEVICE PIC16F873A, HS_OSC 'Xtal OSC
@ DEVICE PIC16F873A, WDT_OFF'WDT off
@ DEVICE PIC16F873A, PWRT_ON 'Power-up timer on
@ DEVICE PIC16F873A, BOD_OFF 'Brown-out detect off
ADCON1 = %00000110
'All PORTA digital
DEFINE LCD_DREG PORTB
; define pines del LCD B4 a B7
DEFINE LCD_DBIT 4
; empezando desde el Puerto B4 hasta el B7
DEFINE LCD_RSREG PORTB
;define el puerto B para conectar el bit RS
DEFINE LCD_RSBIT 3
;este es el puerto B3
DEFINE LCD_EREG PORTB
;define el puerto B para conectar el bit Enable
DEFINE LCD_EBIT 2
;este es el puerto B2
TRISA = %00000010
TRISB = %00000000
PORTB = %00000000
w var word
r var word
trvar PORTA.0
ecvar PORTA.1
w=0
lowtr

'Trig pin
'Echo pin

inicio :
LCDOUT $FE,1,"DISTANCIA"
hightr
pauseus 10
lowtr
pulsin ec,1,w
r = w/58
LCDOUT $FE,$C0,# r, " cm"
IF r>30 THEN gosubalarma
pause 200
goto inicio
alarma:
SOUND porta.3, [100,10,50,10]
low porta.3
return
end

;genera tonos por el Puerto B.0

Oh!! Thanks IT work


But edit code r = w/58 >> r = ((w*10)/58)

USB

#include <18F2550.h>
#fuses
HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGE
N
#use delay(clock=48M)
#DEFINE USB_HID_DEVICE TRUE
#define USB_EP1_TX_ENABLE USB_ENABLE_INTERRUPT //turn on EP1 for IN
bulk/interrupt transfers
#define USB_EP1_TX_SIZE 8
#define USB_EP1_RX_ENABLE USB_ENABLE_INTERRUPT //turn on EP1 for OUT
bulk/interrupt transfers
#define USB_EP1_RX_SIZE 8
#include <pic18_usb.h>//Funciones de bajo nivel(hardware) para la serie PIC 18Fxx5x que
serviran en usb.c
#include <usb_desc_hid.h>//Aqui es donde van las descripciones de este dispositivo (como
lo reconocera windows)
#include <usb.c>
//libreria para el manejo del usb
#define LEDR PIN_C0 //Led rojo para la espera de la conexion USB
#define LEDV PIN_C1 //Led verde, se enciende cuando el USB esta conectado
#define LED_ON output_low
#define LED_OFF output_high
int8 Salida[8];
int8 Entrada[8];
void main() {
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
set_tris_b(0x00);
output_b(0x00);
LED_ON(LEDR);
LED_OFF(LEDV);
usb_init();
usb_task(); //Monitorea el estado de la coneccion conectandose y desconectandose
automaticamente
usb_wait_for_enumeration(); //espera infinitamente hasta que el dispositivo fue
enumerado
LED_ON(LEDV);
LED_OFF(LEDR);
while (TRUE)
{
usb_task();

if (usb_enumerated())
{
Salida[0]=read_adc();
usb_put_packet(1, Salida,1 , USB_DTS_TOGGLE);
if (usb_kbhit(1))
{
usb_get_packet(1, Entrada, 1);
if (Entrada[0]==1)
{
LED_ON(PIN_B0);
}
else
LED_OFF(PIN_B0);
}
}
}
}

Vous aimerez peut-être aussi