A continuación se presentara el funcionamiento de un programa realizado en un microcontrolador AVR con ayuda del software LABVIEW, para el control de motores y la recepción de la distancia medida por un sensor ultrasonico. Esto se explicara con detalle principalmente en cuanto al microcontrolador dejando a LABVIEW debido a su fácil manejo aclarando solo en funcionamiento en general.
DESCRIPCIÓN:
MICROCONTROLADOR:
ISR(TIMER1_CAPT_vect):
Esta rutina de interrupción realiza la medición de la distancia realizada por el sensor ultrasonico esto lo realiza activando entrada por captura del comparador analógico y configurándolo para realizar la interrupción cuando surja un flanco de bajada.
COMPARADOR():
Configura el comparador analógico para utilizar AIN1 como entrada negativa y habilita la captura de entrada.
TEMPORIZADOR():
Configura el TIMER1 con un preescalamiento de 64, en modo normal y detección de flanco de bajada de entrada de captura.
ISR(USART_RX_vect):
Esta sección del codigo realiza prácticamente lo mismo realizado en el codigo presentado del control de motor con el software MYOPENLAB con la excepción del apagado y encendido de un led y que en logar de enviar el valor leído en el potenciometro se envía la distancia detectada.
//converir de cadena a char de 8 bits
void stringToChar()
unsigned char velocidadad(unsigned char unidad)
ULTRASONICO(unsigned char valor):
Esta función realiza la selección del carácter correspondiente a las unidades, decenas y centenas capturadas por el sensor ultrasonico.
unsigned char ULTRASONICO(unsigned char valor)
MAIN:
En esta función se incializan las funciones e interrupciones con las que trabajara nuestro programa.
WHILE(1):
En este ciclo se lee continuamente el la distancia medida por el sensor ultrasonico y se realiza el control del ancho de pulso del TIMER2 para controlar un motor, teniendo un ciclo de trabajo mayor cuando detecta distancias pequeñas.
LABVIEW:
El programa envía tres datos de control, el primero es el estado en el que se encontrara el motor y el segundo la velocidad a la que se desplazara. El ultimo dato enciende o apaga un led.
La comunicación realizada con el protocolo RS232 se configuro de la siguiente forma:
- BAUDRATE 9600
- DATOS 8 BITS
- PARIDAD NONE
- BITS DE STOP 2
- TIMEOUT 2 SEGUNDOS
- SIN CONTROL DE FLUJO
La recepción de datos se realiza mediante la conversión de de cadena a entero indicando los bits que se recibirán, los cuales para esta ocasión son 3 mas el dato de terminación de cadena, siendo presentados en un indicador gráfico y un display para conocer el valor numérico de la distancia medida por el sensor ultrasonico.
NOTA:
Alguna duda o recomendación puede ingresarla en los comentarios para así mejorar los programas y la explicación de los mismos, ademas si desean que se presenta algún programa coloque lo en los comentarios se hará lo posible por presentarlo. El link de los programas se deja al final para que pueda descargarlos.
PROGRAMA:
/*
* PRACTICA_VIERNES.c
*
* Created: 19/03/2014 18:27:16
* Author: TERRAFORMARS
*/
/*
* motorConCadena.c
*
* Created: 24/02/2014 17:14:30
* Author: TERRAFORMARS
*/
#include <avr/io.h>
#ifndef F_CPU
#define F_CPU 8000000UL // XTAL de 8 MHz
#endif
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "UARTAiNit.h"
#include "TIMER0.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 char tempo=0,analog,velocidad=0,i=0,t=1,pot1,pot2,pot3,l,c;
unsigned char a[5]={0},b[5]={0},v1=0,v2=0,v3=0,temp[5]={0},vel0[3]={0},potenciometro[5]={0},vel1[3]={0};
unsigned int PERIODO=0,PERIODO_ANTERIOR=0,PERIODO_REAL=0;
unsigned char DIST=0,dist1[4]={0},DISTANCIA[4]={0},D=0;
unsigned char velocidadad(unsigned char unidad);
//ultrasonico
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);
}
//motores
ISR (USART_RX_vect){
//RECIBIR DATO
for(i=0;i<4;i++){
a[i]=ReceiveUART0();
}
//CONVERTIR A CHAR
stringToChar();
//ESTADO DEL MOTOR
switch(tempo){
case 1:
//MOTOR IZQUIERDA
setbit(PORTB,PB0);
COMPAREA_FASTB(2);
clearbit(PORTD,PD4);
break;
case 3:
//MOTOR DERECHA
setbit(PORTB,PB0);
COMPAREA_FASTB(3);
setbit(PORTD,PD4);
break;
case 2:
//MOTOR STOP
clearbit(PORTB,PB0);
velocidad=3;
break;
}
if (tempo==1||tempo==2||tempo==3)
{
//CAMBIO DE VELOCIDAD
OCR0B=velocidad;
}
//borrar();
//ENVIAR EL VALOR DE LA DISTANCIA LEIDA
for (l=0;l<3;l++)
{
TransmiteUART0(DISTANCIA[l]);
}
//ENVIAR CARACTER PARA SEPARAR DISTANCIAS MEDIDAS
TransmiteUART0(10);
}
//converir de cadena a char de 8 bits
void stringToChar(){
//ESTADO
strcpy(b,a);
strncpy(temp,b,1);
tempo=atoi(temp);
//VELOCIDAD
for(i=0;i<4;i++){
b[i]=a[i];
}
for (i=0;i<2;i++)
{
vel0[i]=b[i+1];
}
if (b[3]=='1'){setbit(PORTD,PD3);}
else if (b[3]=='0'){clearbit(PORTD,PD3);}
for(i=0;i<2;i++){
vel1[i]=velocidadad(vel0[i]);
}
velocidad=16*vel1[1]+vel1[0];
if (velocidad==0){velocidad=4;}
if (velocidad>=253){velocidad=252;}
/////////////////////
}
unsigned char velocidadad(unsigned char unidad){
switch(unidad){
case '0':
v3=0;
break;
case '1':
v3=1;
break;
case '2':
v3=2;
break;
case '3':
v3=3;
break;
case '4':
v3=4;
break;
case '5':
v3=5;
break;
case '6':
v3=6;
break;
case '7':
v3=7;
break;
case '8':
v3=8;
break;
case '9':
v3=9;
break;
case 'A':
v3=10;
break;
case 'B':
v3=11;
break;
case 'C':
v3=12;
break;
case 'D':
v3=13;
break;
case 'E':
v3=14;
break;
case 'F':
v3=15;
break;
}
return v3;
}
unsigned char ULTRASONICO(unsigned char valor){
switch(valor){
case 0:
D='0';
break;
case 1:
D='1';
break;
case 2:
D='2';
break;
case 3:
D='3';
break;
case 4:
D='4';
break;
case 5:
D='5';
break;
case 6:
D='6';
break;
case 7:
D='7';
break;
case 8:
D='8';
break;
case 9:
D='9';
break;
}
return D;
}
//MAIN
int main(void)
{
//MODO FAST PWM
setbit(TCCR2B,CS22);
setbit(TCCR2B,CS21);
setbit(TCCR2B,CS20);
TCCR2A|=(1<<WGM20);
TCCR2A|=(1<<WGM21);
TCCR2B&=~(1<<WGM22);
setbit(TCCR2A,COM2A1);
setbit(DDRB,DDB3);
setbit(DDRB,DDB1);
setbit(PORTB,PB1);
setbit(DDRD,DDD3);
COMPARADOR();
TEMPORIZADOR();
initializeUART0(9600,0,8,2,2);
initTIMER0_FAST1();
PREESCALL(5);
COMPAREA_FASTB(2);
setbit(DDRD,DDD2);
setbit(DDRD,DDD4);
setbit(DDRD,DDD5);
clearbit(PORTD,PD4);
setbit(DDRB,DDB0);
//HABILITAR INTERRUPCION POR ENTRADA DE CAPTURA
setbit(TIMSK1,ICIE1);
setbit(UCSR0B,RXCIE0);
sei();
while(1)
{
//TODO:: Please write your application code
//INICIAR LECTURA
setbit(PORTD,PD2);
_delay_ms(15);
clearbit(PORTD,PD2);
_delay_ms(80);
//SEPARAR CENTENAS, DECENAS Y UNIDADES
dist1[0]=DIST/100;
dist1[1]=(DIST-100*dist1[0])/10;
dist1[2]=(DIST-100*dist1[0]-10*dist1[1]);
dist1[3]=48;
if (DIST<=3)
{
DIST=3;
}
else if(DIST>=252)
{
DIST=252;
}
OCR2A=255-DIST;
for(l=0;l<3;l++){
DISTANCIA[l]=ULTRASONICO(dist1[l]);
}
}
}
VÍDEO:
IMÁGENES:
PROGRAMA EN ATMEL STUDIO:
SIMULACIÓN EN ISIS PROTEUS:
DIAGRAMA DE BLOQUES DE LABVIEW:
SIMULACIÓN EN LABVIEW:
LINK:
MICROCONTROLADOR:
https://mega.co.nz/#!4k0RBRaQ!3TsDdXf8647Q0oDEYQsoNVpNEd1-FKSA-iZqLzDjJp0
LABVIEW:
https://mega.co.nz/#!slNFVTiT!HKLXTBAlcg8rhfmdEIs2PvyLM4TDjzmt8pKHyzbLnCs
No hay comentarios:
Publicar un comentario