A continuación se presentara el funcionamiento del programa mencionado anteriormente sobre el uso del comparador analógico para la lectura de distancia mediante un sensor ultrasonido, para este caso en particular se utilizo el sensor HC-SR04 el cual mide distancia de 2 cm a 400 cm con una resolución de 0.3 cm. Ademas de esto se hará uso del timer1 para la medición de la distancia y se presentara mediante una consola el funcionamiento del circuito con un vídeo que agregare en la descripción.
DESCRIPCIÓN:
El funcionamiento del programa se puede comprender con mayor facilidad si lee las entradas anteriores sobre el uso del comparador analógico y el timer1 en captura de entrada. se describirá de forma sencilla la configuración de estos módulos para detallar mas el tratamiento de la señal para el calculo de la distancia que se desea medir.
initializeUART0(9600,0,8,2,2);
Se inicializa la UART con los siguientes parámetros
- baudrate de 9600
- modo normal de funcionamiento
- bits de datos 8
- sin paridad
- bits de stop, 2
COMPARADOR()
Esta función lo que realiza es la configuración del modulo comparador analógico donde se selecciona al pin AIN1 como la entrada negativa. en seguida se habilita el bit ACIC del registro ACSR el cual permite utilizar la captura de entrada del comparador analógico.
TEMPORIZADOR()
Mediante esta función se configura el timer1 prescalando en primer lugar el reloj para que realice el conteo con incrementos de 1us esto es importante en el código realizado porque permite utilizar valores enteros para la medición de distancia y evitar la perdida de información debido a que se están utilizando variables tipo int. Para finalizar con el timer1 se limpia el bit ICES1 del registro TCCR1B para detectar flancos de bajada en la entrada de captura.
INT MAIN:
initializeUART0(9600,0,8,2,2);
setbit(DDRB,DDB5);//TRIGGER
COMPARADOR();
TEMPORIZADOR();
//HABILITAR INTERRUPCION POR ENTRADA DE CAPTURA
setbit(TIMSK1,ICIE1);
//HABILITAR INTERRUPCION GLOBAL
sei();
La función de esta sección del código es la inicialización del USART, el comparador analógico y del timer1 y enseguida se setea el bit ICIE1 del registro TIMSK1 el cual habilita la interrupción del timer1 por captura de entrada y para finalizar se habilita la interrupción global.
HC-SR04:
Para describir el código dentro de WHILE(1) e ISR(TIMER1_CAPT_vect) debe conocerse el funcionamiento del sensor ultrasonido el cual tiene las siguientes características:
Se nos describe las características de funcionamiento eléctrico y el rango en el cual el sensor funciona de forma optima.
El uso del sensor se describe en seguida:
- Se envía un pulso de al menos 10us al pin TRIG
- En seguida el sensor envía 8 ciclos de 40kHz para detectar algún objeto
- Cuando el sensor recibe los pulso enviados el pin ECHO se mantiene en alto, esto pulso alto se encuentra en microsegundos.
- en seguida mediante el programa se realiza la conversión mediante la formula dependiendo si se desea medir en centímetros o pulgadas.
ISR(TIMER1_CAPT_vect):
En esta rutina de interrupción se determina mediante el flanco recibido en que variable se guardara el contenido del registro ICR1. Esto se realiza con ayuda de la variable i la cual es cero al inicio del programa; cuando se presenta la interrupción e i=0 entonces ICR1 se guarda en PERIODO_ANTERIOR una vez realizado esto se cambia la detección de flanco de bajada por un flanco de subida para que la rutina de interrupción se genera cuando el pin ECHO sea 0 volts nuevamente, se setea la bandera de interrupción por captura de entrada y se pone a uno la variable i,(i=1).
Cuando la interrupción vuelve a suceder y como i=1, entonces el registro ICR1 se guarda en la variable PERIODO. En seguida se resta:
if (PERIODO>PERIODO_ANTERIOR)//SI EL VALOR LEIDO ES SUPERIOR AL VALOR PRECEDENTE REALIZAR LA //SUSTRACCION DE FORMA NORMAL
{
PERIODO_REAL=PERIODO-PERIODO_ANTERIOR;
}
else //SI EL VALOR LEIDO ES INFERIOR AL VALOR PRECEDNTE SUMAR 65536 A LA RESTA PARA
{ //OBTENER EL NUMERO REAL
PERIODO_REAL=65536+PERIODO-PERIODO_ANTERIOR;
}
Una vez realizado esto se realiza la operación:
PERIODO_REAL=(PERIODO_REAL)/58;//DISTANCIA EN CENTIMETROS
Con ello se tiene el valor de la distancia medida en centímetros. para finalizar la interrupción se setea la bandera de interrupción para evitar q se dispare de forma aleatoria y se cambia la detección de la interrupción por captura de entrada con un flanco de bajada para que realice de forma correcta la interrupción en el siguiente ciclo.
if (PERIODO_REAL>=255)//SI EL DATO LEIDO ES MAYOR O IGUAL A 255 SE ASIGANA 255 A LA VARIABLE PERIODO_REAL
{
PERIODO_REAL=255;
}
DIST=(unsigned char)PERIODO_REAL;
Se pregunta si el valor en PERIODO_REAL es superior a 255, de ser así se asigna 255 a la varible DIST, de lo contrario se asigna el valor leído. Esto es para no exceder el valor de 255 de la variable DIST ya que es una variable tipo unsigned char, por ultimo se asigna el valor cero a la variable i.
WHILE(1):
Este ciclo realiza el inicio de la lectura de la distancia a la que se encuentra el objeto respecto del sensor ultrasonido esto es mediante:
//INICIAR LECTURA
setbit(PORTB,PB5);
_delay_ms(15);
clearbit(PORTB,PB5);
_delay_ms(100);
Pone en alto el pin TRIG del sensor por 15 milisegundos y nuevamente lo pone a 0 volts. espera 100 ms para realizar las siguientes funciones y para que la interrupción se realice dentro de este lapso de tiempo.
Después de que ocurrió la interrupción y termino el delay se convierten las centenas, decenas y unidades de la variable DIST en las variables dist1, dist2 y dist3 respectivamente.
//IDENTIFICAR EL CARACTER CORRESPONDIENTE EL VALOR DE LAS CENTENAS, DECENAS Y UNIDADES EN SU CORRESPONDIENTE CARACTER ASCII
centenas_dis();
decenas_dis();
unidades_dis();
Para finalizar se envían los valores convertidos y guardados en la cadena DISTANCIA[ ] con ayuda de un ciclo for, y se envía un carácter para diferenciar los valores enviados por el USART.
//ENVIAR CARACTER PARA SEPARAR DISTANCIAS MEDIDAS
TransmiteUART0(159);
NOTA: Se colocara el link de la simulación y el programa al final para que puedan descargarlo. Algo importante a considerar es un error al simular ya que la interrupción se dispara de forma imprevista pero el circuito funciona bien, debe ser algún bug del simulador. Alguna duda puede ingresarla en los comentarios.
PROGRAMA:
/*
* ultrasonico.c
*
* Created: 03/03/2014 18:06:25
* Author: TERRAFORMARS
*/
#include <avr/io.h>
#ifndef F_CPU
#define F_CPU 8000000UL // XTAL de 8 MHz
#endif
#include <avr/interrupt.h>
#include <util/delay.h>
#include "UARTAiNit.h"
#define setbit(sfr,bit) (_SFR_BYTE(sfr)|=(_BV(bit)))
#define clearbit(sfr,bit) (_SFR_BYTE(sfr)&=~(_BV(bit)))
#define bittoggle(sfr,bit)(_SFR_BYTE(sfr)^=_BV(bit))
unsigned int PERIODO=0,PERIODO_ANTERIOR=0,PERIODO_REAL=0;
unsigned char DIST=0,dist1=0,dist2=0,dist3=0,DISTANCIA[4]={0},l,i;
ISR (TIMER1_CAPT_vect){
//LEER DATO GUARDADO EN ICR1
if (i==0)//IDENTIFICACION DE LECTURA INICIAL
{
PERIODO_ANTERIOR=ICR1;
setbit(TCCR1B,ICES1);//SE CAMBIA LA CONFIGURACION DE INTERRUPCION POR UN FLANCO DE SUBIDA
setbit(TIFR1,ICF1);//SE SETA LA BANDERA DE INTERRUPCION PARA EVITAR QUE SE DISPARE NUEVAMENTE LA INTERRPCION
//DE FORMA INPREVISTA
i=1;
}
else//IDENTIFICACION DE LECTURA FINAL
{
PERIODO=ICR1;
clearbit(TCCR1B,ICES1);//SE CAMBIA LA SELECCION DE INETERRUPCION POR UN FLANCO DE BAJADA
if (PERIODO>PERIODO_ANTERIOR)//SI EL VALOR LEIDO ES SUPERIOR AL VALOR PRECEDENTE REALIZAR LA SUSTRACCION DE
{ //FORMA NORMAL
PERIODO_REAL=PERIODO-PERIODO_ANTERIOR;
}
else //SI EL VALOR LEIDO ES INFERIOR AL VALOR PRECEDNTE SUMAR 65536 A LA RESTA PARA
{ //OBTENER EL NUMERO REAL
PERIODO_REAL=65536+PERIODO-PERIODO_ANTERIOR;
}
PERIODO_REAL=(PERIODO_REAL)/58;//DISTANCIA EN CENTIMETROS
setbit(TIFR1,ICF1);//SE SETEA LA BANDERA DE INTERRUPCION POR CAPTURA PARA EVITAR QUE SE DISPARE UNA INTERRUPCION
if (PERIODO_REAL>=255)//SI EL DATO LEIDO ES MAYOR O IGUAL A 255 SE ASIGANA 255 A LA VARIABLE PERIODO_REAL
{
PERIODO_REAL=255;
}
DIST=(unsigned char)PERIODO_REAL;
i=0;
}
}
//CONFIGURAR COMPARADOR ANALOGICO
void COMPARADOR(){
//ENTRADA NEGATIVA AIN1
setbit(ADCSRB,ACME);
setbit(ADCSRA,ADEN);
//HABILITAR CAPTURA DE ENTRADA DEL COMPARADOR ANALOGICO
setbit(ACSR,ACIC);
}
//CONFIGURACION DE TIMER1
void TEMPORIZADOR(){
//CONFIGURACION DE PREESCALAMIENTO 64
clearbit(TCCR1B,CS12);
setbit(TCCR1B,CS11);
clearbit(TCCR1B,CS10);
//CONFIGURACION DE MODO DE GENERADOR DE FORMA DE ONDA
//MODO NORMAL
clearbit(TCCR1B,WGM13);
clearbit(TCCR1B,WGM12);
clearbit(TCCR1A,WGM11);
clearbit(TCCR1A,WGM10);
//FLANCO DE BAJADA DE ENTRADA DE CAPTURA
clearbit(TCCR1B,ICES1);
}
void centenas_dis(void){
switch(dist1){
case 2:
DISTANCIA[0]='2';
break;
case 1:
DISTANCIA[0]='1';
break;
case 0:
DISTANCIA[0]='0';
break;
}
}
void decenas_dis(void){
switch(dist2){
case 0:
DISTANCIA[1]='0';
break;
case 1:
DISTANCIA[1]='1';
break;
case 2:
DISTANCIA[1]='2';
break;
case 3:
DISTANCIA[1]='3';
break;
case 4:
DISTANCIA[1]='4';
break;
case 5:
DISTANCIA[1]='5';
break;
case 6:
DISTANCIA[1]='6';
break;
case 7:
DISTANCIA[1]='7';
break;
case 8:
DISTANCIA[1]='8';
break;
case 9:
DISTANCIA[1]='9';
break;
}
}
void unidades_dis(void){
switch(dist3){
case 0:
DISTANCIA[2]='0';
break;
case 1:
DISTANCIA[2]='1';
break;
case 2:
DISTANCIA[2]='2';
break;
case 3:
DISTANCIA[2]='3';
break;
case 4:
DISTANCIA[2]='4';
break;
case 5:
DISTANCIA[2]='5';
break;
case 6:
DISTANCIA[2]='6';
break;
case 7:
DISTANCIA[2]='7';
break;
case 8:
DISTANCIA[2]='8';
break;
case 9:
DISTANCIA[2]='9';
break;
}
}
int main(void)
{
initializeUART0(9600,0,8,2,2);
setbit(DDRB,DDB5);//TRIGGER
COMPARADOR();
TEMPORIZADOR();
//HABILITAR INTERRUPCION POR ENTRADA DE CAPTURA
setbit(TIMSK1,ICIE1);
//HABILITAR INTERRUPCION GLOBAL
sei();
while(1)
{
//TODO:: Please write your application code
//INICIAR LECTURA
setbit(PORTB,PB5);
_delay_ms(15);
clearbit(PORTB,PB5);
_delay_ms(100);
//SEPARAR CENTENAS, DECENAS Y UNIDADES
dist1=DIST/100;
dist2=(DIST-100*dist1)/10;
dist3=DIST-100*dist1-10*dist2;
//IDENTIFICAR EL CARACTER CORRESPONDIENTE EL VALOR DE LAS CENTENAS, DECENAS Y UNIDADES EN SU CORRESPONDIENTE CARACTER ASCII
centenas_dis();
decenas_dis();
unidades_dis();
//ENVIAR EL VALOR DE LA DISTANCIA LEIDA
for (l=0;l<3;l++)
{
TransmiteUART0(DISTANCIA[l]);
}
//ENVIAR CARACTER PARA SEPARAR DISTANCIAS MEDIDAS
TransmiteUART0(159);
}
}
VÍDEO DEL PROGRAMA EN PROTOBOARD:
IMÁGENES:
SENSOR HC-SR04:
SIMULACIÓN EN PROTEUS:
DATOS OBTENIDOS CON LA CONSOLA TERA TERM :
PROGRAMA EN ATMEL STUDIO:
LINK:
https://mega.co.nz/#!44c3WZyD!-77t1ICdaTokq-HNd6fxkpYAlkCKONX_hQiJuod4bHg
No hay comentarios:
Publicar un comentario