Está en la página 1de 64

Control de carrera para competicin de robots mviles

TITULACION: Ingeniera Tcnica Industrial en Electrnica Industrial

AUTORS: Eduard Cavall Albert


DIRECTORS: Jos Luis Ramrez Falo
FECHA: Junio /2010.

1 MEMORIA DESCRIPTIVA............................................................ 4
1.1

Objetivo ............................................................................................................ 5

1.2

Esquema del proyecto ..................................................................................... 5

1.3

Especificaciones previas .................................................................................. 5

1.4

Antecedentes .................................................................................................... 6

1.5 Diseo del Hardware ....................................................................................... 6


1.5.1 Seleccin del sensor ...................................................................................... 6
1.5.2 Funcionamiento del sensor ............................................................................ 7
1.5.3 Seleccin del microcontrolador ................................................................... 10
1.5.4 Funcionamiento del micro controlador ....................................................... 10
1.5.4.1 Componentes para la comunicacin...................................................... 10
1.5.4.2 Componentes para el clculo de tiempos .............................................. 11
1.5.5 Desarrollo de la placa PCB.......................................................................... 12
1.6 Diseo del Firmware ..................................................................................... 12
1.6.1 Lenguaje de programacin .......................................................................... 12
1.6.2 Herramientas para el diseo ........................................................................ 13
1.6.3 Programacin............................................................................................... 16
1.6.3.1 Timer ..................................................................................................... 16
1.6.3.2 Pines de entrada..................................................................................... 17
1.6.3.3 Comunicacin USB............................................................................... 18
1.7 Diseo del software de control...................................................................... 19
1.7.1 Lenguaje de programacin .......................................................................... 19
1.7.2 Herramientas para el desarrollo................................................................... 20
1.7.3 Drivers ......................................................................................................... 22
1.7.4 Manual de Funcionamiento ......................................................................... 23

2 MEMORIA DE CLCULO........................................................... 25
2.1 Clculos software........................................................................................... 26
2.1.1 Timer 0 ........................................................................................................ 26
2.2 Clculos Hardware ........................................................................................ 26
2.2.1 Comprobar la salida de los sensores............................................................ 26

3 PLANOS ........................................................................................... 28
3.1

Esquema de la placa PCB ............................................................................. 29

3.2

Diagrama de conexiones................................................................................ 30

3.3

Diagrama de conexiones IS471F .................................................................. 31

4 PRESUPUESTO .............................................................................. 32
2

4.1

Introduccin ................................................................................................... 33

4.2 Precios unitarios ............................................................................................ 33


4.2.1 Componentes ............................................................................................... 33
4.2.2 Mano de obra ............................................................................................... 34
4.3 Precios descompuestos .................................................................................. 34
4.3.1 Componentes ............................................................................................... 34
4.3.2 Mano de obra ............................................................................................... 35
4.4

Resumen del presupuesto.............................................................................. 35

5 BIBLIOGRAFA Y REFERENCIAS ........................................... 36


5.1

Bibliografa..................................................................................................... 37

5.2

Referencias ..................................................................................................... 37

6 ANEXOS........................................................................................... 39
6.1

Cdigo fuente firmware ................................................................................ 40

6.2 Cdigo fuente del software de control ......................................................... 51


6.2.1 Form1.cs ...................................................................................................... 51
6.2.2 PICUSBAPI.CS........................................................................................... 60

Memoria descriptiva

1.1

Objetivo

El objetivo del proyecto es disear y montar un sistema automatizado para


cronometrar el tiempo que tarda un robot sigue-lneas en recorrer un circuito dado,
mostrando tanto el tiempo de vuelta como tiempos parciales.

1.2

Esquema del proyecto

Figura 1. Esquema del proyecto

1.3

Especificaciones previas

Para la realizacin de este proyecto se deben tener en cuenta las siguientes


especificaciones:
-La comunicacin entre el microcontrolador y el PC deber ser mediante USB.
-La interfaz de usuario deber ser amigable y de fcil manejo.

-El sistema deber ser capaz de calcular el tiempo con una resolucin y precisin de
dcimas de segundo.

1.4

Antecedentes

Actualmente podemos encontrar este tipo de sistemas en muchos sitos diferentes,


aunque su uso est muy extendido sobretodo en el mundo de los deportes.
Un ejemplo parecido a este proyecto es el sistema que usan en las carreras de Frmula 1 o
Moto GP ya que disponen de unos sensores y contadores con los cuales pueden calcular el
tiempo parcial y total de la vuelta. Aunque las condiciones y los sensores usados en este
proyecto son muy diferentes, adems la resolucin que vamos a dar es un orden de
magnitud inferior.

1.5

Diseo del Hardware

Se diferencian dos partes principales en lo que al hardware se refiere. Por un lado se


dispone de sensores, los cuales enviarn una seal al microcontrolador cuando detecten la
presencia del robot. Por el otro lado est el microcontrolador, que se encarga de calcular
los tiempos segn le van llegando las seales de los sensores, y a la vez enva estos
tiempos calculados al PC mediante USB.

1.5.1 Seleccin del sensor


Los tipos ms comunes de sensores para detectar el paso del robot son:
Inductivos: Este tipo de sensores se basan en el cambio de inductancia que provoca un
objeto metlico en un campo magntico. Los sensores de este tipo constan bsicamente de
una bobina y de un imn. Cuando un objeto ferro magntico penetra o abandona el campo
del imn el cambio que se produce en dicho campo induce una corriente en la bobina.
Efecto Hall: Relaciona la tensin entre dos puntos de un material conductor o
semiconductor con un campo magntico atreves del material. Este tipo de sensores suelen
constar de ese elemento conductor o semiconductor y de un imn. Cuando un objeto ferro
magntico se aproxima al sensor, el campo provocado por el imn en el elemento se
debilita. As se puede determinar la proximidad de un objeto.
Sensores Capacitivos: Como su nombre indica, estn basados en la deteccin de un
cambio en la capacidad del sensor provocado por una superficie prxima a ste. Constan
de dos elementos principales; por un lado est el elemento cuya capacidad se altera (que
suele ser un condensador formado por electrodos) y por otra parte el dispositivo que
detecta el cambio de capacidad (un circuito electrnico conectado al condensador). Este
tipo de sensores tienen la ventaja de que detectan la proximidad de objetos de cualquier
naturaleza; sin embargo, hay que destacar que la sensibilidad disminuye bastante cuando la
6

distancia es superior a algunos milmetros. Adems, es muy dependiente del tipo de


material.
Sensores Ultrasnicos: Su elemento principal es un transductor electroacstico. Este
elemento, en primer lugar, emite unas ondas ultrasnicas; a continuacin pasa a modo de
recepcin, en el que, durante un cierto tiempo, espera la vuelta de las ondas reflejadas en
algn objeto. Si las ondas llegan, quiere decir que hay algn objeto en las proximidades.
Sensores pticos: Este tipo de sensores son muy parecidos a los anteriores. En
estos, las seales que se transmiten y detectan son luminosas. En los sensores pticos el
emisor y el receptor suelen ser elementos separados. El primero suele ser un diodo emisor
de luz (LED) y el receptor un fotodiodo.

De los sensores expuestos arriba, se eligieron los pticos, por ser ms econmicos
que el resto, ya que requieren de menos componentes y ms baratos, y porque son ms
fciles usar.
El dispositivo IS471F ofrece las caractersticas que se buscan, es un sensor ptico de
uso fcil y de bajo coste.

1.5.2 Funcionamiento del sensor


Este dispositivo est diseado para trabajar en ambientes con luz solar, hasta 7500 lx.
Incorpora un modulador/demodulador integrado en su carcasa y a travs de su patilla 4
controla un diodo LED de infrarrojos externo, modulando la seal que este emitir, para
ser captada por el IS471F que contiene el receptor. Cuando un objeto se sita entre el
conjunto emisor/receptor la luz emitida no es captada y la salida en la patilla 2 pasar a
nivel alto. [1]

Figura 2. IS471F

Consta de 4 pines:
Pin1: Vcc, aqu es donde conectaremos la alimentacin a 5 V.
Pin2: Vo es la salida, si el receptor de luz que se encuentra en el dispositivo la recibe,
este pin pasar automticamente a 5 V. Por el contrario si no la recibe, estar a 0 V. Este
ser el pin que se conectar a una de las entradas del microcontrolador.
Pin3: GND, se conecta este pin a tierra.
Pin4: Glout, este pin es donde se debe conectar el LED IR, para que la luz que
produzca est modulada y el receptor la reciba correctamente.
Un diagrama aproximado de los componentes que forman el sensor y las distancias
entre ellos:

Figura 3. Representacin circuito de carreras


Esta imagen representa una parte del circuito de carreras. Se puede observar que a un
lado de la lnea, est el emisor (LED IR) y en el otro est el receptor (IS471F), de tal
manera que cuando el robot pase entre ambos, la luz emitida no ser recibida y la salida del
dispositivo cambiar.
El reglamento de la competicin especifica que la planta del robot no puede superar
un crculo de 20cm de dimetro. Con el fin de permitir a los robots un margen de error al
seguir la lnea, la distancia entre cada componente y la lnea del circuito es de de 20 cm.
El tiempo que tarda el dispositivo en hacer el cambio de nivel bajo a alto en la pata
de salida cuando el robot es detectado no puede ser muy grande debido a las restricciones
de resolucin de tiempo.[1]

Figura 4. Caractersticas IS471F


Como podemos ver en la imagen anterior, el tiempo mximo para pasar de estado
bajo a alto es de 670 us, en este proyecto se considera un tiempo despreciable ya que el
proceso no requiere de tanta resolucin.

1.5.3 Seleccin del microcontrolador


Uno de los requisitos del proyecto es la capacidad del sistema para comunicarse con
el PC mediante USB. Por lo tanto el abanico de posibilidades a la hora de elegir el
microcontrolador se reduce drsticamente. Debido a que la universidad dispone del equipo
necesario para programar microcontroladores de la marca Microchip o lo que es lo
mismo la familia PIC, se decidi por este en concreto. Dentro de esta marca, se
diferencian dos modelos principales:
PIC 18f2550
PIC 18f4550
Su principal diferencia reside en el nmero de pines, que posteriormente se
configuraran como I/O, convertidores analgicos digitales, etc. El PIC 18F2550, dispone
de 28 pines con 3 puertos mientras que el PIC 18F4550 dispone de 40 pines con 5 puertos.
Para realizar este proyecto, se ha previsto que 3 puertos son suficientes. Por lo tanto, por
ser la opcin ptima, se ha escogido el PIC 18F2550.[2]

1.5.4 Funcionamiento del micro controlador


Este dispositivo tiene 2 funciones principales, una de ellas es la comunicacin con el
PC, y la otra es el clculo de los tiempos. Para establecer la comunicacin se necesita de
ms componentes aparte del PIC, estos son:

1.5.4.1 Componentes para la comunicacin


Oscilador de cristal
Condensadores de mica
Condensadores electrolticos
Conector USB
Oscilador de cristal
La comunicacin mediante USB requiere una frecuencia de trabajo de 4 MHz. Para
poder hacerlo, se necesita un oscilador de cristal. Entre los osciladores ms comunes est el
de 20 MHz, as que sabiendo que posteriormente se puede rebajar la oscilacin a 4 MHz
por software, se decidi comprarlo.
Condensadores de mica
El oscilador de cristal necesita de dos condensadores unipolares para funcionar
adecuadamente, los valores recomendados por el fabricante son de 15 pF. Se eligieron los
condensadores de mica por ser los ms econmicos.
10

Condensadores electrolticos
Se deben colocar dos:
-Un condensador de 47 uf, en el pin VUSB, este valor est recomendado por el
fabricante.
-Un condensador de 100uf, entre alimentacin y massa para prevenir caidas de
tensin por parte de la alimentacin.

Conector y cable USB


Este componente junto a su cable ser el que unir el microcontrolador con el PC
para su comunicacin. En su interior se puede observar que hay 4 cables de diferente color.

Figura 5. Cable USB


Como se puede ver, el rojo y el negro son alimentacin y masa respectivamente, los
podemos conectar directamente al microcontrolador, de tal forma que no necesitaremos
alimentacin externa para su funcionamiento. Mientras que el blanco y el verde son para la
transmisin de datos, y tambin se conectan directamente al microcontrolador.
1.5.4.2 Componentes para el clculo de tiempos
Para el clculo de tiempos se necesita que las salidas de los sensores estn
conectadas a las entradas del microcontrolador, para que puedan ser testeadas.
Internamente el PIC est configurado para calcular los tiempos segn el estado de estas
entradas.
11

1.5.5 Desarrollo de la placa PCB


Para llevar a cabo el diseo de la placa PCB, se ha usado el programa Orcad v10.5.
Con l se cre el diagrama de conexiones y posteriormente se diseo la placa PCB.

1.6

Diseo del Firmware

Se conoce como firmware al conjunto de instrucciones de programa que se


encuentra grabado en una memoria no voltil de un microcontrolador. Estas instrucciones
establecen la lgica de bajo nivel que controla los circuitos electrnicos de algn tipo de
dispositivo.
El firmware, cuyo nombre hace referencia a la programacin en firme, forma parte
del hardware ya que se encuentra integrado a la electrnica, pero tambin est
considerado como parte del software al estar desarrollado en algn lenguaje de
programacin. Podra decirse que el firmware acta como intermediario entre las rdenes
externas que recibe el dispositivo y sus componentes electrnicos.

1.6.1 Lenguaje de programacin


Una de las partes ms importantes al programar el micro controlador es el lenguaje
de programacin a utilizar. Se barajaban dos opciones, programar usando CSS o
ensamblador, a continuacin se muestran las caractersticas de cada uno:
Ensamblador

El cdigo escrito en lenguaje ensamblador posee una cierta dificultad de ser


entendido directamente por un ser humano ya que su estructura se acerca ms bien al
lenguaje mquina, es decir, lenguaje de bajo nivel.

El lenguaje ensamblador es no portable. Es decir, un cdigo escrito para un


microprocesador necesita ser modificado, muchas veces en su totalidad, para poder ser
usado en otra mquina distinta.

Los programas hechos en lenguaje ensamblador son generalmente ms rpidos y


consumen menos recursos del sistema (memoria RAM y FLASH). Al programar
cuidadosamente en lenguaje ensamblador se pueden crear programas que se ejecutan ms
rpidamente y ocupan menos espacio que con lenguajes de alto nivel.

Con el lenguaje ensamblador se tiene un control muy preciso de las tareas


realizadas por un microprocesador por lo que se pueden crear segmentos de cdigo
difciles de programar en un lenguaje de alto nivel.

Tambin se puede controlar el tiempo en que tarda una rutina en ejecutarse.

12

CCS

El cdigo que generamos en lenguaje CSS es fcilmente entendible, ya que es de


alto nivel y las instrucciones se parecen ms al lenguaje humano.

Es fcilmente portable a otros microcontroladores.

La velocidad de ejecucin es uno de sus puntos flacos, si necesitamos que esta sea
muy alta y precisa difcilmente lo conseguiremos.

Otro punto en contra, es el espacio de memoria que necesitan en comparacin con


el que necesita un programa hecho en ensamblador.

Una vez vistos los pros y los contras de usar un lenguaje de programacin u otro, se
eligi usar CSS. Los tiempos de ejecucin no son cruciales en este proyecto ya que la
potencia de clculo elevada del microcontrolador elegido, frente la resolucin que se
demanda, es ms que suficiente. Adems, ste dispone de suficiente memoria para
almacenar todo el cdigo.

1.6.2 Herramientas para el diseo


MPLab V8.4:
Es una herramienta para escribir cdigo en diferentes lenguajes para los
microcontroladores PIC y posteriormente comunicarse con el programador para grabar el
microcontrolador.
MPLab incorpora todas las herramientas necesarias para la realizacin de cualquier
proyecto, ya que adems de un editor de textos cuenta con un simulador en el que se puede
ejecutar el cdigo paso a paso para ver as su evolucin y el estado en el que se encuentran
sus registros en cada momento.
Aunque de las funciones disponibles, dichas anteriormente, solo se usar esta
herramienta para grabar el PIC, ya que MPLab no dispone de compilador CCS con lo cual
no podr compilar el cdigo.
Hace falta destacar que se trata de un software gratuito, que se encuentra disponible
en la pgina de Microchip. La versin actual es la 8.4 y ser la utilizada para realizar las
acciones respectivas en este proyecto.[3]

13

Figura 6. Entorno de trabajo MPlab


ICD2
In-Circuit Debugger 2 permite la depuracin y la programacin de los
microcontroladores flash PIC y dsPIC usando la interfaz grfica de usuario MPLAB
Entorno de Desarrollo Integrado (IDE). El ICD 2 se conecta al PC via USB o RS-232 y al
programador mediante un cable telefnico. [4]

Figura 7. ICD2

14

PIC C Compiler
Es el compilador que se usa en este proyecto, convierte las lneas de cdigo escritas
en lenguaje CCS, en un archivo con extensin .hex, el cual ser grabado al PIC.

Figura 8. Entorno de trabajo de PIC C Compiler


Se puede obtener una demo del programa con todas sus opciones habilitadas,
pudindolo utilizar durante 30 das. [5]

Proteus 7 Professional
Es un simulador de circuitos, PICs incluidos, muy potente, donde se depura y
comprueba el buen funcionamiento de todo el sistema. El programa se us durante el
diseo del firmware para depurar todo lo relacionado con la comunicacin entre PIC y PC.

15

Figura 9. Entorno de trabajo Proteus


Existe una versin de prueba disponible del programa. [6]

1.6.3 Programacin
Internamente el PIC deber hacer 3 funciones esenciales:
-Comprobar el estado de los sensores
-Calcular el tiempo que tarda el robot en realizar el recorrido
-Enviar y recibir datos del PC mediante el bus USB

Para ello se necesita:

1.6.3.1 Timer
Es un temporizador que provoca una interrupcin cada cierto tiempo. Este tiempo no
es aleatorio, sino que depende de los valores de unos parmetros asignados en el cdigo del
firmware.
Se programa el Timer 0 para provocar una interrupcin cada 50 milisegundos. La
atencin a esta interrupcin incrementar en una unidad la variable tics y volver a cargar

16

el Timer 0. De esta manera para saber el valor del tiempo transcurrido se multiplicar el
valor de la variable tics por 50 y se obtendr como resultado el tiempo en milisegundos.
Este proceso no se pone en marcha hasta que no se habilita el Timer 0. En el caso de
este proyecto, se debe habilitar cuando el microcontrolador recibe la seal de deteccin del
primer sensor del circuito, el cual se encuentra al inicio.
Las instrucciones para habilitar el Timer0 son las siguientes:
Setup_timer_0(RTCC_INTERAL|RTCC_DIV_8)

Aqu especificamos que se va a usar el Timer 0, con el oscilador interno y que se va a


usar un preescaler 8.
Enable_interrupts(INT_TIMER0);

Se habilita la interrupcin para Timer 0.


Enable_interrupts(global);

Esta instruccin funciona como un interruptor general, en este caso se abre paso a las
interrupciones habilitadas.

1.6.3.2 Pines de entrada

Con el objetivo de comprobar el estado de las salidas de los sensores, estas estn
conectadas a cinco pines diferentes del puerto B. De manera que se podr analizar la salida
de cada sensor por separado.
Para ello se deben programar estos cinco pines como entradas. Para hacerlo, se debe
modificar el registro TRISB, ya que los pines forman parte del PUERTOB. Como se ve a
continuacin, este registro se encuentra en la posicin de memoria 0x93.

17

Figura 10. Tabla de registros especiales PIC18F2550


Este registro se compone de 8 bits, cada uno de ellos configura como entrada o salida
un pin del PUERTOB. El bit 0 de TRISB configura el pin 0 del PUERTOB, este valdr 1 si
se quiere como configurar como entrada, o 0 como salida, y as respectivamente con los 7
bits restantes.
Sabiendo que en este proyecto se usan los pines RB3-RB7 como entradas, se deben
forzar unos en los bits 3-7 del registro TRISB. Se hace con las siguiente instruccin:
TRISB=0b11111111;
1.6.3.3 Comunicacin USB
Para llevar a cabo este tipo de comunicacin se debe tener en cuenta el protocolo
USB. El compilador CCS contiene libreras para facilitar esta tarea. Se usarn las libreras:
-pic18_usb.h
-usb.h
-usb_desc_scope.h
-usb.c
De estas libreras se utilizarn las funciones siguientes:
usb_init()
Inicializa la pila USB, los perifricos USB y permite interrupciones.
usb_wait_for_enumeration(void)
18

Esperamos hasta que el PicUSB sea configurado por el host


usb_enumerated(void)
Esta funcin retorna true si el PIC ya est configurado y false si no lo est.
usb_kbhit(1)
Si el PIC ha recibido datos del PC esta funcin retorna true, si no false.
usb_put_packet(int endpoint, int * ptr, int16 len, USB_DTS_BIT tgl)
Esta es la funcin que se usa para enviar datos del PIC al PC, como parmetros se
deben pasar, el end point por donde se quieren enviar los datos, el dato a enviar, el tamao
del dato y por ltimo por cul de los canales data se debe enviar DATA0, DATA1 o
cambiar de DATA a cada envo USB_DTS_TOGGLE.
usb_get_packet(int8 endpoint, int8 * ptr, int16 max)
Esta es la funcin que se usa para recibir datos que el PC enva al PIC, como
parmetros se deben pasar, el end point por donde se quieren enviar los datos, el puntero
donde se guardar el dato y el tamao del dato.
Las libreras anteriormente sealadas, disponen de muchas ms funciones que las que
acabamos de citar, pero para este proyecto solo son necesarias estas cinco.

1.7

Diseo del software de control

Para poder establecer la comunicacin PC PIC es necesario que el


microcontrolador est programado para ello, pero tambin se necesita un software de
control para el PC. Este software ser necesario para poder interpretar los datos que enva
el PIC a travs del puerto USB, y para poder enviar datos del PC al PIC por el mismo
puerto.

1.7.1 Lenguaje de programacin


Existen muchos lenguajes de programacin en el mercado. Para elegir uno en
concreto se deben tener en cuenta las restricciones del proyecto, ya que se requiere que este
software sea de fcil manejo y con una interfaz grfica amigable, as que las posibilidades
se reducen.

19

A continuacin se muestran los lenguajes ms populares que cumplen los requisitos


sobre las restricciones de software:
-Visual Basic
-Visual C ++
-Visual C#

Todos ellos cuentan con un compilador con versin gratuita descargable desde
internet, aunque tienen algunas restricciones, cualquiera de ellos es vlido para realizar las
funciones necesarias.
El lenguaje utilizado finalmente fue Visual C#.
El factor clave, que decidi cul de ellos usar, fue el conocimiento adquirido en la
universidad de este lenguaje. C# se ensea en diferentes asignaturas a lo largo de la carrera
y ste no difiere mucho de Visual C#.

1.7.2 Herramientas para el desarrollo


Microsoft Visual C#
Es una aplicacin que permite crear interfaces grficas amigables y fciles de
entender, como la mayora de aplicaciones de Windows.

Figura 11. Entorno de trabajo de Microsoft Visual C#

20

Se puede descargar una versin de prueba desde internet. [7]

Para comunicarse con el microcontrolador Microchip facilita una librera con las
funciones ms importantes. MPUSBAPI.DLL [8]
Esta dll debe adjuntarse al proyecto creado en Visual C# para poder usar estas
funciones:
MPUSBGETDEVICECOUNT(PVID_PID) Devuelve el nmero de dispositivo
con VID_PID asignado.
pVID_PID: Input: cadena de caracteres del nmero de identificacin asignado.
MPUSBGETDLLVERSION(VOID) Lee el nivel de revisin del MPUSAPI.dll. Es
un nivel de revisin de 32bits.
Esta funcin no devuelve la versin del cdigo, no realiza nada con el USB.
Devuelve la versin de la dll en formato hexadecimal de 32bits.
MPUSBOPEN(INSTANCE, PVID_PID, PEP, DWDIR, DWRESERVED)
Devuelve el acceso al pipe del Endpoint con el VID_PID asignado.
instance: Input: Un nmero de dispositivo para abrir. Normalmente, se utiliza
primero la llamada de MPUSBGetDeviceCount para saber cuantos dispositivos hay.
Es importante entender que el driver lo comparten distintos dispositivos. El nmero
devuelto por el MPUSBGetDeviceCount tiene que ser igual o menor que el nmero de
todos los dispositivos actualmente conectados y usando el driver genrico.
pVID_PID: Input: String que contiene el PID&VID del dispositivo objetivo.
El PID y VID son las siglas en ingls de Product IDentifier y Vendor Product
IDentifier respectivamente.
El formato es vid_xxxx&pid_yyyy. Donde xxxx es el valor del VID y el yyyy el
del PID, los dos en hexadecimal.
Ejemplo:
Si un dispositivo tiene un VID=0x04d8 y un PID=0x000b, el string de entrada es:
vid_0x04d8&pid_0x000b.
pEP: Input: String con el nmero del Endpoint que se va a abrir. El formato es
\\MCHP_EPz o \MCHP_EPz dependiendo del lenguaje de programacin. Donde z es
el nmero del Endpoint en decimal.
Ejemplo:
\\MCHP_EP1 o \MCHP_EP1
21

Este argumento puede ser NULL (nulo) para crear lazos con Endpoints de funciones
no especficas.
dwDir: Especifica la direccin del Endpoint:
dwReserved: por ahora nada.
MPUSBREAD(HANDLE,
DWMILLISECONDS)

PDATA,

DWLEN,

PLENGTH,

handle: Input: Identifica la pipe del Endpoint que se va a leer.


pData: Output: Puntero al buffer que recibe el dato ledo de la pipe.
dwLen: Input: Especifica el nmero de bytes que hay que leer de la pipe.
pLenght: Output: Puntero al nmero de bytes ledos. MPUSBRead pone este valor a
cero antes de cualquier lectura o de analizar un error.
dwMilliseconds: Input: Especifica el intervalo de time-out en milisegundos. La
funcin vuelve si transcurre el intervalo aunque no se complete la operacin. Si
dwMilliseconds=0, la funcin comprueba los datos de la pipe y vuelve inmediatamente.
MPUSBCLOSE(HANDLE) Cierra una determinada unin.
handle: Input: Identifica la pipe del Endpoint que se va a cerrar.
MPUSBWRITE(HANDLE,
DWMILLISECONDS)

PDATA,

DWLEN,

PLENGTH,

handle: Input: Identifica la pipe del Endpoint que se va a escribir. La pipe unida
tiene que crearse con el atributo de acceso MP_WRITE.
pData: Output: Puntero al buffer que contiene los datos que se van a escribir en la
pipe.
dwLen: Input: Especifica el nmero de bytes que se van a escribir en la pipe.
pLenght: Output: Puntero al nmero de bytes que se escriben al llamar esta funcin.
MPUSBWrite pone este valor a cero antes de cualquier lectura o de chequear un error.
dwMilliseconds: Input: Especifica el intervalo de time-out en milisegundos. La
funcin vuelve si transcurre el intervalo aunque no se complete la operacin. Si
dwMilliseconds=0, la funcin comprueba los datos de la pipe y vuelve inmediatamente. Si
dwMilliseconds es infinito, el intervalo de time-out nunca termina.

1.7.3 Drivers
Para que el ordenador pueda reconocer y comunicarse con el PIC necesita instalar un
determinado driver que tambin proporciona Microchip MCHPUSB.SYS. Al conectar el
PIC al PC mediante el cable USB, Windows pedir que se seale la direccin donde se
encuentra ste driver, una vez sealada la ruta ste se instalar, si todo ha ido

22

correctamente aparecer un mensaje explicando que el proceso se ha completado


satisfactoriamente.

1.7.4 Manual de Funcionamiento


El programa realiza las siguientes acciones:
-

Pide los nombres de los equipos y los guarda


Analiza la calibracin de los sensores
Obtiene los tiempos de cada equipo y los ordena

A continuacin se explica el funcionamiento:


Obtener el nombre de los equipos

Figura12. Software de control

En el texto en blanco se escribe el nombre del equipo y se hace clic en Introducir.


De esta manera se irn introduciendo todos los equipos. Una vez todos introducidos, se
har clic en Todos los equipos introducidos.
Antes de empezar a hacer correr a los robots se debera de comprobar que los
sensores esten bin fijados. Para ello se pulsar Sensores calibrados?. Debajo de este
botn se mostrar si falla algn sensor o todo est bin.
Despus de este procedimiento ya se puede poner en marcha la carrera. Para ello se
har clic en Iniciar. Una vez el robot pase por delante de los sensores se podrn ver los
tiempos parciales y totales que va marcando

23

Figura 13. Software de control


Una vez concluida la vuelta del robot, se har clic en siguiente jugador, de esta
manera se actualiza la clasificacin de los robots, donde se mostrarn por orden de ms
rpido a ms lento.

Figura 14. Software de control


Cuando el siguiente robot este listo para empezar, haremos otra vez clic en Iniciar!
y se ir repitiendo este procedimento hasta finalizar la competicin.
A medida que los robots hacen el recorrido, se esbribe en un documento TXT el
nombre del equipo y junto a l, los tiempos que va realizando el robot. De esta forma los
equipos podrn ver claramente dnde estn los puntos fuertes o dbiles del mismo.

24

Memoria de Clculo

25

2.1

Clculos software

2.1.1 Timer 0
En este proyecto, se usa para cronometrar el tiempo que tardan los robots en realizar
un tramo o todo el circuito.
Para producir una interrupcin cada 50 ms es necesario configurar el Timer. El
tiempo entre interrupciones sigue esta ecuacin:

(2)

De esta manera cargando un valor de 61 y usando un preescaler de 256 conseguimos


provocar interrupciones cada 50 ms.

(3)
Esta es la forma correcta de hacer la configuracin del Timer0. Pero debido a algun fallo,
el Timer 0 no interrumpe cuando se quiere. Aunque se desconoce la causa, se ha consegido
que el timer interrrumpa cada 44 ms. Con esto se sigue cumpliendo el objetivo del
proyecto y todas las restricciones que se han pedido.
2.2

Clculos Hardware

2.2.1 Comprobar la salida de los sensores


El mtodo para reconocer el paso del robot por un sensor es mediante la encuesta del pin
de salida de este sensor, el cual est conectado al microcontrolador.
Para saber a qu cada cuanto tiempo hay que testear este pin, se deben tener en
cuenta los siguientes factores:
- Velocidad de los robots
- Se debe medir el tiempo de paso con una resolucin de dcimas de segundo
26

La velocidad de los robots


En este apartado se va a calcular la velocidad media de un robot. Sabiendo con
anterioridad que los robots ms veloces conseguan recorrer el circuito en 14 segundos,
tiempo muy difcil de rebajar, se supone que los robots no llegarn en menos de 10
segundos.
Para asegurar que el sistema funcionar prcticamente en cualquier circunstancia se
va disear el sistema pensando que un robot podr hacer el recorrido en estos 10 segundos.
Sabiendo de antemano que el circuito mide 750 aproximadamente y teniendo en cuenta la
siguiente ecuacin:
V=E/T

(4)

Resulta que:
V = 750 / 10 = 75 cm/s

(5)

Por ltimo, suponiendo que la parte lateral de un robot como mnimo medir 5 cm,
un caso extremo ya que hasta ahora todos miden ms, el sensor detectar al robot durante:
T=E/V

(6)

T = 5 / 75 = 66,6 ms

(7)

En este caso, para que en cualquier circunstancia el microcontrolador lea


debidamente la salida del sensor y no se pierda el pase del robot. Se podra muestrear cada
65 ms.
Medir el paso del robot con una resolucin de dcimas de segundo
Como se ha dicho anteriormente, en las especificaciones del proyecto se pide que la
resolucin sea de dcimas de segundo. Para poder hacerlo, se deber muestrear cada 50
ms, ya que si se quiere muestrar una seal, se debe de hacer al doble de su frecuencia. De
esta forma el error cometido ser, como mucho, de media dcima de segundo.
Sin duda el factor ms restrictivo es la resolucin en dcimas de segundo ya que
requiere una frecuencia de muestro ms elevada que el factor velocidad del robot. De
manera que las salidas de los sensores se van a muestrear cada 50 ms.

27

Planos

28

3.1

Esquema de la placa PCB

29

3.2

Diagrama de conexiones

30

3.3

Diagrama de conexiones IS471F

31

Presupuesto

32

4.1

Introduccin
En este apartado se mostrar el coste real que ha supuesto la realizacin del proyecto.
Para esquematizar mejor este tema, se divide el presupuesto en dos partes:
- Componentes
- Mano de obra

4.2

Precios unitarios

4.2.1 Componentes
U

DESCRIPCION

Resistencia220

Resistencia12

DiodoLEDrojo

DiodoLEDverde

Condensador33uF

Condensadorde47uF

Condensadormica22pF

Condensador100uF

Cristal20MHZ

ConectorUSBhembraTipoA

CableUSBMM

PIC18F2550

PRECIO()

0,05
CINCOCNTIMO

0,05
CINCOCNTIMO

0,32
TRENTAYDOSCNTIMO

0,32
TRENTAYDOSCNTIMO

0,12
DOCECNTIMO

0,22
VEINTECNTIMO

0,15
QUINCECNTIMO

0,22
VEINTICINTOCNTIMO

OCHENTE
Y
NUEVE
0,89 CNTIMO

1,23
UNEUROconVEINTITRES

CNTIMO

4,40
CUATROEUROSCON

CUARENTACNTIMO

CUATRO EUROS con


4,81 OCHENTA

YUNCNTIMOS
33

ZcaloDIP20

ZcaloDIP8

SensorIS471F

0,45

0,15

4,46

CUARENTA
Y
CINCO
CNTIMO

QUINCECNTIMO

CUATROEUROSCON
CUARENTA
Y
SEIS
CNTIMO

4.2.2 Mano de obra


U

h
h

4.3

DESCRIPCION

IngenieroTcnicoIndustrial
TcnicoMontador

PRECIO

16,00
9,00

()

DIECISEISEUROS
NUEVEEUROS

Precios descompuestos

4.3.1 Componentes
U

DESCRIPCION

Resistencia220

Resistencia12

DiodoLEDrojo

DiodoLEDverde

Condensador33uF

Condensadorde47uF

Condensadormica22pF

Condensador100uF

Cristal20MHZ

PRECIO()

0,05

0,05

0,32

0,32

0,12

0,22

0,15

0,22

0,89

34

UNIDADES

2,00

5,00

1,00

1,00

5,00

1,00

2,00

1,00

1,00

SUBTOTAL()

0,10

0,25

0,32

0,32

0,60

0,22

0,30

0,22

0,89

Conector USB hembra


TipoA
1,23

CableUSBMM
4,40

PIC18F2550
4,81

ZcaloDIP20
0,45

ZcaloDIP8
0,15

SensorIS471F
4,46

1,00

1,00

1,00

1,00

1,00

5,00

1,23

4,40

4,81

0,45

0,15

22,30

4.3.2 Mano de obra


U

4.4

DESCRIPCION

IngenieroTcnicoIndustrial

TcnicoMontador

PRECIO()

16,00

9,00

Resumen del presupuesto


Componentes36,56
Mano de obra..4827,00
Total.. 4863,56

35

UNIDADES

300

SUBTOTAL()

4800

27

Bibliografa y referencias

36

5.1

Bibliografa

Microchip MPLab IDE gua de usuario


http://ww1.microchip.com/downloads/en/DeviceDoc/MPLAB_User_Guide_51519c.pdf
[30/6/10]
Eduardo Garca Breijo, Compilador C Ccs Y Simulador Proteus Para
Microcontroladores Pic, Alfaomega, 2008.
John Sharp, Microsoft Visual C# 2005 step by step, Microsoft Press, 2005.
Jeff Kent, Visual C# 2005 demystified, McGraw-Hill Osborne Media, 2005.
Wikipedia USB http://es.wikipedia.org/wiki/Universal_Serial_Bus [30/6/10]
Foros de electrnica http://www.forosdeelectronica.com/f24/control-dispositivostraves-modulo-usb-pic18f2550-17458/ [30/6/10]
Mucho trasto http://www.muchotrasto.com/ [30/6/10]
Hobby PIC http://www.hobbypic.com/ [30/6/10]
Un poco de electrnica http://www.unpocodelectronica.netau.net/mis-primerospasos-con-el-18f4550-parte10#mpusb1 [30/6/10]

5.2

Referencias
[1] DatasheetCatalog http://www.datasheetcatalog.org/datasheet/Sharp/mXvrzty.pdf
[30/6/10]
[2] DatasheetCatalog
http://www.datasheetcatalog.org/datasheet/microchip/39617a.pdf [30/6/10]
[3] Microchip
http://ww1.microchip.com/downloads/en/DeviceDoc/MPLAB_IDE_8_50.zip
[30/6/10]
[4] Microchip http://ww1.microchip.com/downloads/en/devicedoc/51331b.pdf
[30/6/10]
[5] Ccsinfo http://www.ccsinfo.com/ccsfreedemo.php [30/6/10]
37

[6] Labcenter http://www.labcenter.co.uk/download/prodemo_autodl_general.cfm


[30/6/10]

[7] Softonic http://microsoft-visual-cpp-2008-express.softonic.com [30/6/10]


[8] Microchip
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2
035 [30/6/10]

38

Anexos

39

6.1

Cdigo fuente firmware

#include <18f2550.h>
#fuses NOMCLR,HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,
PLL5,CPUDIV1,VREGEN,NOPBADEN
#use delay(clock=4000000)

#define USB_HID_DEVICE
HID

FALSE //deshabilitamos el uso de las directivas

#define USB_EP1_TX_ENABLE USB_ENABLE_BULK


//para IN bulk/interrupt transferencias

//habilitar EP1(EndPoint1)

#define USB_EP1_RX_ENABLE USB_ENABLE_BULK


//para OUT bulk/interrupt transferencias

//habilitar EP1(EndPoint1)

#define USB_EP1_TX_SIZE
11
//almacenar en el tx del endpoint 1

//tamaano que se va

#define USB_EP1_RX_SIZE
11
//almacenar en el rx del endpoint 1

//tamaano que se va

#include <pic18_usb.h>
//Microchip PIC18Fxx5x Hardware layer para
para usar el driver USB del pic en CCS
#include <USB_DESC_SCOPE.h>
//Configuracin del USB y los
//descriptores para este dispositivo
#include <usb.c>
//informes descriptivos

//controla seales del sistema usb y consisgue

#define led_rojo

PIN_A1

#define led_verde

PIN_A0

#define LED_ON

output_high

#define LED_OFF

output_low

#BYTE TRISB=0x93
#BYTE PORTB=0x81
#BYTE TRISC=0x94
#BYTE PORTC=0x82
#BYTE ITCON2=0XF1

long tics, tics2, total_tics;//variables que cuentan los tics de la


//interrupcin
int cuenta1, inicia;
//cuenta1, dependiendo de este valor se aumenta tics o tics2
//inicia, si est a 0 se ejecutar ini_int()

int entrada, sensor, sentido, empieza, fin;

40

//entrada, si su valor es 1 significa que el robot acaba de pasar por un


//sensor, entonces hay que pasarle el valor de la variable tics, tics2 o
//total_tics al PC

//sensor, su valor ndica cual es el sensor que hay que comprobar

//sentido, toma 3 valores, 0 o 1 dependiendo del sentido en que se


//realiza
//el recorrido y 2 si el sentido an no est definido.

//empieza, ndica cuando hay que empezar a contar tics

//fin, como su nombre indica, esta variable confirma el fin del recorrido

/************************************************************************
**/

void inicializaciones()//inicializamos algunas variables y configuramos


// de tal forma que el puerto B todo sean entradas digitales.
{
tics=0;
cuenta1=1;
inicia=0;
LED_OFF(PIN_B7);
bit_clear(ITCON2,7);
TRISB=0b11111111;

//********************************************************************

void ini_int() //inicializamos algunas variables y programamos el TIMER0


{
total_tics=0;
tics2=0;
entrada=0;
fin=0;
tics=0;
inicia=1;

41

empieza=0;
sensor=0;
sentido=2;
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_8);
enable_interrupts(INT_TIMER0);
enable_interrupts(global);
set_timer0(61);
}

//*********************************************************************

void end_int()//deshabilitamos las interrupciones del TIMER0


{
disable_interrupts(INT_TIMER0);
}

//*********************************************************************

void main()

int confirmacion[1];
int array[11]; //enviaremos el valor de esta variable,
//que contendr los tics, al PC

int recibe[1]; //nos indicar el valor del dato recibido del PC


int noinput[1];//enviaremos el valor de esta variable al PC para
//informale de que no se ha detectado el robot.
int fallo_sensor[1];//contiene el estado de los sensores
int buffer;

//la usaremos para trabajar con los buffers

int detect; //lo usamos en la funcin que detecta si falla algn


//sensor
LED_ON(led_rojo);

//encendemos led rojo

LED_OFF(led_verde);

//apagamos el verde

usb_init();

//inicializamos usb

usb_task();
interrupciones

//habilita periferico usb e

42

usb_wait_for_enumeration();
//esperamos hasta que el PicUSB sea
//configurado por el host si no hay se queda

LED_OFF(led_rojo);
delay_ms(350);
LED_ON(led_rojo);
delay_ms(100);
LED_OFF(led_rojo);
delay_ms(100);
LED_ON(led_rojo);
delay_ms(100);
LED_OFF(led_rojo);
delay_ms(100);
LED_ON(led_rojo);
delay_ms(100);
LED_OFF(led_rojo);//encendemos led verde cuando ya es reconocido por
//el pc
LED_ON(led_verde);

confirmacion[0]=0x31;
noinput[0]=0x32;
inicializaciones();

if(usb_enumerated())

//si el PicUSB est configurado

{
while(true)

//haz por siempre

{
if (usb_kbhit(1)) //si el endpoint de salida contiene datos
{

usb_get_packet(1, recibe, 1);//guardamos en recibe[0]


//los datos recibidos del PC

if(recibe[0]==0x20)//si recibimos un 0x20, comprobamos los


//sensores
{
fallo_sensor[0]=0x01;
detect=0;

43

if(input(PIN_B7)==TRUE)
{
detect=1;
fallo_sensor[0]=0x07;
}

if((input(PIN_B6)==TRUE)&&(detect==0))
{
fallo_sensor[0]=0x06;
detect=1;
}

if((input(PIN_B5)==TRUE)&&(detect==0))
{
fallo_sensor[0]=0x05;
detect=1;
}

if((input(PIN_B4)==TRUE)&&(detect==0))
{
fallo_sensor[0]=0x04;
detect=1;
}

if((input(PIN_B3)==TRUE)&&(detect==0))
{
fallo_sensor[0]=0x03;

usb_put_packet(1, fallo_sensor, 1, USB_DTS_TOGGLE);


//enviamos el sensor que falla

if (recibe[0]==0x50)//si recibimos un 0x50, inicializamos


{

//algunas variables y paramos la int.


tics=0;
tics2=0;

44

cuenta1=1;
sensor=0;
end_int();
}

if(recibe[0]==0x40)//si recibimos un 0x40, comprobaremos si


{

// la variable entrada tiene valor 0 1 o 2. Si vale 1,


// significa que se ha detectado el paso del robot, por lo
// tanto hay mandar al PC los tics. Si vale 2 significa ha
// pasado por el ltimo sensor y hay que mandar el valor de
// la variable total_tics. Por ltimo si la variable vale 0 significa que
//no se ha detectado el paso del robot por lo tanto mandamos no_input[0].

if(inicia==0)//si es la primera vez, habilitamos la


//int.
{
ini_int();
}

if(entrada==2)//si es el ltimo parcial, le mandamos el


//tiempo total, total_tics
{
entrada=0;
array[0]=0x18;
buffer=1;
while(buffer<=10)
{
array[buffer]=0;
buffer++;
}

buffer=1;
while(total_tics>0)//guardamos en array el valor de
{

//total_tics
array[buffer]=array[buffer]+1;
if(array[buffer]==255)//si est al mximo
{

45

buffer++;
}
total_tics=total_tics-1;
}

usb_put_packet(1, array, 11, USB_DTS_TOGGLE);//lo


//enviamos
inicia=0;//lo dejamos preparado para la siguiente
//vuelta
}

if(entrada==0)//si no se ha detecado el robot


{
usb_put_packet(1, noinput, 1, USB_DTS_TOGGLE);
}
if(entrada==1)// si se ha detectado el paso del robot
{
entrada=0;//inicializamos otro vez

if(cuenta1==1)//si estamos aumentando tics


{
cuenta1=0;
array[0]=0x17;//con esto indicamos al PC
//que el valor enviado corresponden a los tics
//contados

array[1]=(tics/2)+0.5;//copiamos la variable tics


array[2]=tics-array[1];
tics=0;
}
else//si estamos aumentando tics2
{
cuenta1=1;
array[0]=0x17;//con esto indicamos al PC
//que el valor enviado corresponden a los tics
//contados

array[1]=(tics2/2)+0.5;//copiamos la variable
//tics2
array[2]=tics2-array[1];
tics2=0;
}

46

usb_put_packet(1, array, 11, USB_DTS_TOGGLE);//lo


//enviamos

if(fin==1)//si es el final del recorrido


{
fin=0;
entrada=2;//para que se envie el tiempo total
//la prxima vez
}

}
}

}
}
}

//********************************************************************

#int_TIMER0 // declaramos interrupcin del timer 0


void TIMER0_isr(void)
{

set_timer0(61);//cargamos otra vez el TIMER0

if(sensor==0)//si hay que comprobar el estado del primer sensor


{
if(input(PIN_B7)==true)//comprobamos el estado del primer sensor
{
empieza=1;//si es cierto empieza a contar tics
sensor=1;//y pasamos a comprobar el segundo sensor
}
}

if(sensor==1)//Aqui descubrimos en que sentido circula


{

47

if(input(PIN_B6)==true)//sentido 0
{
sensor=2;//comprobaremos el siguiente sensor
entrada=1;//hay que enviar los tics contados
sentido=0;//definimos el sentido de la vuelta
}

if(input(PIN_B3)==true)// sentido 1
{
sensor=2;//comprobaremos el siguiente sensor
entrada=1;//hay que enviar los tics contados
sentido=1;//definimos el sentido de la vuelta
}

if(sentido==0)
{
if(sensor==2)//si toca comprobar este sensor
{
if(input(PIN_B5)==true)//comprobamos el sensor
{
sensor=3;//pasamos a comprobar el siguiente sensor
entrada=1;// hay que enviar los tics contados
}
}

//Se aplica el mismo mtodo con todos los sensores

if(sensor==3)
{
if(input(PIN_B4)==true)
{
sensor=4;
entrada=1;
}
}

if(sensor==4)
{

48

if(input(PIN_B3)==true)
{
sensor=5;
entrada=1;
}
}

if(sensor==5)
{
if(input(PIN_B7)==true)//si llegamos al ltimo sensor
{
fin=1;
entrada=1;
sensor=0;//inicializamos para sigiuente vuelta
end_int();//deshabilitamos las interrupciones
}
}
}

//aplicamos el mismo mtodo si el robot robot circula en el otro


sentido

if(sentido==1)
{
if(sensor==2)
{
if(input(PIN_B4)==true)
{
sensor=3;
entrada=1;
}
}

if(sensor==3)
{
if(input(PIN_B5)==true)
{
sensor=4;
entrada=1;
}
}

49

if(sensor==4)
{
if(input(PIN_B3)==true)
{
sensor=5;
entrada=1;
}
}

if(sensor==5)
{
if(input(PIN_B6)==true)
{
entrada=1;
sensor=0;
fin=1;
end_int();
}
}
}

//Independientemente del valor de cuenta1 aumentamos total_tics

if(cuenta1==1)//Si estamos aumentando tics


{
if(empieza==1)//Si debemos contar tics
{
total_tics++;
tics++;
}
}
else//Si estamos aumentando tics2
{
if(empieza==1)//Si debemos contar tics
{
total_tics++;
tics2++;
}
}

50

6.2

Cdigo fuente del software de control

6.2.1 Form1.cs
using
using
using
using
using
using
using
using

System;
System.Collections.Generic;
System.ComponentModel;
System.Data;
System.Drawing;
System.Linq;
System.Text;
System.Windows.Forms;

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
PicUSBAPI usbapi = new PicUSBAPI();

public Form1()
{
InitializeComponent();
}
// Variables globales//
int
int
int
int
int

ini_var=0;//segun su valor inicializaremos algunas variables


parcial = 0;//indica el tramo en que se encuentra el robot
num_equipos = 0;//indica el nmero de equipos
actual = 1;//su valor indica el jugador que esta activo
ronda = 1;//indica la ronda en que nos encontramos

string[] nombre_jugador = new string[15];//vector que


//guarda el nombre de los equipos
double[] tiempo_total = new double[15];//vector que guarda el
//el tiempo total de cada equipo
double[] clas = new double[15];//vector que guarda el timempo
//total de cada equipo ordenados de menor a mayor
string[] equipo_posicion = new string[15];//vector que
//guarda los nombres de los equipos ordenados segn
//el vector anterior
//***************************//

private void timer1_Tick(object sender, EventArgs e)


{
//Timer del PC, salta cada 50 ms si est habilitado

51

double flag;
flag = usbapi.entrada();// esta funcin nos devuelve
//un 0 si hay error de comunicacin, un 2 si el micro no
//ha detectada an el paso del robot, o nos devuelve el
//nmero de tics que el micro ha calculado en un parcial
if ((flag != 2)&&(flag!=0))
{
flag = flag * (0.044);// 44 ms por interrupcion
string var2 = flag.ToString();//var2 contendr
//el valor de flag en STRING para poder
//visualizarlo en un textbox o un label.
if (parcial == 1)//Si estamos en el parcial 1
{
texto2.Text = var2;//Escribelo en su
//lugar correspondiente para visualizarlo
escribir(var2);//Funcin que escribe el dato
//enviado(var2) en un bloc de notas
}
if (parcial == 2)
{
escribir(var2);
texto3.Text = var2;
}
if (parcial == 3)
{
escribir(var2);
texto4.Text = var2;
}
if (parcial == 4)
{
escribir(var2);
texto5.Text = var2;
}
if (parcial == 5)//Ultimo parcial
{
escribir(var2);
ultimo_parcial.Text = var2;
}
if (parcial == 6)//Tiempo total
{
//El tiempo total no se calcula mediante la
//suma de los parciales, sino que el pic envia
//ste dato, de esta forma es ms exacto.
timer1.Enabled = false;//ya hemos acabado
parcial = 0;//inicializamos para la siguiente
escribir(var2);
tiempo_total[actual] = flag;//El tiempo total
//de este equipo ser igual flag
texto6.Text = tiempo_total[actual].ToString();
//mostramos su tiempo total
}

52

parcial++;//Siguiente parcial
}
if (flag == 0)
{
timer1.Enabled = false;
}

private void button4_Click(object sender, EventArgs e)


{
//Botn de Iniciar!
int ini=0;
if (ini_var == 1)//Si iniciamos una ronda nueva
{
ini_var = 0;
while (ini <= 14)//Inicializamos las variables
{
clas[ini] = 9999;
equipo_posicion[ini] = "";
tiempo_total[ini] = 999;
ini++;
}
//No mostramos nada relacionado con la
//clasificacin ya que lo que veriamos
//sera falso
p1.Visible = false;
primero.Visible = false;
tiempo1.Visible = false;
p2.Visible = false;
segundo.Visible = false;
tiempo2.Visible = false;
p3.Visible = false;
tercero.Visible = false;
tiempo3.Visible = false;
p4.Visible = false;
cuarto.Visible = false;
tiempo4.Visible = false;
p5.Visible = false;
quinto.Visible = false;
tiempo5.Visible = false;
p6.Visible = false;
sexto.Visible = false;
tiempo6.Visible = false;
p7.Visible = false;
septimo.Visible = false;
tiempo7.Visible = false;
p8.Visible = false;
octavo.Visible = false;
tiempo8.Visible = false;

53

p9.Visible = false;
noveno.Visible = false;
tiempo9.Visible = false;
p10.Visible = false;
decimo.Visible = false;
tiempo10.Visible = false;
p11.Visible = false;
undecimo.Visible = false;
tiempo11.Visible = false;
p12.Visible = false;
duodecimo.Visible = false;
tiempo12.Visible = false;
p13.Visible = false;
decimotercero.Visible = false;
tiempo13.Visible = false;

}
escribir(nombre_jugador[actual]);//Escribimos en
//el txt el nombre del equipo actual
parcial = 1;//Inicializacin
timer1.Enabled = true;//Activmos el timer
button4.Visible = false;//Desactivamos este botn
}
private void button5_Click(object sender, EventArgs e)
{
//Botn de siguiente jugador
timer1.Enabled = false;//deshabilitamos el timer
escribir("\r\n");
//Escribimos un salto de linea
//txt para diferenciarse del otro jugador
parcial = 1;//Inicializamos
usbapi.apagar();//Esta funcin hace que el PIC
//Inicialice algunas variables suyas.
clasifica();//Esta funcin ordena los equipos segn
//los tiempos, de menor a mayor y los muestra.
actual++;//Pasamos al siguiente jugador
if (actual > num_equipos)//Si todos los equipos
//han terminado
{
ronda++;//Pasamos a la siguiente rondo
label18.Text = ronda.ToString();//Mostramos
//en que ronda estamos
actual = 1;//Volvemos al primer equipo
ini_var = 1;//Con esta variable a 1 se
//inicializarn variables
}
string equipo_actual=nombre_jugador[actual].ToString();
label6.Text=equipo_actual;//Mostramos por pantalla el
//nombre del equipo al que le toca correr.
//Borramos los tiempos parciales del equipo anterior
texto2.Text = "";
texto3.Text = "";

54

texto4.Text = "";
texto5.Text = "";
ultimo_parcial.Text = "";
texto6.Text = "";
button4.Visible = true;//Volvemos a poner visible
//el botn de Iniciar!
}
private void button6_Click(object sender, EventArgs e)
{
//Botn de introducir equipo
if (textBox1.Text != "")
{
num_equipos++;
nombre_jugador[num_equipos] = textBox1.Text;
textBox1.Text = "";
if (num_equipos == 13)
{
button6.Visible = false;
}
}
}
private void button7_Click(object sender, EventArgs e)
{
//Botn de todos los equipos introducidos
//Hacemos visibles algunos elementos

label1.Visible = true;
label2.Visible = true;
label3.Visible = true;
label4.Visible = true;
label5.Visible = true;
label6.Visible = true;
label7.Visible = true;
label9.Visible = true;
label16.Visible = true;
label18.Visible=true;
texto2.Visible = true;
texto3.Visible = true;
texto4.Visible = true;
texto5.Visible = true;
texto6.Visible = true;
ultimo_parcial.Visible = true;
button4.Visible = true;
button5.Visible = true;
button6.Visible = false;
button7.Visible = false;
string equipo_actual = nombre_jugador[actual].ToString();
label6.Text = equipo_actual;
//Inicializamos variables
int ini_clas = 0;
while (ini_clas <= 14)
{

55

clas[ini_clas] = 9999;
equipo_posicion[ini_clas] = "";
tiempo_total[ini_clas] = 9999;
ini_clas++;
}

string cabezera = "equipos y tiempos\r\n";


// Crea un archivo txt con el nombre test.txt y escribe
// el contenido de cabezara en l.
System.IO.StreamWriter file = new
System.IO.StreamWriter("c:\\test.txt");
file.WriteLine(cabezera);
file.Close();
}

private void clasifica()


{
int pos, desplazar;
pos = 1;
while ((tiempo_total[actual] >= clas[pos])&&(pos<14))
{
pos++;
}
desplazar = 13;
while (desplazar >= pos)
{
clas[desplazar + 1] = clas[desplazar];
equipo_posicion[desplazar+1] =
equipo_posicion[desplazar];
desplazar--;
}
equipo_posicion[pos] = nombre_jugador[actual];
clas[pos] = tiempo_total[actual];
desplazar = 13;
if (actual >= 1)
{
p1.Visible = true;
primero.Visible = true;
tiempo1.Visible = true;
primero.Text = equipo_posicion[1];
tiempo1.Text = clas[1].ToString();
}
if (actual >= 2)
{
p2.Visible = true;
segundo.Visible = true;
tiempo2.Visible = true;
segundo.Text = equipo_posicion[2];
tiempo2.Text = clas[2].ToString();

56

}
if (actual >= 3)
{
p3.Visible = true;
tercero.Visible = true;
tiempo3.Visible = true;
tercero.Text = equipo_posicion[3];
tiempo3.Text = clas[3].ToString();
}
if (actual >= 4)
{
p4.Visible = true;
cuarto.Visible = true;
tiempo4.Visible = true;
cuarto.Text = equipo_posicion[4];
tiempo4.Text = clas[4].ToString();
}
if (actual >= 5)
{
p5.Visible = true;
quinto.Visible = true;
tiempo5.Visible = true;
quinto.Text = equipo_posicion[5];
tiempo5.Text = clas[5].ToString();
}
if (actual >= 6)
{
p6.Visible = true;
sexto.Visible = true;
tiempo6.Visible = true;
sexto.Text = equipo_posicion[6];
tiempo6.Text = clas[6].ToString();
}
if (actual >= 7)
{
p7.Visible = true;
septimo.Visible = true;
tiempo7.Visible = true;
septimo.Text = equipo_posicion[7];
tiempo7.Text = clas[7].ToString();
}
if (actual >= 8)
{
p8.Visible = true;
octavo.Visible = true;
tiempo8.Visible = true;
octavo.Text = equipo_posicion[8];
tiempo8.Text = clas[8].ToString();
}
if (actual >= 9)
{
p9.Visible = true;
noveno.Visible = true;
tiempo9.Visible = true;

57

noveno.Text = equipo_posicion[9];
tiempo9.Text = clas[9].ToString();
}
if (actual >= 10)
{
p10.Visible = true;
decimo.Visible = true;
tiempo10.Visible = true;
decimo.Text = equipo_posicion[10];
tiempo10.Text = clas[10].ToString();
}
if (actual >= 11)
{
p11.Visible = true;
undecimo.Visible = true;
tiempo11.Visible = true;
undecimo.Text = equipo_posicion[11];
tiempo11.Text = clas[11].ToString();
}
if (actual >= 12)
{
p12.Visible = true;
duodecimo.Visible = true;
tiempo12.Visible = true;
duodecimo.Text = equipo_posicion[12];
tiempo12.Text = clas[12].ToString();
}
if (actual >= 13)
{
p13.Visible = true;
decimotercero.Visible = true;
tiempo13.Visible = true;
decimotercero.Text = equipo_posicion[13];
tiempo13.Text = clas[13].ToString();
}
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button8_Click(object sender, EventArgs e)
{
int fallo;
fallo=usbapi.sensores();
if ((fallo != 10)&&(fallo!=0))
{
label8.Text = fallo.ToString();
}
if (fallo == 0)
{
label8.Text = "Fallo de comunicacin";
}
if (fallo == 10)

58

{
label8.Text = "Sensores OK";
}
}

private void escribir(string time)


{
// Read the file as one string.
System.IO.StreamReader myFile =
new System.IO.StreamReader("c:\\test.txt");
string myString = myFile.ReadToEnd();
myFile.Close();
System.IO.StreamWriter file = new
System.IO.StreamWriter("c:\\test.txt");
myString = myString + time + "
";
file.Write(myString);
file.Close();
}
private void label5_Click(object sender, EventArgs e)
{
}

}
}

59

6.2.2 PICUSBAPI.CS
using
using
using
using

System;
System.Collections.Generic;
System.Windows.Forms;
System.Runtime.InteropServices; // Clase para importar DLL

using PVOID = System.IntPtr;


using DWORD = System.UInt32;
namespace WindowsFormsApplication1
{
//Importamos las funciones de la dll de Microchip
unsafe public class PicUSBAPI
{
#region Definicin de los Strings: EndPoint y VID_PID
string vid_pid_norm = "vid_04d8&pid_0012";
string out_pipe = "\\MCHP_EP1";
string in_pipe = "\\MCHP_EP1";
#endregion
#region Funciones importadas de la DLL: mpusbapi.dll
[DllImport("mpusbapi.dll")]
private static extern DWORD _MPUSBGetDLLVersion();
[DllImport("mpusbapi.dll")]
private static extern DWORD _MPUSBGetDeviceCount(string
pVID_PID);
[DllImport("mpusbapi.dll")]
private static extern void* _MPUSBOpen(DWORD instance, string
pVID_PID, string pEP, DWORD dwDir, DWORD dwReserved);
[DllImport("mpusbapi.dll")]
private static extern DWORD _MPUSBRead(void* handle, void* pData,
DWORD dwLen, DWORD* pLength, DWORD dwMilliseconds);
[DllImport("mpusbapi.dll")]
private static extern DWORD _MPUSBWrite(void* handle, void*
pData, DWORD dwLen, DWORD* pLength, DWORD dwMilliseconds);
[DllImport("mpusbapi.dll")]
private static extern DWORD _MPUSBReadInt(void* handle, DWORD*
pData, DWORD dwLen, DWORD* pLength, DWORD dwMilliseconds);
[DllImport("mpusbapi.dll")]
private static extern bool _MPUSBClose(void* handle);
#endregion

void* myOutPipe;
void* myInPipe;
//***************************************************************
public void OpenPipes()
{
//Abrimos las "pipes" para realiar la comunicacion
DWORD selection = 0;

60

myOutPipe = _MPUSBOpen(selection, vid_pid_norm, out_pipe, 0,


0);
myInPipe = _MPUSBOpen(selection, vid_pid_norm, in_pipe, 1,
0);
}
//***************************************************************
public void ClosePipes()
{
//Al concluir la comunicacin cerrramos las "pipes"
_MPUSBClose(myOutPipe);
_MPUSBClose(myInPipe);
}
//***************************************************************
private void SendPacket(byte* SendData, DWORD SendLength)
{
uint SendDelay = 20;
DWORD SentDataLength;
OpenPipes();//Abrimos la comunicacin
_MPUSBWrite(myOutPipe, (void*)SendData, SendLength,
&SentDataLength, SendDelay);
//Usamos la funcin de Microchip para enviar datos
ClosePipes();//Cerramos la comunicacin
}
//***************************************************************
private void ReceivePacket(byte* ReceiveData, DWORD*
ReceiveLength)
{
uint ReceiveDelay = 20;
DWORD ExpectedReceiveLength = *ReceiveLength;
OpenPipes();//Abrimos la comunicacin
_MPUSBRead(myInPipe, (void*)ReceiveData,
ExpectedReceiveLength, ReceiveLength, ReceiveDelay);
//Usamos la funcin de Microchip para recibir datos
ClosePipes();//Cerramos la comunicacin
}
//***************************************************************
public double entrada()
{
//Esta funcin le pregunta al micro si tiene
//datos para pasarle, si los tiene se los envia,
//si no los tiene, le dice que no el robot an no
//ha pasado por el sensor.
byte* send_buf = stackalloc byte[1];
byte* receive_buf = stackalloc byte[11];
DWORD RecvLength = 11;
double total;
send_buf[0] = 0x40;//Dato a enviar

61

SendPacket(send_buf, 1);//Envia el dato


ReceivePacket(receive_buf, &RecvLength);
//Recibimos contestacin, que se guarda
//en receive_buf[]

if (receive_buf[0] == 0x17)
{
//Si en el primer byte tenemos un 0x17,
//significa que hemos recibido un tiempo
//parcial. receive_buf[1]y receive_buf[2]
//contienen los tics que el micro a calculado
total = (receive_buf[1] + receive_buf[2]);

return (total);
}
if (receive_buf[0] == 0x18)
{
//Un 0x18 significa que hemos recibido
//el tiempo total de la vuelta
//Los bytes del 1 al 10 contienen los tics
//totales
int llenar_buf=1;
total = 0;
//Sumamos todos los tics
while (llenar_buf <= 10)
{
total = total + receive_buf[llenar_buf];
llenar_buf++;
}
return (total);
}
if (receive_buf[0] == 0x32)
{
//Si recibimos un 0x32 significa que no
//hay datos para coger
return (2);
}
return (0);
}

//***************************************************************

public int sensores()


{
byte* send_buf = stackalloc byte[1];

62

byte* receive_buf = stackalloc byte[1];


DWORD RecvLength = 1;
send_buf[0] = 0x20;
SendPacket(send_buf, 1);
//Le enviamos un 0x20, as el micro
//comprobar el estado de los sensores
//y nos dir si hay alguno que est
//mal orientado
ReceivePacket(receive_buf, &RecvLength);
//Si el micro nos envia un 0x01, siginifica
//que todo est bin
if (receive_buf[0] == 0x01)
{
return (10);
}
else
{
if (receive_buf[0] == 0x07)
{
//Si recibimos un 0x07
//falla el sensor 1
return (1);
}
//Comprobamos lo mismo
//a continuacin
if (receive_buf[0] == 0x06)
{
return (2);
}
if (receive_buf[0] == 0x05)
{
return (3);
}
if (receive_buf[0] == 0x04)
{
return (4);
}
if (receive_buf[0] == 0x03)
{
return (5);
}
//Si devuelve un 0 es que hay fallo de
//comunicacin
return (0);
}
}

//***************************************************************

public int apagar()


{
byte* send_buf = stackalloc byte[1];
send_buf[0] = 0x50;
SendPacket(send_buf, 1);
//Al enviar un 0x50 al micro, le indicamos

63

//que inicialice algunas variables


return(1);
}
//***************************************************************

}
}

64

También podría gustarte