Post on 28-Jul-2015
1
DIVISION DE CIENCIAS BASICAS E INGENIERIA
DEPARTAMENTO DE ELECTRONICA
LICENCIATURA EN INGENIERIA ELECTRONICA
PROYECTO INTEGRAL DE INGENIERIA ELECTRONICA
“DISEÑO E IMPLEMENTACION DE UN SISTEMA DE CONTROL
POR RF PARA LA ELEVACION VERTICAL DE UN HELICOPTERO”
ALUMNO:
SEGUNDO BAUTISTA PEDRO ENRIQUE 204304741
ASESORES:
JORGE MIGUEL JAIMES PONCE 16248
IRMA IRASEMA SILLER ALCALA 166250
FECHA DE ENTREGA: 21 DE ABRIL DEL 2010
2
OBJETIVO GENERAL:
Diseñar un sistema de control utilizando lenguaje visual en una PC, que pueda recibir
información por medio de un sistema digital y un sistema de RF comercial, para controlar
la elevación de un helicóptero.
OBJETIVOS PARTICULARES:
Diseñar y desarrollar el software en lenguaje visual en PC para implementar una ley
de control clásica.
Diseñar e implementar el software de comunicación por el puerto USB de la PC
hacia un sistema digital.
Diseñar el software y un sistema digital que establezca comunicación por el puerto
USB con la PC.
Diseñar el software y hardware necesarios para poder controlar los interruptores de
mando de control remoto.
Diseñar el software para recibir información por medio de un modulo de RF
comercial.
3
ÍNDICE
CAPITULO 1 “INTRODUCCION”
1.1 Antecedentes…………………………………………………......................06
1.2 Descripción técnica........................................................................................06
CAPITULO 2 “USB”
2.1 Introducción………………………………………………….......................08
2.2 Nivel físico…………………………………………………………………09
2.3 Conexión / desconexión en caliente (plug&play)…………………………..11
2.4 Arquitectura………………………………………………….......................11
2.4.1 Interconexión USB o topología USB……………….........................12
2.4.2 Dispositivos USB…………………………………….......................13
2.4.2.1 Los Hubs………………………………....................14
2.4.2.2 Las funciones……………………………………….15
2.4.3 El Host o controlador anfitrión USB…………………………………16
2.5 Protocolo USB……………………………………………………………...17
2.6 Tipos de transferencia de datos…………………………………………….18
2.6.1 Transferencia de control……………………………………………18
2.6.2 Transferencia isócrona……………………………………………19
2.6.3 Transferencia de interrupción………………………………………19
2.6.4 Transferencia bulk………………………………………………….19
2.7 Clases de dispositivos………………………………………………………20
2.8 Enumeración y descriptores de dispositivos………………………………..24
2.9 Driver……………………………………………………………………….25
CAPITULO 3 “COMUNICACION DE UN SISTEMA DIGITAL CON LA PC”
3.1 Introducción………………………………………………………………...26
4
3.2 Compilador C de CCS……………………………………………………26
3.2.1 Estructura de un programa………………………………………….27
3.2.2 Tipos de datos………………………………………………………28
3.2.3 USB CDC…………………………………………………………..30
3.3 Programación del PIC18F2550…………………………………………….31
3.3.1 Configuración PIC………………………………………………….32
3.3.2 Funciones…………………………………………………………...37
3.4 Circuito del sistema digital…………………………………………………41
CAPITULO 4 “COMUNICACIÓN DE LA PC CON UN SISTEMA DIGITAL”
4.1 Introducción………………………………………………………………...43
4.2 Visual Basic 6.0…………………………………………………………….43
4.2.1 Modo de Diseño y Modo de Ejecución…………………………….44
4.2.2 Formularios y Controles……………………………………………45
4.2.3 Objetos y Propiedades……………………………………………45
4.2.4 Nombres de objetos………………………………………………...46
4.2.5 Eventos……………………………………………………………...47
4.2.6 Métodos…………………………………………………………….47
4.2.7 Tipos de datos………………………………………………………48
4.2.8 Creación de programas ejecutables…………………………………48
4.3 Desarrollo de aplicación en Visual Basic 6.0………………………………49
4.3.1 Pantalla de Controles……………………………………………….49
4.3.2 Pantalla de Código………………………………………………….51
4.3.2.1 Escalamiento del Dato del sensor…………………..55
4.3.2.2 Algoritmo de control PI…………………………….58
CAPITULO 5 “MODULO RECEPTOR DE RF”
5
5.1 Introducción………………………………………………………………...60
5.2 Circuito del modulo receptor de RF………………………………………..60
5.3 Programación del PIC………………………………………………………61
CAPITULO 6 “CONCLUSIONES Y EXPECTATIVAS”
APENDICE A “HOJAS DE DATOS DE LOS DISPOSITIVOS”
6
CAPITULO 1 “INTRODUCCIÓN”
1.1 Antecedentes.
En la actualidad, solo pocos países como estados unidos y Alemania dominan la tecnología
de helicóptero no tripulado. Es de muy amplio uso este tipo de helicóptero capaz de realizar
operaciones de detección a distancia, exploración de recursos y geodesia.
El helicóptero no tripulado “WD100”, desarrollado por Hexiang Aviation Technology Co.
Ltd, realizo un experimento de despegue y aterrizaje automáticos el 27 de enero del 2008
en Anyang de la provincia de Henan, lo que marca que China ya figura entre los países
avanzados en este dominio tecnológico.
Con la realización de este proyecto se ha logrado dar un paso en el diseño e
implementación de un helicóptero no tripulado, al poder controlar la altura a la que se
encuentra el helicóptero, la altura es una de las tantas variables que se deben controlar para
lograr un diseño muy eficiente de un helicóptero no tripulado.
1.2 Descripción técnica.
En la actualidad cada vez son menos las PC que tienen puertos COM (RS-232), por lo que
se debe pensar en una alternativa para crear interfaces con las PC, en este proyecto se opto
por crear una interfaz a través del USB.
Microchip cuenta con familias de PIC que tienen módulos USB, además de que existen
módulos externos los cuales se pueden conectar a cualquier PIC, dentro de los PIC que
tienen modulo USB existen el PIC 18F2550 y 18F4550. Para poder lograr comunicación
por USB se opto por utilizar el PIC 18F2550 debido a que cuenta con modulo USB y un
menor número de puertos, en esta aplicación no se requiere más de dos puertos. Para la
programación del PIC se utilizo el compilador C de CCS, este compilador contiene librerías
para simplificar la comunicación del PIC con la PC a través del USB
7
Del lado de la PC se desarrollo una aplicación en Visual Basic 6.0 para poder establecer la
comunicación entre la PC y el Sistema digital, con ayuda de esta aplicación se puede
monitorear y controlar la altura del helicóptero. Para controlar la distancia se ha
implementado un algoritmo de control PI para obtener una mejor respuesta de todo el
sistema.
Para poder monitorear y controlar la altura del helicóptero a distancia, se opto por usar
módulos de RF, con un modulo Tx-Rx (transmisor-receptor) se monitorea la distancia a la
que se encuentra nuestro helicóptero, con la ayuda de un sensor infrarrojo, y con otro
modulo Tx-Rx se controla los motores del helicóptero con la técnica de PWM.
El proyecto consta de cuatro bloques los cuales se irán explicando uno a uno en los
capítulos siguientes. En la Fig.1 se puede observar el diagrama bloques del proyecto:
Fig.1 Diagrama a bloques del Proyecto.
8
CAPITULO 2 “USB”
2.1 Introducción.
USB (Universal Serial Bus) es una especificación de las empresas COMPAQ, Intel,
Microsoft y NEC, que describe un canal serie que soporta una gran variedad de periféricos
de media y baja velocidad, con soporte integral para transferencias en tiempo real
(isócronas) como voz, audio y vídeo comprimido, y que permite mezclar dispositivos y
aplicaciones isócronas y asíncronas. Por lo tanto, entre los dispositivos USB más
característicos se pueden citar teclados, ratones, joysticks, monitores, módems, impresoras,
escáneres, CD-ROMs, dispositivos de audio (como micrófonos o altavoces digitales),
cámaras digitales y otros dispositivos multimedia.
En 1995 fue publicado USB 0.9.
En 1996 se publica USB 1.0 y se establece dos tipos de conexión: La primera denominada
velocidad baja (“Low speed”), ofrece 1.5 Mbps y esta pensada para periféricos que no
requieren un gran ancho de banda, como ratones o joysticks. La segunda denominada
velocidad completa (“Full speed”), es de 12 Mbps, y esta destinada a los dispositivos más
rápidos.
En 1998 fue publicada USB 1.1, se añade detalles y precisiones a la norma inicial y se
vuelve el estándar mínimo que debe cumplir un dispositivo USB.
En 2000 fue publicada la versión final USB 2.0, es una variación de la norma compatible
con las anteriores y permite velocidades de hasta 480 Mbps denominada alta velocidad
(“High speed”).
En la Tabla 2.1 se muestran características y aplicaciones del USB dependiendo su
velocidad.
9
Velocidad Características Aplicaciones ESPECIFICACIONES
Baja
Velocidad
Dispositivos
Interactivos
10/100KBPS
Teclado, Ratón, Impresora,
Periféricos de Juegos,
Periféricos de Realidad
Virtual
Bajo Costo,
Plug and Play,
Facilidad de uso,
Múltiples Periféricos
Media
Velocidad
Telefonía, Audio
Video
Comprimido
500 KBPS/10
MBPS
RDSI, PBX, POTS, Audio
Bajo Costo,
Facilidad de uso,
Ancho de Banda
Garantizado,
Plug and Play,
Múltiples Dispositivos
Alta
Velocidad
Video
Almacenamiento
25x10 MBPS
Video, Almacenamiento,
Imágenes
Bajo Costo,
Facilidad de uso,
Gran Ancho de Banda,
Plug and Play,
Múltiples Dispositivos
Tabla 2.1 Características y aplicaciones de USB
2.2 Nivel físico.
A nivel físico, USB utiliza un cable de 4 conductores para transmitir una señal diferencial
(D+ y D-) y alimentación (VBus = 5V y GND) por medio de conexiones punto a punto.
Los dispositivos LS van obligatoriamente equipados con un cable de longitud adecuada
(hasta unos 3m, dependiendo de sus características eléctricas), mientras que los FS pueden
ir equipados con un cable o utilizar cables independientes de hasta 5m (también
dependiendo de sus características eléctricas).
Existen dos tipos de conectores USB:
El conector de serie A, conector plano es el conector usado por los dispositivos USB para
conectarse directamente a un host o a un puerto ascendente de un hub, presentan los cuatro
conectores correspondientes a los cuatro conductores alineados. Todos los dispositivos
USB deben tener el estándar Serie A.
10
El conector Serie B es la parte de conexión del dispositivo al host como descendente,
presentan los contactos distribuidos en dos planos paralelos, dos en cada plano, y se
emplean en los dispositivos que deben conectarse a un cable USB. Por ejemplo impresoras,
scanner, y módems.
En la Fig. 2.1 se muestran los dos tipos de conectores USB, el conector de la izquierda es el
de serie A y el de la derecha es el de la serie B.
Fig. 2.1 Conectores USB
En la Tabla 2.2 se puede ver la identificación de cables dependiendo el número de Pin o
color del cable.
Numero de Pin Nombre de la señal Color de identificación
1 VUSB Rojo
2 D- Blanco
3 D+ Verde
4 Gnd Negro
Tabla 2.2 Identificación de Cables.
11
El USB soporta diferentes tamaños de paquetes de información esto permite el poder
conectar diferentes tipos de dispositivos de almacenamiento y proporciona diferentes tipos
de velocidades de transmisión de datos para adaptarse a los diferentes tamaños de los
buffers controlando el flujo de almacenamiento.
La comunicación es bidireccional y semi-dúplex, y utiliza codificación auto reloj NRZI (la
línea cambia de nivel si se transmite un 0 y no cambia si transmite un 1) con "bit stuffing"
(inserción de un cero tras la transmisión de 6 unos, para asegurar transiciones en la línea y
permitir que la PLL del receptor se mantenga sincronizada). Los dispositivos disponen de
un transmisor diferencial, receptores diferencial y S/E y resistencias de terminación con los
que pueden transmitir y detectar varios estados eléctricos distintos en la línea:
Transmisión/Recepción diferencial de bits: Estados DIFF0 y DIFF1, denominados
también estados J y K.
SE0 (Single-Ended 0): Ambas señales D+ y D- a 0V. Se utiliza para detectar la
conexión/desconexión de dispositivos, para indicar el EOP (fin de paquete) y para
generar reset.
IDLE: reposo o línea en alta impedancia, necesario para permitir transferencias
semi-dúplex, detectar la conexión y desconexión de dispositivos y discriminar entre
dispositivos FS y LS.
El SOP (principio de paquete) se indica mediante una transición IDLE a K.
El EOP (fin de paquete) se indica mediante una secuencia SE0 (2 bits) + J (1 bit) +
IDLE.
Detección de dispositivo y discriminación FS/LS: cuando el transmisor deja la línea
en IDLE, si hay un dispositivo conectado su polarización fuerza un estado J (DIFF0
si LS ó DIFF1 si FS), y si no lo hay, la polarización del transmisor fuerza un estado
SE0.
Reset: transmisión de SE0 durante >= 10 ms.
2.3 Conexión/desconexión en caliente (Plug&Play).
USB permite conectar y desconectar un nuevo dispositivo sin tener que reiniciar el sistema.
Cuando un Hub detecta una nueva conexión se lo comunica al Controlador USB, el sistema
interroga al nuevo dispositivo, determina sus propiedades y posibilidades y lo configura.
Adicionalmente el sistema carga el manejador adecuado al tipo de dispositivo con lo que el
usuario puede empezar a trabajar con el mismo inmediatamente. Algunos sistemas
operativos llaman a este proceso "Bus Enumeration".
2.4 Arquitectura.
Esta basada en tres áreas de responsabilidad:
La interconexión USB
Los dispositivos USB
12
El host o controlador anfitrión USB
2.4.1 Interconexión USB o topología USB.
El estándar presenta un ámbito de interconexión, para conectar los dispositivos USB con el
host USB o controlador anfitrión, estructurando la interconexión en siete capas en estrella y
cada estrella tiene como centro un Hub raíz. Esta estructura permite conectar hasta 127
dispositivos a la vez. El hecho de que sean siete capas esta basado en la perdida de señal
que podría generar los accesos jerarquizados.
Cada segmento es una conexión punto a punto entre el host y un Hub o entre el host y un
dispositivo que proporciona una nueva facilidad al host tal como un micrófono digital, un
disco duro, etc. que en la figura se identifica como función, esto quiere decir que cada
dispositivo tiene una funcionalidad específica. En la Fig. 2.2 se detalla esta estructura y se
presenta un elemento que puede considerarse la conjunción de un Hub y una función,
denominándolo como dispositivo compuesto ya que proporciona un modo de unión y una
funcionalidad añadida que en ningún caso pueden separarse.
Fig. 2.2 Conexión de 7 capas en estrella.
13
2.4.2 Dispositivos USB.
Estos pueden ser Hubs que proporcionan conexiones al USB o dispositivos que añaden
funcionalidades al sistema, tales como la facilidad de conexión para un joystick digital,
para altavoces o para dispositivos de almacenamiento.
Estos dispositivos presentan un interfaz estándar de modo que entienden el protocolo de
USB y tienen la capacidad para responder a operaciones propias del estándar USB, tales
como operaciones de configuración y liberación. Bajo la denominación de dispositivos
USB se enmarcan los Hub, interfaces humanos (HID), impresoras, dispositivos de
almacenamiento y otros. De un modo genérico podemos distinguir dos grupos.
Los Hub.
Las Funciones.
En la Fig. 2.3 se presenta el modo de interconexión y la forma en que se realizan dichas
conexiones, de tal modo que a través del teclado se insertan en el bus las funcionalidades de
un lápiz, y el ratón. Así mismo, el monitor asume las funcionalidades dadas a través del
teclado y añade al bus funcionalidades de sonido e imagen, por último los puertos del PC
atienden por un lado el bus de teclado y monitor y por otro la funcionalidad de telefonía por
otro puerto y la posible conexión de otros periféricos vía un Hub para otras funcionalidades
diferentes, cámara digital, disco duro integrado, etc.
Fig. 2.3 Interconexión de varios Hub.
14
Es importante resaltar que solamente los Hub tienen la capacidad de proporcionar punto de
acceso adicional al USB y las Funciones dan nuevas facilidades al host directamente o a
través del Hub.
2.4.2.1 Los Hubs.
Dentro de la arquitectura USB, unos elementos esenciales y especiales son los Hubs
(concentradores), que proveen conectividad (los dispositivos no se conectan entre sí
directamente, sino cada uno a un Hub), detectan la conexión y desconexión (plug&play) de
dispositivos y si son FullSpeed o LowSpeed, generan alimentación hacia los dispositivos e
incorporan la terminación de las líneas. Los Hubs disponen de una conexión "Upstream"
hacia el ordenador y una o varias conexiones "Downstreams" hacia dispositivos u otros
Hubs, de forma que se pueden encadenar varios Hubs para formar una topología en varios
niveles.
Como a los Hub se conectan los dispositivos en estrella, la topología USB se denomina
Estrella en Niveles. USB permite hasta 6 niveles, y en el nivel 0 (Raíz o Root) se encuentra
el Controlador USB, que controla todo el tráfico de información en el bus. Los Hubs
podrán ir integrados en algunos dispositivos (del estilo de teclados, impresoras y
monitores), y también estarán disponibles como elementos independientes. Normalmente
los Hubs serán autoalimentados, aunque bajo ciertas restricciones topológicas podrían
utilizarse Hubs alimentados desde el bus.
El Hub dispone de un Repetidor, para pasar información entre el puerto Upstream y los
puertos Downstreams, y de un Controlador, que incorpora un juego de registros a través de
los cuales el Controlador USB configura el hub y controla y monitoriza los puertos
Downstream.
Los Hubs son como distribuidores inteligentes de datos y alimentación, y hacen posible la
conexión de 127 dispositivos a un único puerto USB. De una forma selectiva reparten datos
y alimentación hacia sus puertos Downstream y permiten la comunicación hacia su puerto
de retorno o Upstream. Un hub de 4 puertos, por ejemplo, acepta datos del PC para un
periférico por su puerto Dowstream de y los distribuye a los 4 puertos Upstream si fuera
necesario.
Los aspectos más relevantes de su funcionalidad son:
Proporcionar un dominio de conectividad
Gestionar la alimentación eléctrica
Detectar la conexión y desconexión de los dispositivos
Detectar las caídas del bus y las recuperaciones del mismo
Soportar dispositivos de alta, completa y baja velocidad.
En la Fig. 2.4 se puede observar un Hub.
15
Fig. 2.4 Hub de 6 y 4 puertos.
Presenta un puerto Upstream que le conecta al hub ascendente en dirección del host y
varios puertos descendentes que conceden conexiones a otros hub de nivel inferior o a otras
funciones.
Un hub esta formado por tres componentes:
El Hub Repetidor es responsable de la funcionalidad de conexión y desconexión
entre los puertos Upstream y Downstream y gestiona la señalización para
situaciones excepcionales tales como la detección de conexión y desconexión del
bus y de la conexión y desconexión de los periféricos que estén conectados.
El Hub Controlador proporciona el mecanismo de comunicación hacia y desde el
host y mediante información de los estados de un Hub y algunos comandos de
control puede configurar, monitorizar y controlar los flujos de información de los
puertos de este.
El Traductor de transacciones realiza la adaptación de transacciones que sean de
diferente velocidad, de modo que hace posible la unión entre dispositivos de alta y
baja velocidad.
2.4.2.2 Las funciones.
Una función es un dispositivo USB que esta diseñado para transmitir y recibir datos o
información de control sobre el bus USB. Es identificada como un dispositivo periférico
que con un cable se conecta a un puerto de un hub, sin embargo físicamente puede
incorporar múltiples funciones e incluso llevar dentro un hub en cuyo caso se conoce como
un dispositivo compuesto, que es visto por el host como un hub con uno o más dispositivos
USB que no pueden ser desconectados o conectados de modo individual.
Cada Función tiene información de la configuración que describe sus facilidades y
funcionalidades y no puede funcionar si antes el host no lo ha configurado en base a esa
16
información, lo que significa asignar ancho de banda y selección de las opciones de
configuración de su función específica.
Un ejemplo de Función seria en lo relativo al interfaz humano un ratón, un controlador de
un juego, etc. En lo relativo a dispositivos de tratamiento de imágenes seria un scanner o
una cámara. En lo relativo al almacenamiento masivo un CD-ROM, floppy o un DVD. En
lo relativo a comunicaciones seria un periférico que aporta la filosofía de comunicaciones
Bluetooth. En la Fig. 2.5 se pueden observar algunos ejemplos de las funciones antes
mencionadas.
Fig. 2.5 Ejemplos de funciones USB.
2.4.3 El Host o controlador anfitrión USB.
El controlador es único, reside dentro del PC y es responsable de las comunicaciones entre
los periféricos USB y la CPU del PC, pudiendo ser una combinación de hardware, firmware
y software. Es también responsable de la admisión de los periféricos dentro del bus, tanto si
se detecta una conexión como una desconexión. Para cada periférico añadido, el
controlador determina su tipo y le asigna una dirección lógica para utilizarla siempre en las
comunicaciones con el mismo. Si se producen errores durante la conexión, el controlador lo
comunica a la CPU, que a su vez, lo transmite al usuario. Una vez se ha producido la
conexión correctamente, el controlador asigna al periférico los recursos del sistema que éste
precise para su funcionamiento. El controlador también es responsable del control de flujo
de datos entre el periférico y la CPU.
17
Además del controlador, el PC también contiene el concentrador raíz o root. Este es el
primer concentrador de toda la cadena que permite a los datos y a la energía pasar a uno o
dos conectores USB del PC, y de allí a los 127 periféricos que, como máximo, puede
soportar el sistema. Esto es posible añadiendo concentradores adicionales. Por ejemplo, si
el PC tiene un único puerto USB y a este le conectamos un Hub de 4 puertos, el PC se
queda sin más puertos disponibles. Sin embargo, el hub de 4 puertos permite realizar 4
conexiones descendentes. Conectando otro hub de 4 puertos a uno de los 4 puertos del
primero, habremos creado un total de 7 puertos a partir de un puerto del PC. De esta forma,
añadiendo concentradores, el PC puede soportar hasta 127 periféricos USB. En la Fig. 2.6
se representa la creación de los 7 puertos comentados a través de dos hub.
Fig. 2.6 Creación de 7 puertos con 2 Hub.
2.5 Protocolo USB.
El protocolo a nivel físico se basa en tokens (testigos). El controlador USB transmite tokens
que incluyen la dirección del dispositivo destino, y el dispositivo que detecta su dirección
en el token responde y lleva a cabo la transferencia de datos con el controlador. De esta
manera, el Controlador USB maneja la parte más compleja del protocolo, generando los
tokens de transferencias de datos a 12 Mbps o a 1,5 Mbps, y controlando la conexión lógica
entre el sistema y las funciones internas de cada dispositivo. El controlador USB también
maneja el consumo en el bus a través de las funciones Suspender/Continuar, por medio de
las cuales controla los modos Reposo/Activo de los dispositivos. Esta arquitectura permite
el diseño de dispositivos extremadamente simples y de bajo costo.
18
USB divide el tiempo en Tramas de 1ms, durante las cuales se llevan a cabo las
comunicaciones a través de Transacciones, las cuales se componen a su vez de Paquetes. Se
utiliza un sistema de detección y corrección de errores bastante robusto tipo CRC
("Cyclical Redundancy Check").Las transacciones se componen de 3 fases Token, Dato y
Validación (Handshake):
La fase de Token se compone de un paquete de Token enviado por el Controlador
USB, y siempre está presente en toda transacción. El paquete contiene los campos:
o PID (Product-ID, identifica el tipo de paquete). Todos los PIDs van
protegidos por bits redundantes.
o Dirección del elemento destino (7 bits de dispositivo + 4 bits de elemento
interno al dispositivo), y CRC5.
La fase de Datos (opcional) se compone de los paquetes de datos que se transfieren
entre el Controlador USB y el dispositivo. Cada paquete se compone de los campos
PID, Datos, y CRC16.
La fase de Validación (opcional) se usa para indicar el resultado de la transacción.
Se compone sólo de un campo PID.
Adicionalmente, el Controlador USB indica el principio de cada Trama y la transmisión
hacia dispositivos LS mediante tokens especiales.
2.6 Tipos de transferencias de datos.
USB soporta 4 tipos de transferencias de datos:
Control, para configuración y control de dispositivos y para manejo del bus.
Isócrono, para transmisión de información con ancho de banda y latencia
garantizadas, necesario para aplicaciones como audio, telefonía y vídeo. Permite
una comunicación periódica y continua entre el sistema y el dispositivo.
Interrupción, para transferencias de pocos datos, no periódicas, de baja frecuencia
pero con unos ciertos límites de latencia.
Bulk, para transferencias de grandes cantidades de datos con dispositivos
asíncronos, como impresoras, escáneres, cámaras fotográficas, etc.
2.6.1 Transferencia de control.
Se desarrollan en 3 Transacciones:
19
Transacción de Configuración (Setup), en la que se envía al dispositivo un paquete
que específica la operación a ejecutar. Ocupa 8 bytes.
Cero o más Transacciones de Datos, en las que se transfieren los paquetes de datos
en el sentido indicado por la Transacción de Configuración. La información útil por
paquete puede ser de 8, 16, 32 ó 64 bytes para Endpoints FS, y de 8 bytes para
Endpoints LS.
Transacción de Estado, en la que el receptor informa del estado final de la
operación.
Las transacciones se procesan por medio de un mecanismo "best effort", según el cual el
Controlador USB las va procesando en función del tiempo disponible en cada Trama.
Como mínimo se reserva el 10% del tiempo de Trama, y se puede utilizar tiempo adicional
siempre que las necesidades de los tráficos isócrono y de interrupción lo permitan. También
incorporan mecanismos de detección de errores (CRC) y de recuperación/retransmisión de
datos.
2.6.2 Transferencia isócrona
Este proceso se utiliza cuando es necesario enviar datos en tiempo real. Los datos son
enviados con una cadencia exacta ajustada a un reloj, de modo que la transmisión es a
velocidad constante. Es utilizada por dispositivos de full speed y la información útil por
paquete es de 1 a 1023 bytes. Los errores no se recuperan de tal modo que cuando la
información no llega a su tiempo se descarta.
2.6.3 Transferencia de interrupción.
Aseguran una transacción (paquete), dentro de un periodo máximo (los dispositivos FS
pueden solicitar entre 1 y 255ms, y los LS entre 10 y 255ms de periodo máximo de
servicio). Incorpora detección de errores y retransmisión de datos. La información útil por
paquete puede oscilar entre 1 y 64 bytes para dispositivos FS y entre 1 y 8 bytes para
dispositivos LS.
El sistema puede asignar como máximo el 90% del tiempo de Trama para transferencias
isócronas y de interrupción. Si el sistema no puede garantizar tiempo suficiente como para
manejar una nueva conexión de interrupción (transmitir un nuevo paquete dentro del
periodo máximo requerido), simplemente no se establece la conexión.
2.6.4 Transferencia bulk.
Sólo son utilizables por dispositivos FS. Se procesan por medio de un mecanismo "good
effort", en el que el sistema aprovecha cualquier ancho de banda disponible y en el
momento en que esté disponible (en otras palabras, no se garantiza una latencia ni un ancho
20
de banda mínimos). Se puede utilizar el tiempo de Trama reservado y no consumido por
transferencias de Control (10%).
Incorporan mecanismos de control de errores para garantizar la entrega de datos. La
información útil por paquete puede ser de 8, 16, 32 ó 64 bytes.
2.7 Clases de dispositivos.
A aquellos grupos de dispositivos que tienen similares características tales como formatos
de datos similares, la misma forma de comunicarse, etc. se le denomina Clase USB.
Las distintas Especificaciones de Clase USB permite que los fabricantes desarrollen
dispositivos que puedan trabajar con drivers que controlan a los dispositivos en base a la
información descriptiva dada por el propio dispositivo, estos son los Drivers de Clase.
Una Clase se utiliza para describir la forma en que un interfaz se comunica con el sistema,
tanto a nivel de datos como a nivel de control, proporcionando información sobre la
funcionalidad del interfaz. Esto hace que dicha información pueda utilizarse para que el
sistema localice un driver que pueda controlar tanto la conectividad entre el interfaz y el
sistema, como la funcionalidad del dispositivo.
Existe una relación entre driver y dispositivo que opera del siguiente modo:
En USB solo se permite que la comunicación entre el driver y el hardware del dispositivo
sea a través de una vía de comunicación, denominada “pipe”, para el intercambio entre
aplicaciones que se ejecutan en el host y los distintos endpoints de los dispositivos USB.
Cuando un dispositivo USB se conecta a un sistema y este lo reconoce y lo configura, el
dispositivo queda organizado como un conjunto de interfaces donde cada interfaz
específica que partes del hardware del dispositivo interactúa con el sistema USB (se
denominan endpoint) y el sistema establece todas las vías de comunicación (pipes)
necesarias entre el sistema y cada uno de los endpoint disponibles en esa configuración del
dispositivo. Es importante resaltar que el dispositivo puede contemplar varias
configuraciones con distintos conjuntos de “endpoint”. El sistema elige una configuración
en base a la funcionalidad específica que se precise del dispositivo.
En la Fig. 2.7 se puede observar la representación de las pipes para cuatro endpoint:
21
Fig. 2.7 Representación de Pipes.
Sobre estas pipes pueden llevarse a cabo diferentes tipos de transacciones y existen dos
tipos de pipes:
Pipe de Control o Mensaje: Es una vía de comunicación bidireccional entre el host y dos
endpoint de control en un dispositivo USB, siendo uno de Salida y otro de Entrada y todos
los dispositivos disponen de estos endpoint en al dirección 0 para que siempre el sistema
pueda establecer una pipe de control, incluso antes de la configuración, pudiendo a través
de ella leer toda la información descriptiva del dispositivo para saber el tipo de dispositivo,
posibles configuraciones, protocolo que soporta, número y tipo de endpoint que tiene en
cada configuración, etc. En resumen lo denominado como Descriptores, que veremos más
adelante. Los datos que se mueven a través de este pipe tienen una estructura caracterizada
por las especificaciones del Bus USB. En la Fig. 2.8 se puede observar la representación de
una Pipe de control o mensaje.
22
Fig. 2.8 Pipe de control o mensaje.
Pipe de Stream: Es una vía de comunicación unidireccional, entre el host y un endpoint
con transferencias tipo Bulk, Interrupción o Isócrono es decir los datos no están
estructurados como indica USB. En la Fig. 2.9 se puede observar la representación de una
Pipe de Stream.
23
Fig. 2.9 Pipe de Stream
En la Tabla 2.3 se muestran las características de cada tipo de pipe.
Tabla 2.3 Características de las Pipes.
24
Es importante definir el dispositivo USB en base a las clases, configuraciones, interfaces y
endpoint, de tal manera que un Dispositivo de USB es una colección de posibles
Configuraciones, cada Configuración es una colección de Interfaces y cada interfaz es una
colección de Endpoint.
Existen varias clases de dispositivos:
Clase de Dispositivos de Almacenamiento Masivo
Clase de Dispositivos de Impresión
Clase de Dispositivos de Comunicaciones
Clase de Dispositivos de Interconexión
Clase de Dispositivos de Interfaz Humano
Clase de Dispositivos de Tratamiento de Audio y video
2.8 Enumeración y descriptores de dispositivos.
Tal como se describió en la transferencia de control, cuando un dispositivo se conecta por
primera vez el controlador de host envía un paquete notificándole el número que le ha
asignado, esta es la enumeración que va desde 1 a 127 y en base a esto se puede leer el
descriptor que contiene la estructura de datos sobre el dispositivo y sus propiedades. Un
Descriptor es una estructura de datos que identifica toda la información descriptiva del
dispositivo al sistema
Existen cinco descriptores estándar:
Descriptor de Dispositivo: Describe información de carácter general sobre el dispositivo
USB y es único por dispositivo. Tiene la información que se aplica al dispositivo y a todas
sus posibles configuraciones.
Descriptor de Configuración: Describe información sobre una configuración específica.
Cada configuración tiene una o más interfaces y cada interfaz puede tener 0 o más
endpoints. Estos no son compartidos entre interfaces dentro de una misma configuración a
menos que el endpoint se utilice con configuraciones alternativas de la misma interfaz. Las
configuraciones pueden ser activadas usando una transferencia de control estándar
SET_CONFIGURATION.
Descriptor de Interfaz: Describe un interfaz específico dentro de una configuración. Un
interfaz puede incluir configuraciones alternativas que permiten a los endpoint variar
después de que el dispositivo haya sido configurado. La configuración por defecto es la
cero.
Para seleccionar las configuraciones alternativas puede hacerse uso de la transferencia
estándar SET_INTERFACE. Por ejemplo sobre un dispositivo multifunción tal como una
videocámara puede tener tres configuraciones alternativas, según se activen, la cámara, el
micrófono o ambos a la vez.
25
Descriptor de endpoint: Definen los requisitos de transmisión de cada dispositivo. El
endpoint cero se usa parta las transferencias de control y no hay descriptor para este.
Descriptores de cadenas: Son opcionales y proporcionan información adicional tal como
el nombre acerca del fabricante, del dispositivo o el número de serie. Estos descriptores
pueden ser vistos por las personas en formato Unicode.
2.9 Driver.
Como ya se comento el driver es el conjunto de instrucciones con las que se controla el
dispositivo y dado que un dispositivo puede estar formado por distintas interfaces, puede
ser necesario que un dispositivo precise varios drivers para controlarlos, luego es lógico que
exista un forma de localizar y asociar drivers a dispositivos e interfaces, de modo que se
simplifique el modelo común para los Sistemas Operativos y para los fabricantes de dichos
drivers.
Dado que los descriptores disponen de toda la información, es a ellos a los que hay que
acudir y la información a que se recurre dentro de la proporcionada por el driver es:
Fabricante, Producto y Versión del producto o Fabricante y Producto.
Continuando por:
Clase, Subclase y Protocolo o Clase y Subclase
Si no es localizado y el campo de Clase indica que pertenece a una Clase específica del
fabricante, es decir no es estándar USB entonces hay que navegar por datos de:
Fabricante, Subclase y Producto o Fabricante y Subclase.
En caso de no localizar ningún driver, el Sistema Operativo seleccionara una configuración
para el dispositivo y seguirá buscando un driver para cada interfaz que haya en dicha
configuración.
26
CAPITULO 3 “COMUNICACION DE UN SISTEMA DIGITAL CON LA PC”
3.1 Introducción.
En este capitulo se puede observar la realización de un software para poder comunicar un
sistema digital, basado en el microcontrolador PIC18F2550, con la PC a través del puerto
USB. Este sistema digital también puede recibir datos de un modulo receptor de RF para
enviarlos al PC y del PC recibe datos para enviarlos por un modulo transmisor de RF a otro
modulo receptor, situado en el helicóptero, para el control de los motores del helicóptero.
El software para el sistema digital se desarrollo con la ayuda del compilador de lenguaje C
de CCS, debido a la facilidad para lograr comunicación USB del PIC18F2550 con la PC y
también la poca complejidad del lenguaje C ya que es un lenguaje muy común.
3.2 Compilador C de CCS.
El compilador C de CCS ha sido desarrollado específicamente para programar PIC,
obteniendo la máxima optimización del compilador con estos dispositivos. Dispone de una
amplia librería de funciones predefinidas, programas de preprocesado y ejemplos. Además
suministra los drivers para diversos dispositivos como LCD, convertidores AD, relojes en
tiempo real, EEPROM serie, etc.
Un compilador convierte el lenguaje de alto nivel a instrucciones en código maquina; un
cross-compiler es un compilador que funciona en un procesador (normalmente en un PC)
diferente al procesador de objeto. El compilador CCS C es un cross-compiler. Los
programas son editados y compilados a instrucciones maquina en el entorno de trabajo del
PC, el código maquina puede ser cargado del PC al sistema PIC mediante cualquier
programador y puede ser depurado desde el entorno de trabajo del PC.
27
El CCS es C estándar y, además de las directivas estándar (#include, etc.), suministra unas
directivas especificas para PIC (#device, etc.); además incluye funciones especificas
(bit_set(), etc.). Se suministra con un editor que permite controlar la sintaxis del programa.
3.2.1 Estructura de un programa.
Para escribir un programa en C con el CCS C se deben tener en cuenta una serie de
elementos básicos de su estructura:
Directivas de procesado: controlan la conversión del programa a código maquina por parte
del compilador.
Programas o funciones: las funciones son bloques de sentencias; todas las sentencias se
deben enmarcar dentro de las funciones. Al igual que las variables, las funciones deben
definirse antes de utilizarse. Puede haber uno o varios; en cualquier caso siempre debe de
haber uno definido como principal en lenguaje C la función principal es la llamada main().
Una función puede ser llamada desde una sentencia de otra función. Una función puede
devolver un valor a la sentencia que la ha llamado. El tipo de dato se indica en la definición
de la función; en el caso de no indicarse nada se entiende que es un int8 y en el caso de no
devolver un valor se debe especificar el valor VOID. La función, además de devolver un
valor, puede recibir parámetros o argumentos.
La forma de devolver un valor es mediante la sentencia RETURN; donde la expresión debe
manejar el mismo tipo de dato que el indicado en la definición de la función. En el caso de
no devolver nada se finaliza con RETURN, al encontrar esta sentencia el compilador
vuelve a la ejecución de la sentencia de llamada. También se puede finalizar la función sin
RETURN, tan solo con la llave de cierre ”}”.
Instrucciones o Sentencias: indican como se debe comportar el PIC en todo momento.
Comentarios: los comentarios en el programa facilitan la comprensión de las distintas
expresiones tanto para el programa como para quien tiene que interpretar dicho programa.
No afectan a la compilación por lo que pueden ser tan extensos como el programador
quiera. Se pueden colocar en cualquier parte del programa y con dos formatos:
Utilizando // al colocar estos signos se comienza el comentario y finaliza en el final de la
línea.
Utilizando /* y */ se debe utilizar al inicio y al final de comentario respectivamente, pero
no pueden repetirse dentro del mismo comentario.
28
3.2.2 Tipos de datos.
En la Tabla 3.1 se pueden observar los tipos de datos que acepta el compilador C de CCS
Tipo Tamaño Rango Descripción
Int1
Short 1 bit 0 a 1 Entero de 1 bit
Int
Int8 8 bits 0 a 255 Entero
Int16
Long 16 bits 0 a 65535 Entero de 16 bits
Int32 32 bits 0 a 4294967295 Entero de 32 bits
Float 32 bits +1.175x10-38
a +3.402x1038
Coma flotante
char 8 bits 0 a 255 Carácter
void - - Sin valor
Signed Int8 8 bits -128 a +127 Entero con signo
Signed Int16 16 bits -32768 a +32767 Entero largo con signo
Signed Int32 32 bits -231
a +(231
-1) Entero 32 bits con signo
Tabla 3.1 Tipos de datos en C de CCS.
Las constantes se pueden especificar en decimal, octal, hexadecimal o en binario, en la
Tabla 3.2 se puede observar la forma de especificar constantes.
29
123 Decimal
0123 Octal (0)
0x123 Hexadecimal (0x)
0b010010 Binario (0b)
„x‟ Carácter
„\010‟ Carácter octal
„\xA5‟ Carácter hexadecimal
Tabla 3.2 Tipos de constantes.
Además se pueden definir constantes con sufijo, en la Tabla 3.3 se puede observar la forma
en que se definen las constantes.
Int8 127U
Long 80UL
Signed Int16 80L
Float 3.14F
Char Con comillas simples „C‟
Tabla 3.3 Definición de constantes.
También se definen caracteres especiales, en la Tabla 3.4 se puede observar algunos de
estos caracteres especiales.
\n Cambio de línea
\r Retorno de carro
\t Tabulación
\b Backspace
Tabla 3.4 Caracteres especiales.
30
3.2.3 USB CDC.
La interfaz serie RS-232 esta desapareciendo de los PC y esto se vuelve un problema, ya
que muchas de las aplicaciones con microcontroladores utilizan este bus para su
comunicación con el PC. La solución ideal es migrar a una interfaz USB y existen distintas
formas de hacerlo. El método más sencillo es emular RS-232 con el USB, con la ventaja de
que el PC vera la conexión USB como una conexión COM RS-232 y no requerirá cambios
en el software existente. Otra ventaja es que utilizan drivers suministrados por Windows,
por lo que no es necesario desarrollar uno; estos drivers son el usbser.sys y el ccport.sys.
Debido a que el protocolo USB maneja comunicaciones de bajo nivel, los conceptos baud
rate, bit de paridad y control de flujo para el RS-232 ya no importan.
La especificación Clase de Dispositivo de Comunicación (CDC) define algunos modelos de
comunicación, incluyendo la comunicación serie. Windows suministra el driver usber.sys
para esta especificación. Para la especificación CDC se necesitan dos interfaces USB,
primero la interfaz Communication Class usando un IN interrupt endpoint de interrupción y
el segundo es la interfaz Data Class usando un OUT bulk endpoint y un IN bulk endpoint.
Esta interfaz es utilizada para transferir los datos que normalmente deberían ser transferidos
a través de la interfaz RS-232.
Para permiten al sistema clasificar al dispositivo y asignarle un driver se necesita alguna
información dentro de los descriptores. La primera información que necesita es la del
fabricante y producto (USB vendor ID-VID y el product ID-PID). El VIP es un numero de
16 bits asignado por el USB implementers product (USB-IF) y debe ser obtenido por el
fabricante del dispositivo USB; cada VID puede contener 65536 PID diferentes al ser
también un numero de 16 bits. Microchip suministra su VIP y los PID para cada familia de
PIC con USB.
Microsoft Windows (2000 o XP) no tiene un archivo *.inf estándar para el driver CDC, así
que es necesario suministrar este archivo cuando se conecta un dispositivo USB por
primera vez al sistema. Microchip suministra el archivo mchpcdc.inf necesario para sus
dispositivos PIC.
CCS suministra librerías para comunicar PIC con el PC utilizando el bus USB mediante
periféricos internos (familia PIC18F2550, PIC18F4550 o el PIC16C765) o mediante
dispositivos externos al PIC (del tipo USBN9603).
Las librerías suministradas son:
Pic_usb.h: driver de la familia PIC16 C765.
Pic_18usb.h: driver de la familia PIC18F4550.
31
Usbn960x.h: driver para el dispositivo externo USBN9603/USBN9604. De esta
forma, se pude utilizar el bus en cualquier PIC.
Usb.h: definiciones y prototipos utilizados en el driver USB.
Usb.c: El USB stack, que maneja las interrupciones USB y el USB Setup Requests
en Endpoint 0.
Usb_cdc.h: driver que permite utilizar una clase de dispositivo CDC USB,
emulando un dispositivo RS-232 y lo muestra como un puerto COM en Windows.
Las funciones más importantes son:
Usb_init(): Inicializa el hardware USB. Espera en un bucle infinito hasta que el periférico
USB es conectado al bus (aunque eso no significa que ha sido enumerado por el PC).
Habilita y utiliza la interrupción USB.
Usb_task(): Si se utiliza una detección de conexión para la inicialización, entonces se debe
llamar periódicamente a esta función para controlar el pin de detección de conexión.
Cuando el PIC es conectado o desconectado del bus, esta función inicializa el puerto USB o
resetea el USB stack y el puerto.
Usb_enumerated(): Devuelve un TRUE si el dispositivo ha sido enumerado por el PC y, en
este caso, el dispositivo entra en un modo de operación normal y puede enviar y recibir
paquetes de datos.
Usb_cdc_putc(): Es idéntica a putc() y envía un carácter. Coloca un carácter en el buffer de
transmisión; en el caso de que este lleno esperara hasta que pueda enviarlo.
3.3 Programación del PIC18F2550.
Para lograr la comunicación por USB se utiliza el PIC18F2550. El total de ancho de banda
que posee el bus de este dispositivo es de 1.5Mbps, pero es imposible que el PIC se
comunique con el Host a esa velocidad debido a que hay perdidas de tiempo por el
protocolo, otros periféricos conectados al Host, incluso perdidas de tiempo en
comportamiento del PIC ya que este también recibe y envía datos a módulos de RF, etc. En
la mayoría de los casos nos vamos a poder comunicar a 64Kbps.
La distribución de pines del PIC18F2550 se puede observar en la Fig. 3.1.
32
Fig. 3.1 PIC18F2550
El programa realizado en C CCS hace que el PIC se comunique con la PC por USB
enviando y recibiendo datos, al recibir datos desde la PC los envía por un modulo de RF y a
través del puerto B recibe el valor del sensor de distancia el cual es mandado al PC para su
procesamiento. Este programa se explicara en dos partes:
Configuracion PIC.
Funciones.
3.3.1 Configuración PIC.
En esta parte veremos la configuración del PIC detallando librerías y fuses que se utilizan.
A continuación se muestra el código de configuración:
#include <18F2550.h>
#fuses HSPLL, MCLR, NOWDT, NOPROTECT, NOLVP, NODEBUG, USBDIV, PLL3, CPUDIV1,
VREGEN, NOPBADEN
#use delay(clock=48000000)
#include "usb_cdc.h"
#include "usb_desc_cdc.h"
int8 motor1, motor2; //variables globales
Para la definición de registros internos del PIC se utiliza la librería #include<18F2550.h>.
Primero se necesita configurar los fuses del PIC. A continuación se detalla cada uno de
ellos:
33
HSPLL: Se utiliza un cristal HS de alta velocidad, en conjunto con el PLL para
generar los 48Mhz de operación del dispositivo.
MCLR: Se utiliza reset por hardware. Este pin se puede activar o desactivar en caso
de que se necesite el pin para otras funciones pero solamente se podrá usar como
entrada.
NOWDT: No se utiliza el Watchdog.
NOPROTECT: Se desactiva la protección de código contra lecturas.
NOLVP: Se desactiva la programación a bajo voltaje.
NODEBUG: No se utiliza el modo debug.
USBDIV: Este bit puede ser 1 o 0 y con el se selecciona la fuente de oscilación del
periférico USB, utilizando la frecuencia del cristal seleccionado o del PLL/2. En
este caso significa que el clock del usb se tomará del PLL/2 = 96MHz/2 = 48MHz.
PLL3: Aquí se selecciona el factor de división del postcaler, el mismo se
seleccionará teniendo en cuenta el valor del cristal que se utiliza. Se necesitan
4MHz en la entrada del PLL para que este genere 96MHz. En este caso se utiliza un
cristal de 12MHz por lo que el factor de división va a ser 3. Significa que el PLL
prescaler dividirá en 3 la frecuencia del cristal para generar 4MHz: HS = 12Mhz/3 =
4MHz.
CPUDIV1: El PLL postscaler decide la división en 2 de la frecuencia de salida del
PLL de 96MHZ, como se requiere 48MHZ se deja como está.
VREGEN: Se utiliza para habilitar el regulador interno de 3.3v para el puerto USB,
en caso de que se este usando el USB interno, pero en caso de que estemos usando
un controlador externo se desactiva este bit y se utiliza una fuente externa. En este
caso se habilita el regulador de 3.3 volts que usa el módulo USB.
NOPBADEN: No se utilizan las entradas analógicas del puerto B por lo que el
puerto B queda como I/O digital.
Con #use delay(clock=48000000) se determina la frecuencia máxima de trabajo del PIC en
este caso debe ser de 48MHz.
La librería #include "usb_cdc.h" describe las funciones que incluye el compilador para
lograr comunicación USB.
La librería #include "usb_desc_cdc.h" describe el dispositivo USB y este contiene el VID,
el PID y el nombre del dispositivo. A continuación se muestra el código de esta librería:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//// usb_desc_cdc.h ////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//// Bulk endpoint sizes updated to allow more than 255 byte packets. ////
//// Changed device to USB 1.10 ////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
#IFNDEF __USB_DESCRIPTORS__
#DEFINE __USB_DESCRIPTORS__
#include <usb.h>
34
//////////////////////////////////////////////////////////////////
///
/// start config descriptor
/// right now we only support one configuration descriptor.
/// the config, interface, class, and endpoint goes into this array.
///
//////////////////////////////////////////////////////////////////
#DEFINE USB_TOTAL_CONFIG_LEN 67 //config+interface+class+endpoint+endpoint (2 endpoints)
const char USB_CONFIG_DESC[] = {
//IN ORDER TO COMPLY WITH WINDOWS HOSTS, THE ORDER OF THIS ARRAY MUST BE:
// config(s)
// interface(s)
// class(es)
// endpoint(s)
//config_descriptor for config index 1
USB_DESC_CONFIG_LEN, //length of descriptor size ==0
USB_DESC_CONFIG_TYPE, //constant CONFIGURATION (CONFIGURATION 0x02) ==1
USB_TOTAL_CONFIG_LEN,0, //size of all data returned for this config ==2,3
2, //number of interfaces this device supports ==4
0x01, //identifier for this configuration. (IF we had more than one configurations) ==5
0x00, //index of string descriptor for this configuration ==6
0xC0, //bit 6=1 if self powered, bit 5=1 if supports remote wakeup (we don't), bits 0-4 unused and
bit7=1 ==7
0x32, //maximum bus power required (maximum milliamperes/2) (0x32 = 100mA) ==8
//interface descriptor 0 (comm class interface)
USB_DESC_INTERFACE_LEN, //length of descriptor =9
USB_DESC_INTERFACE_TYPE, //constant INTERFACE (INTERFACE 0x04) =10
0x00, //number defining this interface (IF we had more than one interface) ==11
0x00, //alternate setting ==12
1, //number of endpoints ==13
0x02, //class code, 02 = Comm Interface Class ==14
0x02, //subclass code, 2 = Abstract ==15
0x01, //protocol code, 1 = v.25ter ==16
0x00, //index of string descriptor for interface ==17
//class descriptor [functional header]
5, //length of descriptor ==18
0x24, //dscriptor type (0x24 == ) ==19
0, //sub type (0=functional header) ==20
0x10,0x01, // ==21,22 //cdc version
//class descriptor [acm header]
4, //length of descriptor ==23
0x24, //dscriptor type (0x24 == ) ==24
2, //sub type (2=ACM) ==25
2, //capabilities ==26 //we support Set_Line_Coding, Set_Control_Line_State, Get_Line_Coding, and
the notification Serial_State.
//class descriptor [union header]
5, //length of descriptor ==27
0x24, //dscriptor type (0x24 == ) ==28
6, //sub type (6=union) ==29
0, //master intf ==30 //The interface number of the Communication or Dat a Cl ass interface,
designated as the masteror controlling interface for the union.
1, //save intf0 ==31 //Interface number of first slave or associated interface in the union. *
//class descriptor [call mgmt header]
5, //length of descriptor ==32
0x24, //dscriptor type (0x24 == ) ==33
1, //sub type (1=call mgmt) ==34
35
0, //capabilities ==35 //device does not handle call management itself
1, //data interface ==36 //interface number of data class interface
//endpoint descriptor
USB_DESC_ENDPOINT_LEN, //length of descriptor ==37
USB_DESC_ENDPOINT_TYPE, //constant ENDPOINT (ENDPOINT 0x05) ==38
USB_CDC_COMM_IN_ENDPOINT | 0x80, //endpoint number and direction
0x03, //transfer type supported (0x03 is interrupt) ==40
USB_CDC_COMM_IN_SIZE,0x00, //maximum packet size supported ==41,42
250, //polling interval, in ms. (cant be smaller than 10) ==43
//interface descriptor 1 (data class interface)
USB_DESC_INTERFACE_LEN, //length of descriptor =44
USB_DESC_INTERFACE_TYPE, //constant INTERFACE (INTERFACE 0x04) =45
0x01, //number defining this interface (IF we had more than one interface) ==46
0x00, //alternate setting ==47
2, //number of endpoints ==48
0x0A, //class code, 0A = Data Interface Class ==49
0x00, //subclass code ==50
0x00, //protocol code ==51
0x00, //index of string descriptor for interface ==52
//endpoint descriptor
USB_DESC_ENDPOINT_LEN, //length of descriptor ==60
USB_DESC_ENDPOINT_TYPE, //constant ENDPOINT (ENDPOINT 0x05) ==61
USB_CDC_DATA_OUT_ENDPOINT, //endpoint number and direction (0x02 = EP2 OUT) ==62
0x02, //transfer type supported (0x02 is bulk) ==63
// make8(USB_CDC_DATA_OUT_SIZE,0),make8(USB_CDC_DATA_OUT_SIZE,1), //maximum
packet size supported ==64, 65
USB_CDC_DATA_OUT_SIZE & 0xFF, (USB_CDC_DATA_OUT_SIZE >> 8) & 0xFF, //maximum
packet size supported ==64, 65
250, //polling interval, in ms. (cant be smaller than 10) ==66
//endpoint descriptor
USB_DESC_ENDPOINT_LEN, //length of descriptor ==53
USB_DESC_ENDPOINT_TYPE, //constant ENDPOINT (ENDPOINT 0x05) ==54
USB_CDC_DATA_IN_ENDPOINT | 0x80, //endpoint number and direction (0x82 = EP2 IN) ==55
0x02, //transfer type supported (0x02 is bulk) ==56
// make8(USB_CDC_DATA_IN_SIZE,0),make8(USB_CDC_DATA_IN_SIZE,1), //maximum packet
size supported ==57, 58
USB_CDC_DATA_IN_SIZE & 0xFF, (USB_CDC_DATA_IN_SIZE >> 8) & 0xFF, //maximum packet
size supported ==64, 65
250, //polling interval, in ms. (cant be smaller than 10) ==59
};
//****** BEGIN CONFIG DESCRIPTOR LOOKUP TABLES ********
//since we can't make pointers to constants in certain pic16s, this is an offset table to find
// a specific descriptor in the above table.
//the maximum number of interfaces seen on any config
//for example, if config 1 has 1 interface and config 2 has 2 interfaces you must define this as 2
#define USB_MAX_NUM_INTERFACES 2
//define how many interfaces there are per config. [0] is the first config, etc.
const char USB_NUM_INTERFACES[USB_NUM_CONFIGURATIONS]={2};
//define where to find class descriptors
//first dimension is the config number
//second dimension specifies which interface
//last dimension specifies which class in this interface to get, but most will only have 1 class per interface
//if a class descriptor is not valid, set the value to 0xFFFF
const int16
USB_CLASS_DESCRIPTORS[USB_NUM_CONFIGURATIONS][USB_MAX_NUM_INTERFACES][4]=
{
36
//config 1
//interface 0
//class 1-4
18,23,27,32,
//interface 1
//no classes for this interface
0xFFFF,0xFFFF,0xFFFF,0xFFFF
};
#if (sizeof(USB_CONFIG_DESC) != USB_TOTAL_CONFIG_LEN)
#error USB_TOTAL_CONFIG_LEN not defined correctly
#endif
//////////////////////////////////////////////////////////////////
///
/// start device descriptors
///
//////////////////////////////////////////////////////////////////
const char USB_DEVICE_DESC[USB_DESC_DEVICE_LEN] ={
//starts of with device configuration. only one possible
USB_DESC_DEVICE_LEN, //the length of this report ==0
0x01, //the constant DEVICE (DEVICE 0x01) ==1
0x10,0x01, //usb version in bcd ==2,3
0x02, //class code. 0x02=Communication Device Class ==4
0x00, //subclass code ==5
0x00, //protocol code ==6
USB_MAX_EP0_PACKET_LENGTH, //max packet size for endpoint 0. (SLOW SPEED SPECIFIES
8) ==7
0xD8,0x04, //vendor id (0x04D8 is Microchip, or is it 0x0461 ??) ==8,9
0x0B,0x00, //product id ==10,11
0x00,0x01, //device release number ==12,13
0x01, //index of string description of manufacturer. therefore we point to string_1 array (see below)
==14
0x02, //index of string descriptor of the product ==15
0x00, //index of string descriptor of serial number ==16
USB_NUM_CONFIGURATIONS //number of possible configurations ==17
};
//////////////////////////////////////////////////////////////////
///
/// start string descriptors
/// String 0 is a special language string, and must be defined. People in U.S.A. can leave this alone.
///
/// You must define the length else get_next_string_character() will not see the string
/// Current code only supports 10 strings (0 thru 9)
///
//////////////////////////////////////////////////////////////////
//the offset of the starting location of each string. offset[0] is the start of string 0, offset[1] is the start of string
1, etc.
char USB_STRING_DESC_OFFSET[]={0,4,12};
char const USB_STRING_DESC[]={
//string 0
4, //length of string index
USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING)
0x09,0x04, //Microsoft Defined for US-English
//string 1
8, //length of string index
USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING)
'C',0,
37
'C',0,
'S',0,
//string 2
24, //length of string index
USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING)
'C',0,
'D',0,
'C',0,
'_',0,
'U',0,
'S',0,
'B',0,
'_',0,
'P',0,
'I',0,
'C',0,
};
#ENDIF
3.3.2 Funciones.
Este programa solo hay tres funciones, dos para enviar datos a través del modulo RF y la
función principal (main()). A continuación se describe cada función:
Función void clave(void)
Esta función se utiliza para comunicar el receptor y el transmisor del modulo de RF
mediante una clave de reconocimiento y sincronización.
void clave(void)
{
output_high(PIN_A2); //pone en alto el pin 2 del Puerto A.
Delay_us(350); // tiempo de espera para la sincronización.
output_low(PIN_A2);
Delay_us(350);
output_high(PIN_A2);
Delay_us(350);
output_low(PIN_A2);
Delay_us(350);
output_high(PIN_A2);
Delay_us(350);
output_low(PIN_A2);
Delay_us(350);
}
Función void datamotor(void)
Esta función se utiliza para enviar los datos recibidos, por el PIC desde la PC, hacia el
modulo de RF para el control de los motores. Este dato se envía bit por bit por lo que si un
38
bit es “1” pone el pin en alto y si es “0” pone el pin en bajo con cierto tiempo de espera
entre bit y bit.
void datamotor(void)
{
// valor para el motor 1
if (bit_test(motor1, 7)==1){
output_high(PIN_A2);
Delay_us(350);
}
else
{
output_low(PIN_A2);
Delay_us(350);
}
if (bit_test(motor1, 6)==1){
output_high(PIN_A2);
Delay_us(350);
}
else
{
output_low(PIN_A2);
Delay_us(350);
}
if (bit_test(motor1, 5)==1){
output_high(PIN_A2);
Delay_us(350);
}
else
{
output_low(PIN_A2);
Delay_us(350);
}
if (bit_test(motor1, 4)==1){
output_high(PIN_A2);
Delay_us(350);
}
else
{
output_low(PIN_A2);
Delay_us(350);
}
if (bit_test(motor1, 3)==1){
output_high(PIN_A2);
Delay_us(350);
}
else
{
output_low(PIN_A2);
Delay_us(350);
}
if (bit_test(motor1, 2)==1){
output_high(PIN_A2);
Delay_us(350);
39
}
else
{
output_low(PIN_A2);
Delay_us(350);
}
if (bit_test(motor1, 1)==1){
output_high(PIN_A2);
Delay_us(350);
}
else
{
output_low(PIN_A2);
Delay_us(350);
}
if (bit_test(motor1, 0)==1){
output_high(PIN_A2);
Delay_us(350);
}
else
{
output_low(PIN_A2);
Delay_us(350);
}
// valor para el motor 2
if (bit_test(motor2, 7)==1){
output_high(PIN_A2);
Delay_us(350);
}
else
{
output_low(PIN_A2);
Delay_us(350);
}
if (bit_test(motor2, 6)==1){
output_high(PIN_A2);
Delay_us(350);
}
else
{
output_low(PIN_A2);
Delay_us(350);
}
if (bit_test(motor2, 5)==1){
output_high(PIN_A2);
Delay_us(350);
}
else
{
output_low(PIN_A2);
Delay_us(350);
}
if (bit_test(motor2, 4)==1){
output_high(PIN_A2);
Delay_us(350);
}
40
else
{
output_low(PIN_A2);
Delay_us(350);
}
if (bit_test(motor2, 3)==1){
output_high(PIN_A2);
Delay_us(350);
}
else
{
output_low(PIN_A2);
Delay_us(350);
}
if (bit_test(motor2, 2)==1){
output_high(PIN_A2);
Delay_us(350);
}
else
{
output_low(PIN_A2);
Delay_us(350);
}
if (bit_test(motor2, 1)==1){
output_high(PIN_A2);
Delay_us(350);
}
else
{
output_low(PIN_A2);
Delay_us(350);
}
if (bit_test(motor2, 0)==1){
output_high(PIN_A2);
Delay_us(350);
}
else
{
output_low(PIN_A2);
Delay_us(350);
}
}
Función principal void main()
Esta función contiene el programa principal, desde esta función se hacen llamadas a las
funciones anteriores para la transmisión a través del modulo de RF y también se hacen
llamadas al los buffer de escritura y lectura del puerto USB.
void main() {
int16 envia, Rep;
int1 a,b;
41
Rep=0;
motor1=0;
motor2=0;
SET_TRIS_B( 0xFF );
SET_TRIS_A( 0xF0 );
usb_cdc_init(); // Funciones necesarias para iniciar el módulo USB.
usb_init(); // Funciones necesarias para iniciar el módulo USB.
while(!usb_cdc_connected()) { // Mientras el USB no esté conectado.
output_high(PIN_A0); // El USB no se ha conectado. (Enciende LED rojo)
output_low(PIN_A1); // (Apaga LED verde)
}
output_high(PIN_A1); // Se ha conectado el USB. (Enciende LED verde)
output_low(PIN_A0); // (Apaga LED rojo)
do{
usb_task();
if (usb_enumerated()){ // Si el puerto ya fue enumerado por el host :
if(usb_cdc_kbhit()){ // en espera de nuevo caracter en el buffer.
envia= input_B(); // recibe valor del sensor de distancia a traves del Puerto B
if(input(pin_A5))
bit_set(envia, 8);
else
bit_clear(envia, 8);
if(input(pin_A4))
bit_set(envia, 9);
else
bit_clear(envia, 9);
if(envia!=Rep){
printf(usb_cdc_putc, "%04Lu", envia); // el dato se envia por USB
Rep=envia;
}
motor1 = usb_cdc_getc(); // recibe dato del Puerto USB
motor2= motor1/2;
clave(); // comienza la transmisión por RF para control del helicoptero
datamotor();
output_low(PIN_A2);
Delay_us(1400);
clave();
datamotor();
output_low(PIN_A2);
Delay_us(1400);
clave();
datamotor();
output_low(PIN_A2);
Delay_us(1400);
}
}
}while (TRUE); // ciclo eterno
}
3.4 Circuito del Sistema Digital.
Este circuito esta basado en el PIC18F2550, como ya se ha mencionado, el cual cuenta con
modulo USB y tres puertos. A través del puerto B y los pines 4 y 5 del puerto A recibe el
valor del sensor de distancia, desde el modulo receptor de RF, se utilizan 10 bits debido a
42
que las conversiones Analógico-Digital en los PIC‟s se hacen en registros de 10 bits. Para
poder controlar los motores del helicóptero se envían los datos bit a bit por el pin A2 el cual
esta conectado a un modulo transmisor de RF. En el puerto C se encuentra el USB con el
cual se hace la comunicación con el PC. En la Fig. 3.2 se muestra el diagrama del circuito
del sistema digital.
Fig. 3.2 Diagrama del Sistema digital.
43
CAPITULO 4 “COMUNICACIÓN DE LA PC CON UN SISTEMA DIGITAL”
4.1 Introducción.
Para la realización de la comunicación de la PC con el sistema Digital se utiliza Visual
Basic 6.0, para crear una aplicación, la cual se comunica con el puerto USB como si fuera
un puerto COM RS-232 debido a que el PIC se ha programado para realizar la emulación
de RS-232 con el puerto USB. La aplicación realizada en Visual Basic 6.0 se comunica con
el puerto USB para recibir y transmitir datos. Cuando reciba un dato este será procesado
para determinar el valor de la distancia arrojada por el sensor y este valor será procesado
por un algoritmo de control PI (proporcional-integral) para mejorar la respuesta del sistema.
Al algoritmo de control se le pueden modificar las constantes de control para poder obtener
diferentes respuestas. Una vez obtenida la respuesta del algoritmo de control se envía este
dato para poder controlar los motores variando su velocidad para aumentar o disminuir la
altura del helicóptero. En este capitulo primero se explica el entorno de Visual Basic y
después la aplicación creada para la comunicación por USB con el Sistema Digital
4.2 Visual Basic 6.0.
Visual Basic 6.0 es una excelente herramienta de programación que permite crear
aplicaciones propias (programas) para Windows 95/98 o Windows NT. Con ella se puede
crear desde una simple calculadora hasta una hoja de cálculo de la talla de Excel (en sus
primeras versiones...), pasando por un procesador de textos o cualquier otra aplicación que
se le ocurra al programador. Sus aplicaciones en Ingeniería son casi ilimitadas:
representación de movimientos mecánicos o de funciones matemáticas, gráficas
termodinámicas, simulación de circuitos, etc.
Este programa permite crear ventanas, botones, menús y cualquier otro elemento de
Windows de una forma fácil e intuitiva. El lenguaje de programación que se utiliza es el
Basic.
44
Visual Basic 6.0 es un lenguaje de programación visual, también llamado lenguaje de 4ª
generación. Esto quiere decir que un gran número de tareas se realizan sin escribir código,
simplemente con operaciones gráficas realizadas con el ratón sobre la pantalla.
Visual Basic 6.0 es también un programa basado en objetos, aunque no orientado a objetos
como C++ o Java. La diferencia está en que Visual Basic 6.0 utiliza objetos con
propiedades y métodos, pero carece de los mecanismos de herencia y polimorfismo propios
de los verdaderos lenguajes orientados a objetos como Java y C++.
Existen distintos tipos de programas. En los primeros tiempos de los ordenadores los
programas eran de tipo secuencial (también llamados tipo batch) Un programa secuencial
es un programa que se arranca, lee los datos que necesita, realiza los cálculos e imprime o
guarda en el disco los resultados. Mientras un programa secuencial está ejecutándose no
necesita ninguna intervención del usuario, a este tipo de programas se les llama también
programas basados u orientados a procedimientos o a algoritmos (procedural languages).
Este tipo de programas siguen utilizándose ampliamente en la actualidad, pero la difusión
de los PCs ha puesto de actualidad otros tipos de programación.
Los programas interactivos exigen la intervención del usuario en tiempo de ejecución, para
suministrar datos o para indicar al programa lo que debe hacer por medio de menús. Los
programas interactivos limitan y orientan la acción del usuario. Un ejemplo de programa
interactivo podría ser Matlab.
Por su parte los programas orientados a eventos son los programas típicos de Windows,
tales como Netscape, Word, Excel y PowerPoint. Cuando uno de estos programas ha
arrancado, lo único que hace es quedarse a la espera de las acciones del usuario, que en este
caso son llamadas eventos.
El usuario dice si quiere abrir y modificar un archivo existente, o si quiere crear un archivo
desde el principio. Estos programas pasan la mayor parte de su tiempo esperando las
acciones del usuario (eventos) y respondiendo a ellas. Estos programas requieren de un tipo
especial de programación “la programación orientada a eventos”. Este tipo de
programación es más complicada que la secuencial y la interactiva, pero Visual Basic 6.0 la
hace sencilla.
Visual Basic 6.0 está orientado a la realización de programas para Windows, pudiendo
incorporar todos los elementos de este entorno: ventanas, botones, cajas de diálogo y de
texto, botones de opción y de selección, barras de desplazamiento, gráficos, menús, etc.
Prácticamente todos los elementos de interacción con el usuario de los que dispone
Windows 95/98/NT pueden ser programados en Visual Basic 6.0 de un modo muy sencillo.
En ocasiones bastan unas pocas operaciones con el ratón y la introducción a través del
teclado de algunas instrucciones para disponer de aplicaciones con todas las características
de Windows 95/98/NT.
4.2.1 Modo de diseño y modo de ejecución.
45
La aplicación Visual Basic de Microsoft puede trabajar de dos modos distintos: en modo de
diseño y en modo de ejecución. En modo de diseño el usuario construye interactivamente la
aplicación, colocando controles en el formulario, definiendo sus propiedades, y
desarrollando funciones para gestionar los eventos.
La aplicación se prueba en modo de ejecución. En ese caso el usuario actúa sobre el
programa (introduce eventos) y prueba cómo responde el programa. Hay algunas
propiedades de los controles que deben establecerse en modo de diseño, pero muchas otras
pueden cambiarse en tiempo de ejecución desde el programa escrito en Visual Basic 6.0.
También hay propiedades que sólo pueden establecerse en modo de ejecución y que no son
visibles en modo de diseño.
4.2.2 Formularios y Controles.
Cada uno de los elementos gráficos que pueden formar parte de una aplicación típica de
Windows 95/98/NT es un tipo de control: los botones, las cajas de diálogo y de texto, las
cajas de selección desplegables, los botones de opción y de selección, las barras de
desplazamiento horizontales y verticales, los gráficos, los menús, y muchos otros tipos de
elementos son controles para Visual Basic 6.0. Cada control debe tener un nombre a través
del cual se puede hacer referencia a él en el programa.
En la terminología de Visual Basic 6.0 se llama formulario (form) a una ventana. Un
formulario puede ser considerado como una especie de contenedor para los controles. Una
aplicación puede tener varios formularios, pero un único formulario puede ser suficiente
para las aplicaciones más sencillas. Los formularios deben también tener un nombre, que
puede crearse siguiendo las mismas reglas que para los controles.
4.2.3 Objetos y Propiedades.
Los formularios y los distintos tipos de controles son entidades genéricas de las que puede
haber varios ejemplares concretos en cada programa. En programación basada en objetos se
llama clase a estas entidades genéricas, mientras que se llama objeto a cada ejemplar de una
clase determinada. Por ejemplo, en un programa puede haber varios botones, cada uno de
los cuales es un objeto del tipo de control command button, que sería la clase.
Cada formulario y cada tipo de control tienen un conjunto de propiedades que definen su
aspecto gráfico (tamaño, color, posición en la ventana, tipo y tamaño de letra, etc.) y su
forma de responder a las acciones del usuario (si está activo o no, por ejemplo). Cada
propiedad tiene un nombre que viene ya definido por el lenguaje.
Por lo general, las propiedades de un objeto son datos que tienen valores lógicos (True,
False) o numéricos concretos, propios de ese objeto y distintos de las de otros objetos de su
clase. En pocas palabras cada clase, tipo de objeto o control tiene su conjunto de
propiedades, y cada objeto o control tiene valores determinados para las propiedades de su
clase.
46
Casi todas las propiedades de los objetos pueden establecerse en tiempo de diseño y
también en tiempo de ejecución. En este segundo caso se accede a sus valores por medio de
las instrucciones del programa, en forma análoga a como se accede a cualquier variable en
un lenguaje de programación. Para ciertas propiedades ésta es la única forma de acceder a
ellas.
Se puede acceder a una propiedad de un objeto por medio del nombre del objeto a que
pertenece, seguido de un punto y el nombre de la propiedad, como por ejemplo
optColor.objName.
4.2.4 Nombres de objetos.
En principio cada objeto de Visual Basic 6.0 debe tener un nombre, por medio del cual se
hace referencia a dicho objeto. El nombre puede ser el que el usuario desee, e incluso
Visual Basic 6.0 proporciona nombres por default para los diversos controles. Estos
nombres por default hacen referencia al tipo de control y van seguidos de un número que se
incrementa a medida que se van introduciendo más controles de ese tipo en el formulario
(por ejemplo VScroll1, para una barra de desplazamiento -scroll bar- vertical, HScroll1,
para una barra horizontal, etc.).
Existe una convención ampliamente aceptada que es la siguiente: se utilizan siempre tres
letras minúsculas que indican el tipo de control, seguidas por otras letras (la primera
mayúscula, a modo de separación) libremente escogidas por el usuario, que tienen que
hacer referencia al uso que se va a dar a ese control. La Tabla 4.1 muestra las abreviaturas
de los controles más usuales, junto con la nomenclatura inglesa de la que derivan.
47
Abreviatura Control Abreviatura Control
chk Check box cbo Combo y drop-list box
cmd Command button dir Dir list box
drv Drive list box fil File list box
frm form fra frame
hsb Horizontal scroll bar img image
lbl label lin Line
lst list mnu menu
opt Option button pct Picture box
shp shape txt Text edit box
tmr timer vsb Vertical scroll bar
Tabla 4.1 Abreviaciones de controles.
4.2.5 Eventos.
Ya se ha dicho que las acciones del usuario sobre el programa se llaman eventos. Son
eventos típicos el clicar sobre un botón, el hacer doble clic sobre el nombre de un archivo
para abrirlo, el arrastrar un icono, el pulsar una tecla o combinación de teclas, el elegir una
opción de un menú, el escribir en una caja de texto, o simplemente mover el ratón.
Cada vez que se produce un evento sobre un determinado tipo de control, Visual Basic 6.0
arranca una determinada función o procedimiento que realiza la acción programada por el
usuario para ese evento concreto. Estos procedimientos se llaman con un nombre que se
forma a partir del nombre del objeto y el nombre del evento, separados por el carácter (_),
como por ejemplo txtBox_click, que es el nombre del procedimiento que se ocupará de
responder al evento click en el objeto txtBox.
4.2.6 Métodos.
Los métodos son funciones que también son llamadas desde programa, pero a diferencia de
los procedimientos no son programadas por el usuario, sino que vienen ya pre-programadas
con el lenguaje. Los métodos realizan tareas típicas, previsibles y comunes para todas las
aplicaciones. De ahí que vengan con el lenguaje y que se libere al usuario de la tarea de
programarlos. Cada tipo de objeto o de control tiene sus propios métodos.
48
Por ejemplo, los controles gráficos tienen un método llamado Line que se encarga de
dibujar líneas rectas. De la misma forma existe un método llamado Circle que dibuja
circunferencias y arcos de circunferencia.
4.2.7 Tipos de datos.
Al igual que C y otros lenguajes de programación, Visual Basic dispone de distintos tipos
de datos, aplicables tanto para constantes como para variables. La Tabla 4.2 muestra los
tipos de datos disponibles en Visual Basic.
Tipo Descripción Carácter de
declaración
Intervalo
Boolean Binario True o False
Byte Entero corto 0 a 255
Integer Entero (2 bytes) % -32768 a 32767
Long Entero largo (4 bytes) & -2147483648 a
2147483647
Single Real simple precisión (4 bytes) ! -3.4E+38 a 3.4E+38
Double Real doble precisión (8 bytes) # -1.79D+308 a
1.79D+308
Currency Numero con punto decimal fijo (8
bytes)
@ -9.22E+14 a
9.22E+14
String Cadena de caracteres (4bytes + 1
byte/car hasta 64K)
$ 0 a 65500 caracteres
Tabla 4.2 Tipos de datos en Visual Basic.
4.2.8 Creación de programas ejecutables.
Una vez finalizada la programación de la nueva aplicación, la siguiente tarea suele consistir
en la creación de un programa ejecutable para su distribución e instalación en cuantos
ordenadores se desee, incluso aunque en ellos no esté instalado Visual Basic 6.0.
Para crear un programa ejecutable se utiliza el comando Make nombreProyecto.exe … en
el menú File. De esta manera se generará un archivo cuya extensión será *.exe. Para que
este programa funcione en un ordenador solamente se necesita que el archivo
MSVBVM60.DLL esté instalado en el directorio c:\Windows\System o
49
c:\Winnt\System32. En el caso de proyectos más complejos en los que se utilicen muchos
controles pueden ser necesarios más archivos, la mayoría de ellos con extensiones *.ocx,
*.vbx o *.dll. Para saber en cada caso cuáles son los archivos necesarios se puede consultar
el archivo *.vbp que contiene la descripción completa del proyecto. Casi todos esos
archivos necesarios se instalan automáticamente al instalar el compilador de Visual Basic
6.0 en el ordenador.
4.3 Desarrollo de aplicación en Visual Basic 6.0.
Como se explico anteriormente, para desarrollar programas ejecutables en Visual Basic, se
trabaja en dos pantallas, las cuales explicaremos por separado:
Pantalla de controles.
Pantalla de Código.
4.3.1 Pantalla de Controles.
En la Fig. 4.1 se puede observar la pantalla de controles de la aplicación realizada en Visual
Basic 6.0.
Fig. 4.1 Pantalla de controles.
50
A continuación se explicara cada elemento de la pantalla de controles y algunas de sus
propiedades:
Estos dos elementos se utilizan para la conexión del puerto el
primero es un combo box en el cual se muestra una lista de los posibles puertos a los cuales
se le puede asignar el sistema digital y el segundo es un Comand button, con el cual
después de haber seleccionado el puerto en el combo box, se empieza la conexión teniendo
acceso al puerto. El Comand button produce un evento en el cual se configura la conexión.
Como el puerto USB es visto como un puerto COM es necesario insertar un control
MSComm. Este se configura para un Baud rate de 9600, sin paridad, 8 bits de datos y 1 bit
de paro.
Se utiliza un Timer para un mejor control del programa durante el tiempo en que no
ocurren nuevos eventos. La configuración de este Timer se realiza en la pantalla de código.
Para poder monitorear la conexión entre el puerto USB y el
sistema digital se utiliza un indicador, el cual se muestra de color rojo cuando no se
establece comunicación con el sistema digital y de color verde cuando hay comunicación
con el sistema digital.
Estos dos cuadros de texto muestran el
dato arrojado por el sensor de distancia, en el primero se muestra el valor de la distancia en
cm y en el segundo se muestra el valor asignado por el convertidor Analógico-Digital a el
valor de voltaje generado por sensor.
En este cuadro de texto el usuario debe indicar la altura en
cm, a la cual se desea que este el helicóptero.
51
En este cuadro de texto el usuario debe indicar el valor de la constante
del control proporcional que se desea.
En este cuadro de texto el usuario debe indicar el valor de la constante
del control integral que se desea.
En este cuadro de texto se muestra el valor arrojado por el algoritmo de
control PI y con el cual se activaran los motores del helicóptero.
Este Comand button genera un evento con el cual se cierra la
aplicación y se finaliza la conexión con el sistema digital.
4.3.2 Pantalla de Código.
En esta pantalla se encuentra todo el código de la aplicación, dentro de este código se
encuentran algunas configuraciones como por ejemplo la configuración del Timer,
configuración del MSComm y también se encuentra el código del algoritmo del control PI,
el código para ajustar el dato del sensor etc. A continuación se muestra todo el código de la
aplicación y después se irán explicando algunos segmentos del código:
Option Explicit
Dim value As Long
Dim bandera As Boolean
Dim cont1, x, y, z, i, p(2), d, Er, Ct As Integer 'Variables globales
Private Sub conectar_Click()
'comprueva que el puerto este cerrado para poder abrirlo
If MSComm1.PortOpen = False Then
'determina el puerto que hemos seleccionado.
If puerto.ListIndex = 0 Then
MSComm1.CommPort = 1
End If
If puerto.ListIndex = 1 Then
MSComm1.CommPort = 2
End If
If puerto.ListIndex = 2 Then
MSComm1.CommPort = 3
52
End If
If puerto.ListIndex = 3 Then
MSComm1.CommPort = 4
End If
If puerto.ListIndex = 4 Then
MSComm1.CommPort = 5
End If
If puerto.ListIndex = 5 Then
MSComm1.CommPort = 6
End If
If puerto.ListIndex = 6 Then
MSComm1.CommPort = 7
End If
If puerto.ListIndex = 7 Then
MSComm1.CommPort = 8
End If
If puerto.ListIndex = 8 Then
MSComm1.CommPort = 9
End If
If puerto.ListIndex = 9 Then
MSComm1.CommPort = 10
End If
If puerto.ListIndex = 10 Then
MSComm1.CommPort = 11
End If
End If
MSComm1.OutBufferSize = 4 'tamaño del dato a transmitir.
MSComm1.InBufferSize = 4
MSComm1.InputMode = comInputModeText
MSComm1.PortOpen = True
MSComm1.RThreshold = 4
End Sub
Private Sub Form_Load()
puerto.AddItem "COM1" ' Añadimos diferentes numeraciones para el puerto serie.
puerto.AddItem "COM2"
puerto.AddItem "COM3"
puerto.AddItem "COM4"
puerto.AddItem "COM5"
puerto.AddItem "COM6"
puerto.AddItem "COM7"
puerto.AddItem "COM8"
puerto.AddItem "COM9"
puerto.AddItem "COM10"
puerto.AddItem "COM11"
puerto.ListIndex = 0 ' Configuramos COM1, como predeterminado.
cont1 = 0
x = 0
y = 0
z = 0
p(0) = 0
p(1) = 0
p(2) = 0
i = 0
Er = 0
Ct = 0
Timer1.Interval = 50
53
Timer1.Enabled = True 'activamos el ciclo de escan.
End Sub
Private Sub MSComm1_OnComm()
Dim InBuff, v As String
Select Case MSComm1.CommEvent
Case comEvReceive
InBuff = MSComm1.Input
v = InBuff * 5 / 1023
d = -v ^ 5 * 11.3422 + v ^ 4 * 90.8138 - v ^ 3 * 289.5986 + v ^ 2 * 476.3524 - v * 440.6954 + 230.1869
If d <= 120 And d >= 20 Then
Debug.Print InBuff
txtValor.Text = ""
txtValor.Text = Left$(InBuff, 4) ' se recorta los caracteres basura
p(i) = d
d = (p(0) + p(1) + p(2)) / 3
txtAlt.Text = d
i = i + 1
If i = 3 Then
i = 0
End If
y = 4000 - 20 * txtRef.Text
z = 4000 - 20 * d
Graf.PSet (x, y), (&HFF0000)
Graf.PSet (x, z), (&HFF)
If x = 5000 Then
Graf.Cls
Graf.AutoRedraw = True
x = 0
End If
Er = Er + txtRef.Text - d
Ct = txtKp.Text * (txtRef.Text - d) + 0.0071987 * txtKi.Text * Er
txtp3.Text = Ct
If Ct > 255 Then
MSComm1.Output = Chr(255)
ElseIf Ct < 0 Then
MSComm1.Output = Chr(0)
Else
MSComm1.Output = Chr(Ct)
End If
End If
MSComm1.PortOpen = False 'cierra el puerto y vacia el buffer
End Select
End Sub
Private Sub Salir_Click()
Beep
End
End Sub
Private Sub Timer1_Timer()
Dim InBuff, v As String
On Error GoTo Tratamiento_errores
DoEvents
If MSComm1.PortOpen = True Then
DoEvents
estado.BackColor = &HFF00&
Debug.Print "Conectado"
cont1 = cont1 + 10
54
x = x + 1
Graf.PSet (x, y), (&HFF0000)
Graf.PSet (x, z), (&HFF)
If x = 5000 Then
Graf.Cls
Graf.AutoRedraw = True
x = 0
End If
If Ct > 255 Then
MSComm1.Output = Chr(255)
ElseIf Ct < 0 Then
MSComm1.Output = Chr(0)
Else
MSComm1.Output = Chr(Ct)
End If
'MSComm1.PortOpen = False
Exit Sub
Else
DoEvents
MSComm1.PortOpen = True
Exit Sub
End If
Tratamiento_errores: Debug.Print Err.Number & ": " & Err.Description
Select Case Err.Number
Case 8002 'Número de puerto no válido
DoEvents
estado.BackColor = &HFF&
Case 8005 'el puerto ya está abierto
DoEvents
estado.BackColor = &HFF0000
Case 8012 '8012 el dispositivo no está abierto
DoEvents
estado.BackColor = &HFF&
Case 8015
DoEvents ' para evitar retardos en bucles
estado.BackColor = &HFF&
End Select
End Sub
Private Sub Form_Unload(Cancel As Integer)
If MSComm1.PortOpen = True Then
MSComm1.PortOpen = False
End If
End Sub
Private Sub conectar_Click()
Cuando se genera un evento debido a oprimir el Comand Button para conectar con el
puerto el programa se va a este segmento de código, primero comprueba que el puerto este
cerrado después verifica el puerto que se ha seleccionado y se le asigna este puerto al
MSComm. Después de hacer eso se configuran los buffers de lectura y escritura del
MSComm y se abre el puerto para iniciar la comunicación con este puerto.
Private Sub Form_Load()
55
Cuando se inicia la aplicación este es el primer segmento de código al que accede el
programa. En este segmento se le asigna la lista de posibles puertos al combo box donde se
selecciona el asignado al sistema digital, también se inicializan las variables globales y el
Timer. El Timer se configura con un valor de 50 y se inicializa habilitándolo.
Private Sub MSComm1_OnComm()
Cuando se genera un evento por el MSComm el programa se dirige a esta parte del código.
En esta parte del código se verifica que tipo de evento fue el que se genero y si fue debido a
que el puerto recibió un nuevo dato este es procesado para obtener el valor de la altura en
cm, después este valor e procesa por el algoritmo de control PI y el resultado se manda al
buffer de escritura del MSComm y se cierra el puerto para vaciar el los buffer.
Private Sub Timer1_Timer()
Desde el momento en que activamos el Timer el programa se dirige a esta parte del código
y en esta parte se esta censando el estado del puerto, si han ocurrido eventos y se mando al
buffer de escritura el último valor generado por el algoritmo de control PI. Si se han
generado errores durante el tiempo de ejecución del programa se verifica que tipo de error
ocurrió y se cierra el programa.
4.3.2.1 Escalamiento del Dato del sensor.
Para poder obtener la distancia a la que se encuentra el helicóptero se utilizo un sensor
infrarrojo, debido a que fue la mejor opción, teniendo en cuenta varias posibles fuentes de
ruido, como la interferencia generada por las turbulencias de las hélices o la complejidad
del funcionamiento de distintos tipos de sensores así como la alimentación requerida por
estos.
Al caracterizar el sensor, haciendo varias mediciones a diferentes distancias se observo que
tiene un mejor funcionamiento en un intervalo de 20 a 120 cm de distancia, por lo que para
la poder obtener una mejor función que describiera el comportamiento del sensor solo se
tomaron en cuenta estas mediciones. Se realizaron 5 mediciones en intervalos de 5cm de
distancia y de estos datos se saco un promedio para cada una de las diferentes distancias.
En la Tabla 4.3 se puede observar los valores de las distancias y el voltaje promedio
generado por el sensor a estas distancias.
56
Distancia (cm) Voltaje (v) Distancia (cm) Voltaje (v)
20 2.55 75 0.7304
25 2.178 80 0.6772
30 1.86 85 0.6148
35 1.606 90 0.553
40 1.402 95 0.5078
45 1.236 100 0.4652
50 1.096 105 0.4262
55 1.0042 110 0.4142
60 0.9168 115 0.4036
65 0.8408 120 0.399
70 0.7752
Tabla 4.3 Datos para caracterización del sensor.
Para obtener una ecuación que describiera el funcionamiento del sensor se graficaron los
datos en MATLAB y se genero una ecuación realizando una interpolación con ayuda de
MATLAB y se encontró que la más aproximada a la grafica fue una de quinto orden. En la
Fig. 4.2 se puede observar la grafica de los datos y la grafica de la ecuación de quinto
orden.
57
Fig. 4.2 Grafica de la caracterización del sensor.
La ecuación obtenida en MATLAB es la siguiente:
𝑑 = −11.3422 ∙ 𝑣5 + 90.8138 ∙ 𝑣4 − 289.5986 ∙ 𝑣3 + 476.3524 ∙ 𝑣2 − 440.6954∙ 𝑣 + 230.1869
Como ya se ha mencionado el sensor genera un voltaje dependiendo de la distancia y este
valor de voltaje es digitalizado por un PIC, por lo que nuestra aplicación recibe el valor
digital del voltaje. Para poder obtener el valor de la distancia en cm primero se debe
convertir el valor digital del voltaje a analógico y después evaluar la ecuación de quinto
grado con este valor, cuando se tiene 0v su valor digital es 0 y cuando se tiene 5v su valor
digital es 1023, por lo que para poder convertir de nuevo a analógico solo se utiliza una
regla de tres dentro del programa.
Para no obtener muchas variaciones, y con esto menos fuentes de errores, en los valores de
distancia se utilizan promedios dinámicos, estos promedios se hacen con tres valores
distintos, además de que los valores del sensor se restringen a distancias entre 20cm y
120cm. Dentro del programa el código que se usa para obtener el valor de la distancia en
cm es el siguiente:
v = InBuff * 5 / 1023
58
d = -v ^ 5 * 11.3422 + v ^ 4 * 90.8138 - v ^ 3 * 289.5986 + v ^ 2 * 476.3524 - v * 440.6954 + 230.1869
If d <= 120 And d >= 20 Then
Debug.Print InBuff
txtValor.Text = ""
txtValor.Text = Left$(InBuff, 4) ' se recorta los caracteres basura
p(i) = d
d = (p(0) + p(1) + p(2)) / 3
txtAlt.Text = d
4.3.2.2 Algoritmo de control PI.
Después de obtener el valor de la distancia del sensor en cm, este valor es procesado por un
algoritmo de control. La función principal de un controlador es comparar el valor real del
parámetro a controlar (en este caso distancia) con el valor deseado y generar la señal de
control más adecuada para minimizar los errores y obtener una respuesta lo más rápida
posible.
Existen modelos básicos de comportamientos o también denominados acciones básicas de
control, en este caso se utiliza una acción Proporcional-Integral para poder obtener una
respuesta más rápida y estable del sistema.
Cuando se implementan algoritmos de control en sistemas digitales las señales se deben
muestrear a una frecuencia de dos a cuatro veces superior a la máxima frecuencia de
variación de las mismas, de lo contrario se puede perder información.
En un controlador tipo proporcional la salida o acción de control depende del error
generado al comparar el valor real y el valor deseado como se muestra en la siguiente
expresión:
𝐶𝑡 = 𝑘𝑝 ∙ 𝜀(𝑡)
Donde:
kp es una constante denominada constante proporcional
𝜀 𝑡 = 𝑑𝑖𝑠𝑡𝑎𝑛𝑐𝑖𝑎 𝑑𝑒𝑠𝑒𝑎𝑑𝑎 − 𝑑𝑖𝑠𝑡𝑎𝑛𝑐𝑖𝑎 𝑟𝑒𝑎𝑙
El principal inconveniente de un controlador que solo tiene acción proporcional es que
siempre deja un error por corregir debido a la constante proporcional. La acción integral
permite anular este error haciendo que la señal de control crezca proporcionalmente al
producto del error con el tiempo, se puede decir que la acción integral tiende a anular el
error promedio. La acción integral se muestra en la siguiente expresión:
𝐶𝑡 = 𝑘𝑖 𝜀 𝑡𝑖 ∙ (𝑡𝑖 − 𝑡𝑖−1)𝑖=𝑥
𝑖=0
Por lo que la expresión para la acción PI es la suma de las anteriores como se muestra en la
siguiente expresión:
59
𝐶𝑡 = 𝑘𝑝 ∙ 𝜀 𝑡 + 𝑘𝑖 𝜀 𝑡𝑖 ∙ (𝑡𝑖 − 𝑡𝑖−1)𝑖=𝑥
𝑖=0
Dentro del programa el código correspondiente al algoritmo de control es el siguiente:
Er = Er + txtRef.Text - d
Ct = txtKp.Text * (txtRef.Text - d) + 0.0071987 * txtKi.Text * Er
txtp3.Text = Ct
If Ct > 255 Then
MSComm1.Output = Chr(255)
ElseIf Ct < 0 Then
MSComm1.Output = Chr(0)
Else
MSComm1.Output = Chr(Ct)
End If
Para poder controlar los motores se usa PWM el cual se genera con un PIC, para determinar
el ciclo de trabajo del PWM se utilizan valores de 0 a 255 siendo 255 un ciclo de trabajo
del 100%, debido a esto cuando la señal de control del algoritmo PI es mayor a 255 se
envía 255 y cuando es menos a 0 se envía 0y cuando esta entre estos valores se envía tal
cual, entonces se podría decir que: 0 ≤ 𝐶𝑡 ≤ 255
60
CAPITULO 5 “MODULO RECEPTOR DE RF”
5.1 Introducción.
Como ya se ha mencionado en el helicóptero se encuentra un sensor infrarrojo y el valor de
voltaje generado por este sensor dependiendo la distancia a que se encuentra se digitaliza
con un PIC con modulo ADC y después de digitalizar este valor se envía por un modulo
transmisor de RF hasta un modulo receptor de RF y este va conectado a un PIC y después
de que el PIC recibió el dato lo manda por un puerto a nuestro sistema digital. En este
capitulo se explicara el funcionamiento de este modulo receptor de RF y la forma en que
recibe los datos.
5.2 Circuito del modulo receptor de RF.
En este circuito se utiliza el modulo RX334 y para la decodificación de los datos se utiliza
el PIC16F877A, después de que el modulo RX334 recibe la señal transmitida por el
RX334, el PIC recibe esta señal y la decodifica para obtener los datos del sensor y estos
datos después son desplegados por el puerto B y los pines C6 y C7 hacia el sistema digital
que hace la comunicación por USB con la PC. En la Fig. 5.1 se puede observar el circuito
de este modulo
61
Fig. 5.1 Circuito modulo receptor RF.
5.3 Programación del PIC.
Para una programación más sencilla se utilizo el compilador Mikrobasic debido a que tiene
instrucciones más sencillas y no se pierde mucho tiempo en la ejecución de las mismas, en
este caso es necesario no perder mucho tiempo para una mejor sincronización entre los
módulos receptor y transmisor de RF, el código es el siguiente:
program receptor
dim valor1 as byte
dim valor2 as byte
dim valor3 as byte
dim valor11 as byte
dim valor22 as byte
dim valor33 as byte
dim alto as byte
dim bajo as byte
SUB PROCEDURE lecturaclave
while TRUE
if PORTC.0 = 1 then
Delay_us(350)
break
end if
62
wend
while TRUE
if PORTC.0 = 1 then
Delay_us(350)
break
end if
wend
while TRUE
if PORTC.0 = 1 then
Delay_us(350)
break
end if
wend
while TRUE
if PORTC.0 = 1 then
Delay_us(350)
break
end if
wend
END SUB
SUB PROCEDURE lecturadatos1
if PORTC.0 = 1 then
SetBit(valor11, 1)
Delay_us(350)
else
Clearbit(valor11, 1)
Delay_us(350)
end if
if PORTC.0 = 1 then
SetBit(valor11, 0)
Delay_us(350)
else
Clearbit(valor11, 0)
Delay_us(350)
end if
if PORTC.0 = 1 then
SetBit(valor1, 7)
Delay_us(350)
else
Clearbit(valor1, 7)
Delay_us(350)
end if
if PORTC.0 = 1 then
SetBit(valor1, 6)
Delay_us(350)
else
Clearbit(valor1, 6)
Delay_us(350)
end if
if PORTC.0 = 1 then
SetBit(valor1, 5)
Delay_us(350)
else
Clearbit(valor1, 5)
Delay_us(350)
63
end if
if PORTC.0 = 1 then
SetBit(valor1, 4)
Delay_us(350)
else
Clearbit(valor1, 4)
Delay_us(350)
end if
if PORTC.0 = 1 then
SetBit(valor1, 3)
Delay_us(350)
else
Clearbit(valor1, 3)
Delay_us(350)
end if
if PORTC.0 = 1 then
SetBit(valor1, 2)
Delay_us(350)
else
Clearbit(valor1, 2)
Delay_us(350)
end if
if PORTC.0 = 1 then
SetBit(valor1, 1)
Delay_us(350)
else
Clearbit(valor1, 1)
Delay_us(350)
end if
if PORTC.0 = 1 then
SetBit(valor1, 0)
Delay_us(350)
else
Clearbit(valor1, 0)
Delay_us(350)
end if
END SUB
SUB PROCEDURE lecturadatos2
if PORTC.0 = 1 then
SetBit(valor22, 1)
Delay_us(350)
else
Clearbit(valor22, 1)
Delay_us(350)
end if
if PORTC.0 = 1 then
SetBit(valor22, 0)
Delay_us(350)
else
Clearbit(valor22, 0)
Delay_us(350)
end if
if PORTC.0 = 1 then
SetBit(valor2, 7)
Delay_us(350)
64
else
Clearbit(valor2,7)
Delay_us(350)
end if
if PORTC.0 = 1 then
SetBit(valor2, 6)
Delay_us(350)
else
Clearbit(valor2,6)
Delay_us(350)
end if
if PORTC.0 = 1 then
SetBit(valor2, 5)
Delay_us(350)
else
Clearbit(valor2,5)
Delay_us(350)
end if
if PORTC.0 = 1 then
SetBit(valor2, 4)
Delay_us(350)
else
Clearbit(valor2,4)
Delay_us(350)
end if
if PORTC.0 = 1 then
SetBit(valor2, 3)
Delay_us(350)
else
Clearbit(valor2,3)
Delay_us(350)
end if
if PORTC.0 = 1 then
SetBit(valor2, 2)
Delay_us(350)
else
Clearbit(valor2,2)
Delay_us(350)
end if
if PORTC.0 = 1 then
SetBit(valor2, 1)
Delay_us(350)
else
Clearbit(valor2,1)
Delay_us(350)
end if
if PORTC.0 = 1 then
SetBit(valor2, 0)
Delay_us(350)
else
Clearbit(valor2,0)
Delay_us(350)
end if
END SUB
SUB PROCEDURE lecturadatos3
65
if PORTC.0 = 1 then
SetBit(valor33, 1)
Delay_us(350)
else
Clearbit(valor33, 1)
Delay_us(350)
end if
if PORTC.0 = 1 then
SetBit(valor33, 0)
Delay_us(350)
else
Clearbit(valor33, 0)
Delay_us(350)
end if
if PORTC.0 = 1 then
SetBit(valor3, 7)
Delay_us(350)
else
Clearbit(valor3,7)
Delay_us(350)
end if
if PORTC.0 = 1 then
SetBit(valor3, 6)
Delay_us(350)
else
Clearbit(valor3,6)
Delay_us(350)
end if
if PORTC.0 = 1 then
SetBit(valor3, 5)
Delay_us(350)
else
Clearbit(valor3,5)
Delay_us(350)
end if
if PORTC.0 = 1 then
SetBit(valor3, 4)
Delay_us(350)
else
Clearbit(valor3,4)
Delay_us(350)
end if
if PORTC.0 = 1 then
SetBit(valor3, 3)
Delay_us(350)
else
Clearbit(valor3,3)
Delay_us(350)
end if
if PORTC.0 = 1 then
SetBit(valor3, 2)
Delay_us(350)
else
Clearbit(valor3,2)
Delay_us(350)
end if
66
if PORTC.0 = 1 then
SetBit(valor3, 1)
Delay_us(350)
else
Clearbit(valor3,1)
Delay_us(350)
end if
if PORTC.0 = 1 then
SetBit(valor3, 0)
Delay_us(350)
else
Clearbit(valor3,0)
Delay_us(350)
end if
END SUB
main:
TRISB = 0x00
TRISC = 0x0F
valor1 = 0
valor2 = 0
valor3 = 0
while TRUE
' primer lectura
lecturaclave
lecturadatos1
' segunda lectura
lecturaclave
lecturadatos2
' tercera lectura
lecturaclave
lecturadatos3
' valida datos menos significativos
if valor1 = valor2 then
bajo = valor1
else
if valor1 = valor3 then
bajo = valor1
else
if valor2 = valor3 then
bajo = valor2
else
PORTB = 0
ClearBit(PORTC, 1)
ClearBit(PORTC, 0)
end if
end if
end if
' valida datos mas significativos
if valor11 = valor22 then
alto = valor11
PORTB = bajo
PORTC.7 = alto.1
PORTC.6 = alto.0
SetBit(PORTC, 5)
Delay_us(50)
67
else
if valor11 = valor33 then
alto = valor11
PORTB = bajo
PORTC.7 = alto.1
PORTC.6 = alto.0
SetBit(PORTC, 5)
Delay_us(50)
else
if valor22 = valor33 then
alto = valor22
PORTB = bajo
PORTC.7 = alto.1
PORTC.6 = alto.0
SetBit(PORTC, 5)
Delay_us(50)
else
PORTB = 0
ClearBit(PORTC, 7)
ClearBit(PORTC, 6)
ClearBit(PORTC, 5)
end if
end if
end if
wend
end.
SUB PROCEDURE lecturaclave: En esta subrutina del programa se verifica la clave de
transmisión con la que se enviaron los datos para sincronizar y comunicar el receptor con el
transmisor.
SUB PROCEDURE lecturadatos: En esta subrutina del programa el PIC recibe el dato
bit a bit y los va acomodando en un registro de 10 bits.
main: Esta es la parte principal del programa primero se inicializan variables, después se
mandan llamar las subrutinas de lectura de clave y lectura de datos. Después de que se
recibieron los datos el programa verifica que se haya recibido el mismo dato tres veces,
para evitar errores de transmisión de datos, si el dato se recibió tres veces entonces lo
manda desplegar al puerto B y a los pines 6 y 7 del puerto C, estos pines del puerto C y el
puerto B están conectados al sistema digital que se comunica con la PC por USB.
68
CAPITULO 6 “CONCLUSIONES Y EXPECTATIVAS”
Como se ha podido observar se han logrado los objetivos planteados para la realización de
este proyecto. Se logro establecer comunicación entre un sistema digital basado en el
PIC18F2550 y la PC a través del USB, utilizando una aplicación realizada en Visual Basic
6.0, para lograr esta comunicación se emulo el puerto USB como si fuera un puerto COM
RS-232, esto genera una comunicación entre la PC y el PIC más veloz que si fuera un
puerto COM y aunque se trabaja como un puerto COM no importan sus propiedades como
el baud rate, bit de paridad y mucho menos el tamaño del buffer. Esto es una ventaja ya que
si nosotros contamos con aplicaciones en la PC que se comunican con dispositivos externos
a través del COM RS-232 se pueden utilizar para comunicar con dispositivos externos a
través del puerto USB y también se podría mejorar la eficiencia de estas aplicaciones
debido a que se pueden tener velocidades de transmisión de datos de hasta 1.5Mbps.
Nuestro sistema se puede considerar un sistema de tiempo real debido a las altas
velocidades de transmisión que se lograron, tanto con la comunicación USB como con la
transmisión por RF, además de que no se mostraron perdidas de datos, cosa que puede
pasar cuando se utiliza un puerto COM RS-232.
Al tener la opción de poder modificar los valores de las constantes del control PI, se pueden
obtener diferentes tipos de respuestas del sistema, desde respuestas muy lentas hasta
respuestas muy rápidas, lo cual puede tomarse como un mayor numero de velocidades del
helicóptero, esto es bueno en sistemas en donde el usuario esta interactuando
constantemente, pero en sistemas que deben ser más automáticos no es muy recomendable
ya que se puede tener inestabilidad del sistema.
En general se ha realizado un sistema muy rápido y de gran alcance, ya que los módulos de
radiofrecuencia pueden llegar a tener un alcance de hasta 100m, dependiendo de la antena y
la fuente de alimentación de los módulos.
Al realizar la comunicación del sistema digital con la PC por el USB se puede observar que
la comunicación se puede mejorar, en cuanto a velocidad, programando el dispositivo como
HID debido a que hay mayor velocidad de transmisión de datos y se necesitan menos
configuraciones para poder realizar comunicación entre el sistema digital y el Host.
69
También se puede utilizar compiladores con un lenguaje de programación menos estricto y
más dinámico para la programación del PIC como por ejemplo lenguaje Basic, ya que
tienen instrucciones más simples y un mayor número de librerías especificas para PICs.
También se puede mejorar la velocidad de transmisión y recepción de datos de los módulos
de RF, utilizando módulos más veloces y otras técnicas de codificación de datos para la
transmisión y recepción como por ejemplo código Manchester entre otras, ya que al
sincronizar y comunicar los módulos mediante claves se pierde tiempo.
El realizar la comunicación de la PC con el sistema digital también seria más sencillo si se
utiliza el dispositivo USB como HID, ya que no se tendrían que hacer configuraciones de
baud rate el cual limita la velocidad de transmisión de datos entre la PC y el sistema digital
y nuestra aplicación en Visual Basic necesitaría menos configuraciones, se podrían evitar
configuraciones del MSComm y la configuración del puerto con el cual se realiza la
conexión debido a que un dispositivo HID se conecta automáticamente sin la necesidad de
elegir el puerto al que se conecto este dispositivo.
En cuanto al algoritmo de control PI, se podría mejorar la respuesta del sistema si se
realizara un análisis de todo el sistema para poder obtener las constantes de control
adecuadas para una respuesta más rápida y estable, ya que en este trabajo las constantes
podían ser cambiadas y esto complica la obtención de una mejor respuesta de todo el
sistema.
Otra cosa que se podría mejorar es el encontrar un sensor que tenga una mejor respuesta, la
respuesta del sensor utilizado no es muy estable además de que solo tendría un buen
funcionamiento en superficies totalmente planas debido a que una pequeña variación en el
ángulo del sensor puede llegar a significar una gran variación de distancia y esto puede
afectar de manera muy considerable a la respuesta de todo el sistema. Además de conseguir
un sensor con una mejor respuesta también se podría conseguir un sensor con un intervalo
de distancias de operación mucho más grandes, debido a que con el sensor utilizado no se
puede controlar el helicóptero a distancias pequeñas y esto genera problemas para iniciar el
vuelo.
70
APENDICE A “HOJAS DE DATOS TECNICOS DE LOS DISPOSITIVOS”
71
72
73
74
75
76