Medición HC-SR04 con el PIC16F
Hola como estas, soy Pablo y te doy la bienvenida a mi blog dedicado al mundo de la electrónica digital, y en especial a la programación de microcontroladores PIC, el contenido publicado en este sitio tiene un propósito educativo que pueda ser de ayuda en tu formación, por lo estaré atento a cualquier consulta o critica constructiva relacionada con esta publicación. Al final encontraras mis datos de contacto.
Hoy veremos como utilizar el modulo HC-SR04 que es bastante común verlos en proyectos de robótica con microcontroladores. El objetivo que buscaremos lograr sera el de medir la distancia que desde el origen donde se encuentra el sensor al objeto que esta de frente, para lo cual usaremos un microcontrolador PIC16F887
La
programación del ejemplo se realizara utilizando el software de diseño MPLABX y el compilador de lenguaje C para PIC XC8 ambos
disponibles en la pagina de microchip de forma gratuita. Aquí dejo los enlaces de las
versiones utilizadas para nuestro ejemplo: <<MPLABX v6.20>> <<XC8 v2.45>>
Mencionar
también que es necesario contar con conocimientos mínimos sobre
programación en lenguaje C y el uso de microcontroladores PIC16.
Introducción al Tema
El HC-SR04 es un sensor de distancia que utiliza ondas de ultrasonido para determinar la distancia de un objeto, lo destacable de este sensor es su bajo costo, tamaño y consumo de energía, y que gracias a su buena precisión lo convierten en uno de los sensores mas utilizados en diversos proyectos electrónicos, como vera en la figura 1, el modulo consta de dos transductores, un emisor, un receptor y la electrónica necesaria para su operación.
Fig1. Sensor ultrasónico HC-SR04
Revisando la hoja de dato de este modulo, describiremos los aspectos mas importantes para su implementación:
- El voltaje de operación es 5V, aunque existen versiones que trabajan con menor voltaje, en cuanto al consumo es alrededor unos 15mA.
- Su rango de medición va de 2 — 400 centímetros, aunque en algunas especificaciones indica que puede llegar a los 500 centímetros.
- En rango de apertura para detectar los objetos es mas o menos 30 grados.
Fig1. Funcionamiento del modulo HC-SR04 |
Para que el Microcontrolador de inicio al proceso de una medición con este sensor, primero generara un pulso de disparo en TRIG, el ancho de este pulso deberá ser al menos 10us, cuando el sensor recibe el pulso, automáticamente emitirá al espacio ocho tonos pulsantes de 40Khz que no son audibles, entonces los tonos en su recorrido por el espacio podrán reflejarse en cualquier obstáculo produciendo un eco que retornara al sensor. La señal que retorna al sensor servirá para determinar a que distancia se encuentra el objeto reflectante, esto se consigue calculando el tiempo de retardo desde la emisión del tono hasta la recepción del eco. El sensor provee a través de la salida ECHO, la duración del retardo, entonces el microcontrolador solo tiene que medir el ancho de pulso que tiene la salida del sensor y calcular la distancia considerando que los tonos emitido viajan por el espacio a la velocidad del sonido (343 m/s).
La referencia que se tiene con relación al ancho de pulso es de 1 centímetro por cada 29 microsegundos (343 m/s), pero considerando que los tonos cubren dos veces la distancia(trayecto de ida y trayecto de vuelta), podemos deducir que la distancia sera 1cm por cada 28us.
Esquema del Circuito
El modulo no requiere elementos adicionales, así que solo se necesita alimentarlo con 5V y conectar el pin ECHO del sensor al un pin de entrada en el PIC (pin RB4), luego pin TRIG del sensor a un pin de salida del PIC (pin RB3), siguiendo la distribución de pines que muestra la figura 2.
Adicionalmente se utilizara un diodo LED conectado al pin de salida RE2, mismo que servirá para indicar el funcionamiento normal del programa mediante un destello cada segundo.
La figura 3, muestra el esquema simplificado del circuito que utilizaremos para realizar unas pruebas de medición, el esquema posibilita la simulación pero carece de las conexiones de alimentación y elementos adicionales para un montaje real.
Programación de medición
Ahora describiré el programa que servirá para medir la distancia en centímetros, donde la frecuencia del oscilador es Fosc = 8Mhz, para ser mas práctico dentro del mismo código se comenta la función de cada linea explicando y al final explicare las secciones que conllevan a manejar el sensor.
El programa hace uso de un temporizador utilizando el modulo TMR1, con el cual se desea contar los microsegundos que pasan cuando se recibe el pulso de retorno. Si quieres conocer con mayor detalle como funcione este recurso del microcontrolador PIC, te recomiendo revises esta publicación.
#pragma config FOSC = INTRC_NOCLKOUT, WDTE = OFF, LVP = OFF
#include <xc.h>
#include <stdio.h>
#define _XTAL_FREQ 8000000 //Definición del oscilador
#define TRIGpin PORTBbits.RB3//Salida del disparo
#define ECHOpin PORTBbits.RB4 //Entrada del eco
#define LEDpin PORTEbits.RE2 //Salida del led
uint16_t distcm = 0; //Variable de distancia en cm
uint16_t SR04Getval(void); //Función para leer sensor
void setup(void); //Procedimiento de inicialización
void main(void)
{
setup(); //Inicializa el PIC
while(1)
{
distcm = SR04Getval(); //Lectura distancia
printf("Distancia cm:%u\r\n", distcm); //Envía mensaje
__delay_ms(500); //Espera medio segundo
PORTEbits.RE2 = 0; //Apaga el led
__delay_ms(500); //Espera medio segundo
PORTEbits.RE2 = 1; //Enciende el led
}
}
void setup(void) //Procedimiento de inicialización
{
OSCCONbits.IRCF = 0b111; //Fosc=8MHz Tcy=0.5uS
while(OSCCONbits.HTS == 0){};
ANSEL = 0; //AN0-AN7 en modo digital
ANSELH = 0; //AN8-AN12 en modo digital
TRISEbits.TRISE2 = 0; //Pin RE2 como salida LED
TRISBbits.TRISB3 = 0; //Pin RB3 como salida TRIG
TRISBbits.TRISB4 = 1; //Pin RB3 como entrada ECHO
OPTION_REGbits.nRBPU = 0; //Activa pull-ups
TRIGpin = 0; //Pin TRIG en nivel 0
/* CONFIGURA TIMER1 1uS Fosc=8MHz */
T1CONbits.TMR1CS = 0; //Modo temporizador
T1CONbits.T1CKPS = 0b01; //Ajuste pre-escala 1:2
/* CONFIGURA USART A 9600 BPS 8MHz*/
TXSTAbits.BRGH = 1; //Alta del Generador
TXSTAbits.TXEN = 1; //Activa el transmisor
RCSTAbits.SPEN = 1; //Habilita el modulo USART
SPBRG = 51; //Formula [8MHz/(16 * 9600)] - 1
}
uint16_t SR04Getval(void) //Función para lectura del sensor
{
uint16_t value; //Valor temporal
TRIGpin = 1; //Nivel alto para inicio de pulso
_delay(20); //Espera de pulso 10us
TRIGpin = 0; //Nivel bajo para fin de pulso
while(ECHOpin == 0); //Espera inicio del ECO
TMR1H = 0x00; //Reinicia contador
TMR1L = 0x00;
PIR1bits.TMR1IF = 0; //Limpia bandera
T1CONbits.TMR1ON = 1; //Inicia temporizador
while(ECHOpin == 1) //Espera fin del ECO
{
if(PIR1bits.TMR1IF) //Si hay desbordamiento
break; //Sale del bucle
}
T1CONbits.TMR1ON = 0; //Apaga temporizador
value = TMR1L; //Recupera valor del tiempo
value |= (uint16_t) TMR1H << 8;
return value/58; //vs= 343m/s => 1cm/29uS
}
void putch(char byte) //Procedimiento salida serial
{
while(PIR1bits.TXIF == 0) {};
TXREG = byte;
}
El programa principal luego de llevar a cabo la configuracion inicial llamando al procedimiento setup, ingresa en un bucle indefinido donde se ejecuta de manera secuencial, la lectura del sensor llamando a la función SR04Getval, esta función retorna un numero que representa la distancia medida en centímetros., luego se envía un mensaje formateado con el valor de distancia a través del puerto serial, finalmente se ejecuta un par de esperas de medio segundo para encender y apagar el LED,#include <xc.h>
#include <stdio.h>
#define _XTAL_FREQ 8000000 //Definición del oscilador
#define TRIGpin PORTBbits.RB3//Salida del disparo
#define ECHOpin PORTBbits.RB4 //Entrada del eco
#define LEDpin PORTEbits.RE2 //Salida del led
uint16_t distcm = 0; //Variable de distancia en cm
uint16_t SR04Getval(void); //Función para leer sensor
void setup(void); //Procedimiento de inicialización
void main(void)
{
setup(); //Inicializa el PIC
while(1)
{
distcm = SR04Getval(); //Lectura distancia
printf("Distancia cm:%u\r\n", distcm); //Envía mensaje
__delay_ms(500); //Espera medio segundo
PORTEbits.RE2 = 0; //Apaga el led
__delay_ms(500); //Espera medio segundo
PORTEbits.RE2 = 1; //Enciende el led
}
}
void setup(void) //Procedimiento de inicialización
{
OSCCONbits.IRCF = 0b111; //Fosc=8MHz Tcy=0.5uS
while(OSCCONbits.HTS == 0){};
ANSEL = 0; //AN0-AN7 en modo digital
ANSELH = 0; //AN8-AN12 en modo digital
TRISEbits.TRISE2 = 0; //Pin RE2 como salida LED
TRISBbits.TRISB3 = 0; //Pin RB3 como salida TRIG
TRISBbits.TRISB4 = 1; //Pin RB3 como entrada ECHO
OPTION_REGbits.nRBPU = 0; //Activa pull-ups
TRIGpin = 0; //Pin TRIG en nivel 0
/* CONFIGURA TIMER1 1uS Fosc=8MHz */
T1CONbits.TMR1CS = 0; //Modo temporizador
T1CONbits.T1CKPS = 0b01; //Ajuste pre-escala 1:2
/* CONFIGURA USART A 9600 BPS 8MHz*/
TXSTAbits.BRGH = 1; //Alta del Generador
TXSTAbits.TXEN = 1; //Activa el transmisor
RCSTAbits.SPEN = 1; //Habilita el modulo USART
SPBRG = 51; //Formula [8MHz/(16 * 9600)] - 1
}
uint16_t SR04Getval(void) //Función para lectura del sensor
{
uint16_t value; //Valor temporal
TRIGpin = 1; //Nivel alto para inicio de pulso
_delay(20); //Espera de pulso 10us
TRIGpin = 0; //Nivel bajo para fin de pulso
while(ECHOpin == 0); //Espera inicio del ECO
TMR1H = 0x00; //Reinicia contador
TMR1L = 0x00;
PIR1bits.TMR1IF = 0; //Limpia bandera
T1CONbits.TMR1ON = 1; //Inicia temporizador
while(ECHOpin == 1) //Espera fin del ECO
{
if(PIR1bits.TMR1IF) //Si hay desbordamiento
break; //Sale del bucle
}
T1CONbits.TMR1ON = 0; //Apaga temporizador
value = TMR1L; //Recupera valor del tiempo
value |= (uint16_t) TMR1H << 8;
return value/58; //vs= 343m/s => 1cm/29uS
}
void putch(char byte) //Procedimiento salida serial
{
while(PIR1bits.TXIF == 0) {};
TXREG = byte;
}
Este ejemplo es una forma muy sencilla de leer el sensor, además los retardos provocados con el procedimiento __delay_ms generan un tiempo muerto o inactivo que deberia evitarse en cualquier sistema secuencial, de la misma manera si revisados la codificación de la función SR04Getval, observaremos que su ejecución puede conllevar a un proceso bloqueante, debido a las sentencias condicionales while de carácter indefinido, por ejemplo si retira la conexión en la linea ECO, el programa quedara colgado, y esto también representa una condición indeseable en cualquier sistema electrónico.
Una mejor solución para llevar a cabo la lectura de este sensor, de manera segura y evitando las condiciones que pueden darse en el programa anterior, es utilizar interrupciones, donde se pueden aplicar eventos para la detección de flanco, cambios de estado o eventos propios del contador. En nuestro caso veremos un ejemplo utilizando la interrupción por cambio de estado.
Programa de medición con interrupción
Con el propósito de evitar procesos bloqueantes dentro del programa, en este ejemplo se hace uso de las interrupciones del modulo temporizador TMR0 y el cambio de estado del PORTB. La codificación en si utiliza una técnica de programación por estados, si
quieres conocer mas detalles al respecto, te recomiendo revises antes de continuar, la siguiente
publicación.
Además este programa podría adaptarse con facilidad para manejar mas de un sensor de distancia, dado que en este PIC, la interrupción por cambio de estado puede aplicarse a todos los pines del PORTB.
#pragma config FOSC = INTRC_NOCLKOUT, WDTE = OFF, LVP = OFF
#include <xc.h>
#include <stdio.h>
#define TRIGpin PORTBbits.RB3 //Salida del disparo
#define ECHOpin PORTBbits.RB4 //Entrada del eco
#define LEDpin PORTEbits.RE2 //Salida del led
uint16_t distcm = 0; //Variable de distancia en cm
volatile __bit tick1ms = 0, distOK, catchT1; //Banderas
void taskLED(void); //Tarea para destellar LED
void taskSR04(void);//Tarea para leer sensor
void setup(void); //Procedimiento de inicialización
void __interrupt() isr(void) //Rutina ISR
{
uint8_t res;
if(INTCONbits.T0IF) //Evento de tiempo 0.0001s
{
INTCONbits.T0IF = 0; //Limpia bandera
TMR0 += 131; //Reinicia contador T0
tick1ms = 1; //Activa bandera
}
if(INTCONbits.RBIF) //Evento de cambio en pin RB4
{
res = PORTB; //Registrar valor PORTB
INTCONbits.RBIF = 0;//Limpia condición
T1CONbits.TMR1ON = 0; //Para el temporizador T1
catchT1 = 1; //Activa Bandera
}
}
void main(void)
{
setup(); //Inicializa el PIC
while(1)
{
if(tick1ms) //Valida cada milisegundo
{
tick1ms = 0; //Limpia bandera
taskLED(); //Tarea para destellar led
taskSR04(); //Tarea para lectura de sensor
if(distOK) //Si hay distancia calculada
{
distOK = 0; //Limpia bandera
printf("Distancia cm:%u\r\n", distcm);//Enviar mensaje
}
}
}
}
void setup(void)
{
OSCCONbits.IRCF = 0b111; //Fosc=8MHz Tcy=0.5uS
while(OSCCONbits.HTS == 0){};
ANSEL = 0; //AN0-AN7 en modo digital
ANSELH = 0; //AN8-AN12 en modo digital
TRISEbits.TRISE2 = 0; //Pin RE2 como salida LED
TRISBbits.TRISB3 = 0; //Pin RB3 como salida TRIG
TRISBbits.TRISB4 = 1; //Pin RB3 como entrada ECHO
OPTION_REGbits.nRBPU = 0; //Activa pull-ups
TRIGpin = 0; //Pin TRIG en nivel 0
/* CONFIGURA LA INT POR CAMBIO*/
IOCBbits.IOCB4 = 1; //Activa Interrupción por cambio en RB4
/* CONFIGURACION TIMER0 1MS Fosc=8Mhz*/
OPTION_REGbits.T0CS = 0;//Modo Termporizador
OPTION_REGbits.PSA = 0; //Con prescala
OPTION_REGbits.PS = 0b011; //Prescala 1:16
TMR0 = 131; //256-[(time*Fosc)/(pre*4)] time=0.001 seg
INTCONbits.T0IF = 0; //Limpia bandera
INTCONbits.T0IE = 1; //Activa interrupción del TMR0
/* CONFIGURA TIMER1 1uS Fosc=8MHz */
T1CONbits.TMR1CS = 0; //Modo temporizador
T1CONbits.T1CKPS = 0b01; //Ajuste pre-escala 1:2
/* CONFIGURA USART A 9600 BPS 8MHz*/
TXSTAbits.BRGH = 1; //Alta del Generador
TXSTAbits.TXEN = 1; //Activa el transmisor
RCSTAbits.SPEN = 1; //Habilita el modulo USART
SPBRG = 51; //Formula [8MHz/(16 * 9600)] - 1
INTCONbits.GIE = 1; //Habilita las Interrupciones
}
void taskSR04(void) //Tarea para lectura de sensor, cada 1ms
{
static uint8_t state = 0;
static uint16_t cnt = 0;
uint16_t value;
cnt++; //Incrementa contador
switch(state)
{
case 0: //Estado para enviar disparo
value = PORTB; //Registra condición
INTCONbits.RBIF = 0;
INTCONbits.RBIE = 1; //Activa interrupción RB
T1CONbits.TMR1ON = 0;
TMR1L = 0; //Reinicia temporizador T1
TMR1H = 0;
PIR1bits.TMR1IF = 0;
T1CONbits.TMR1ON = 1; //Arranca T1
catchT1 = 0; //Limpia bandera
TRIGpin = 1; //Inicio del disparo TRIG
_delay(20); //Tiempo del pulso 0.5u x 20 = 10u
TRIGpin = 0; //Fin del disparo TRIG
cnt = 0; //Reinicia contador
state++; //Siguiente estado
break;
case 1: //Estado de espera inicio del pulso ECO
if(catchT1) //Flanco POS detectado
{
catchT1 = 0; //Limpia bandera
T1CONbits.TMR1ON = 0; //Para contador
TMR1L = 0; //Reinicia contado
TMR1H = 0;
PIR1bits.TMR1IF = 0;
T1CONbits.TMR1ON = 1; //Arranca el contador
state++; //Siguiente estado
}
if(PIR1bits.TMR1IF) state = 3;//Limite de tiempo > a 65ms
break;
case 2: //Estado de espera final del pulso ECO
if(catchT1) //Flanco NEG detectado
{
catchT1 = 0; //Limpia bandera
INTCONbits.RBIE = 0; //Desactiva interrupción RB
value = TMR1L; //Recupera valor del contador us
value |= (uint16_t) (TMR1H << 8);
distcm = value/58U; //1cm/30uS solo ida
distOK = 1;//Activa bandera
state++; //Siguiente Estado
}
if(PIR1bits.TMR1IF) state = 3; //Limite de tiempo > a 65ms
break;
case 3: //Estado para espera de repetición
if(cnt >= 999)
state = 0; //Reinicia maquina cada 0.5s
break;
}
}
void taskLED(void) //Destella led ciclo 1ms
{
static uint16_t tcnt = 0;
if(tcnt++ > 999)
{
tcnt = 0;
LEDpin = 1;
}
if(tcnt == 200) LEDpin = 0;
}
void putch(char byte)
{
while(PIR1bits.TXIF == 0) {};
TXREG = byte;
}
#include <xc.h>
#include <stdio.h>
#define TRIGpin PORTBbits.RB3 //Salida del disparo
#define ECHOpin PORTBbits.RB4 //Entrada del eco
#define LEDpin PORTEbits.RE2 //Salida del led
uint16_t distcm = 0; //Variable de distancia en cm
volatile __bit tick1ms = 0, distOK, catchT1; //Banderas
void taskLED(void); //Tarea para destellar LED
void taskSR04(void);//Tarea para leer sensor
void setup(void); //Procedimiento de inicialización
void __interrupt() isr(void) //Rutina ISR
{
uint8_t res;
if(INTCONbits.T0IF) //Evento de tiempo 0.0001s
{
INTCONbits.T0IF = 0; //Limpia bandera
TMR0 += 131; //Reinicia contador T0
tick1ms = 1; //Activa bandera
}
if(INTCONbits.RBIF) //Evento de cambio en pin RB4
{
res = PORTB; //Registrar valor PORTB
INTCONbits.RBIF = 0;//Limpia condición
T1CONbits.TMR1ON = 0; //Para el temporizador T1
catchT1 = 1; //Activa Bandera
}
}
void main(void)
{
setup(); //Inicializa el PIC
while(1)
{
if(tick1ms) //Valida cada milisegundo
{
tick1ms = 0; //Limpia bandera
taskLED(); //Tarea para destellar led
taskSR04(); //Tarea para lectura de sensor
if(distOK) //Si hay distancia calculada
{
distOK = 0; //Limpia bandera
printf("Distancia cm:%u\r\n", distcm);//Enviar mensaje
}
}
}
}
void setup(void)
{
OSCCONbits.IRCF = 0b111; //Fosc=8MHz Tcy=0.5uS
while(OSCCONbits.HTS == 0){};
ANSEL = 0; //AN0-AN7 en modo digital
ANSELH = 0; //AN8-AN12 en modo digital
TRISEbits.TRISE2 = 0; //Pin RE2 como salida LED
TRISBbits.TRISB3 = 0; //Pin RB3 como salida TRIG
TRISBbits.TRISB4 = 1; //Pin RB3 como entrada ECHO
OPTION_REGbits.nRBPU = 0; //Activa pull-ups
TRIGpin = 0; //Pin TRIG en nivel 0
/* CONFIGURA LA INT POR CAMBIO*/
IOCBbits.IOCB4 = 1; //Activa Interrupción por cambio en RB4
/* CONFIGURACION TIMER0 1MS Fosc=8Mhz*/
OPTION_REGbits.T0CS = 0;//Modo Termporizador
OPTION_REGbits.PSA = 0; //Con prescala
OPTION_REGbits.PS = 0b011; //Prescala 1:16
TMR0 = 131; //256-[(time*Fosc)/(pre*4)] time=0.001 seg
INTCONbits.T0IF = 0; //Limpia bandera
INTCONbits.T0IE = 1; //Activa interrupción del TMR0
/* CONFIGURA TIMER1 1uS Fosc=8MHz */
T1CONbits.TMR1CS = 0; //Modo temporizador
T1CONbits.T1CKPS = 0b01; //Ajuste pre-escala 1:2
/* CONFIGURA USART A 9600 BPS 8MHz*/
TXSTAbits.BRGH = 1; //Alta del Generador
TXSTAbits.TXEN = 1; //Activa el transmisor
RCSTAbits.SPEN = 1; //Habilita el modulo USART
SPBRG = 51; //Formula [8MHz/(16 * 9600)] - 1
INTCONbits.GIE = 1; //Habilita las Interrupciones
}
void taskSR04(void) //Tarea para lectura de sensor, cada 1ms
{
static uint8_t state = 0;
static uint16_t cnt = 0;
uint16_t value;
cnt++; //Incrementa contador
switch(state)
{
case 0: //Estado para enviar disparo
value = PORTB; //Registra condición
INTCONbits.RBIF = 0;
INTCONbits.RBIE = 1; //Activa interrupción RB
T1CONbits.TMR1ON = 0;
TMR1L = 0; //Reinicia temporizador T1
TMR1H = 0;
PIR1bits.TMR1IF = 0;
T1CONbits.TMR1ON = 1; //Arranca T1
catchT1 = 0; //Limpia bandera
TRIGpin = 1; //Inicio del disparo TRIG
_delay(20); //Tiempo del pulso 0.5u x 20 = 10u
TRIGpin = 0; //Fin del disparo TRIG
cnt = 0; //Reinicia contador
state++; //Siguiente estado
break;
case 1: //Estado de espera inicio del pulso ECO
if(catchT1) //Flanco POS detectado
{
catchT1 = 0; //Limpia bandera
T1CONbits.TMR1ON = 0; //Para contador
TMR1L = 0; //Reinicia contado
TMR1H = 0;
PIR1bits.TMR1IF = 0;
T1CONbits.TMR1ON = 1; //Arranca el contador
state++; //Siguiente estado
}
if(PIR1bits.TMR1IF) state = 3;//Limite de tiempo > a 65ms
break;
case 2: //Estado de espera final del pulso ECO
if(catchT1) //Flanco NEG detectado
{
catchT1 = 0; //Limpia bandera
INTCONbits.RBIE = 0; //Desactiva interrupción RB
value = TMR1L; //Recupera valor del contador us
value |= (uint16_t) (TMR1H << 8);
distcm = value/58U; //1cm/30uS solo ida
distOK = 1;//Activa bandera
state++; //Siguiente Estado
}
if(PIR1bits.TMR1IF) state = 3; //Limite de tiempo > a 65ms
break;
case 3: //Estado para espera de repetición
if(cnt >= 999)
state = 0; //Reinicia maquina cada 0.5s
break;
}
}
void taskLED(void) //Destella led ciclo 1ms
{
static uint16_t tcnt = 0;
if(tcnt++ > 999)
{
tcnt = 0;
LEDpin = 1;
}
if(tcnt == 200) LEDpin = 0;
}
void putch(char byte)
{
while(PIR1bits.TXIF == 0) {};
TXREG = byte;
}
Pruebas de funcionamiento
Para realizar las pruebas de funcionamiento del circuito he utilizado una placa de pruebas que utiliza un PIC16F887, lo cual facilito la conexión del sensor y el convertidor UART/USB para recibir los mensajes en una terminal serial para PC, note lo simple que resulta montar el circuito que se muestra en la figura 4.Los mensajes recibidos por la terminal serial de la figura 5, muestra la información de distancia en centímetros por cada segundo.
Aquí dejo
los enlaces para que puedas descargar el proyecto, se encuentra
en formato gzip, debes descomprimir y abrir con MPLABX
Si quieres ver como compilar e implementar los proyectos de este blog, elaborados con MPLABX mira este vídeo.<Compilando proyectos MPLABX>
Conclusiones y recomendaciones
Con la implementación de este circuito junto al programa descrito, se demostró como realizar mediciones de distancia, utilizando el sensor SR04, si estás pensando utilizar este sensor en un proyecto electrónico, te recomiendo considerar los siguientes aspectos:
- El código de este ejemplo asume una situación ideal donde los pulsos de disparo siempre serán reflejados, y así el ancho de pulso en el pin eco tendría una duración no mayor a 400 centímetros que es la distancia máxima del sensor; pero en una situación real estas condiciones podrían no ocurrir si el objeto esta muy distante o no existe un reflejo de los pulsos, entonces se sugiere tomar en cuenta estos detalles en la programación en caso de una implementación real.
- También es una buena opción utilizar el promedio de varias lecturas con la finalidad de reducir el error por pequeñas variaciones que suceden entre lecturas, estos por lo general se deben a interferencias que sufren los pulsos en el trayecto.
Sin
mas que mencionar agradezco tu visita al blog y espero que el ejemplo
visto pueda ser útil en tu formación y el proyecto que desarrollas.
Atentamente, Pablo Zárate Arancibia email: pablinza@me.com / pablinzte@gmail.com, @pablinzar
Santa Cruz de la Sierra - Bolivia
No hay comentarios.:
Publicar un comentario