Top Banner
ESCUELA SUPERIOR DE INGENIEROS DE SEVILLA INGENIERÍA EN AUTOMÁTICA Y ELECTRÓNICA INDUSTRIAL PROYECTO FINAL DE CARRERA DISEÑO E IMPLEMENTACIÓN DE UNA TARJETA DE CONTROL CON COMUNICACIÓN USB Tutor: José Luís Mora Jiménez Autor: Fernando Bueno Zambruno Sevilla, septiembre de 2013
79

Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Oct 20, 2018

Download

Documents

hoangbao
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

ESCUELA SUPERIOR DE INGENIEROS DE SEVILLA

INGENIERÍA EN AUTOMÁTICA Y ELECTRÓNICA INDUSTRIAL

PROYECTO FINAL DE CARRERA DISEÑO E IMPLEMENTACIÓN DE UNA

TARJETA DE CONTROL CON COMUNICACIÓN USB

Tutor: José Luís Mora Jiménez

Autor: Fernando Bueno Zambruno

Sevilla, septiembre de 2013

Page 2: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 2

Page 3: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 3

INDICE DE CONTENIDOS

Introducción …………………………………… 5

Objeto del proyecto …………………………………… 5

Diseño de la tarjeta …………………………………… 7

Diseño del esquemático …………………………………… 10

Etapa de alimentación …………………………………… 10

Etapa del microcontrolador …………………………………… 11

Diseño de la PCB …………………………………… 14

Programación del microcontrolador …………………………………… 15

Aplicación del PC …………………………………… 16

Diseño de la aplicación …………………………………… 16

Funcionamiento del sistema …………………………………… 18

Funciones de comunicación …………………………………… 18

Diseño de los controles …………………………………… 23

Control Calefactor y de Humidificador …………………………………… 23

Control temperatura y control humedad …………………………………… 23

Presupuesto …………………………………… 27

Recursos Humanos …………………………………… 27

Coste de los componentes y fabricación del PCB …………………………………… 27

Coste Total …………………………………… 28

Conclusión …………………………………… 30

Bibliografía …………………………………… 31

ANEXO 1:Programas del microcontrolador …………………………………… 32

APLICACION_HID.c …………………………………… 32

APLICACION_HID.h …………………………………… 35

shtxx.h …………………………………… 36

Descriptor_easyHID.h …………………………………… 41

ANEXO 2:Programas de la aplicación del PC …………………………………… 47

Form1.cs …………………………………… 47

EasyHID.cs …………………………………… 61

ANEXO 3: Bibliotecas de CCS …………………………………… 63

ANEXO 4: USB- Firmware para dispositivo esclavo

USB de Clase HID

…………………………………… 66

Page 4: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 4

Page 5: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 5

INTRODUCCION

La evolución de la microelectrónica desde principios de los años setenta permite la

aplicación de los microcontroladores a unos costes razonables, en todas las funciones

de la cadena productiva.

Así prácticamente en las máquinas modernas de todo tipo de industrias se acoplan

microcontroladores para automatizar parcial o totalmente su ciclo productivo, y a la

vez efectuar una recogida de datos para gestión de la producción y realizar análisis y

estudios técnicos de fabricación. Las técnicas actuales de fabricación apoyadas de

los microcontroladores , permite el diseño de instalaciones automáticas según el

concepto de fabricación desatendida, es decir, sin necesidad de operarios que vigilen

y trabajen continuamente a pie de máquina.

Objeto del proyecto La redacción del presente proyecto es meramente educacional y su propósito es

la de culminar la finalización de los estudios de ingeniería. Así mismo, el objetivo del

proyecto no ha sido el desarrollo de una aplicación para cubrir una necesidad

especifica de control, sino la demostración de la capacidad de diseño para buscar una

solución a una posible necesidad de control, en otras palabras, la aplicación

desarrollada no va a ser de aplicación, puesto que el problema planteado es

completamente ficticio.

Así el proyecto que aquí se expone, versa sobre el diseño de una aplicación de

control de diversas variables, comprendiendo este tanto el diseño y construcción de

una tarjeta electrónica como la de una aplicación informática.

Las funciones que desempeñará la tarjeta será:

Comunicar con el sensor que captará las variables ambientales.

Adaptar los valores de las variables para su transmisión.

Establecer el protocolo de comunicación con el ordenador.

Recibir las instrucciones para el control de las variables.

Comunicar con los elementos finales la respuesta oportuna, como

resultado de la acción de control.

La aplicación informática se encargará de :

Page 6: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 6

Realizar la comunicación con la tarjeta .

Visualizar los valores de las variable.

Establecer las respuestas adecuadas según los parámetros de cada

control.

Transmisión de las respuestas hacia la tarjeta.

Hay que señalar que el proyecto tiene un emplazamiento es ficticio, además no

se ha realizado maqueta alguna que simule una ubicación de los controles, enfatizado

más en el carácter didáctico de la construcción de la aplicación, y queda fuera de este

proyecto la sintonización de los controles. No obstante, esta afección no supone

ningún impedimento para su posible uso práctico futuro.

Page 7: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 7

DISEÑO DE LA TARJETA

Bajo las premisas marcadas anteriormente, pasamos a la descripción de la tarjeta

diseñada, remarcando y posteriormente ampliando los aspectos más importante.

El núcleo de la tarjeta, va ha ser un microcontrolador, que deberá acometer las

funciones de:

Comunicación con el PC.

Comunicación con el sensor.

Enlace con los elementos finales.

Así se ha seleccionado el microcontrolador

PIC 18F2550 de la casa Microchip. Este

tiene una importante característica y es la

integración de un transceptor de USB 2.0.

Aprovechando esta característica se realizó

la tarjeta de adquisición basada en este

tipo de puerto; Este tiene tres formas

distintas de ser utilizado: HID (Poca

Velocidad, no necesita instalar drivers), CDC

(Velocidad Media, Instala un driver

suministrado por el compilador), DLL

PIC 18F2550 (Alta velocidad, Instala driver

y requiere uso de una DLL,

ambos suministrados por Microchip). Se optó

por la opción HID (Human Interface Device

) debido a que este tipo de dispositivos

implementados por la clase HID es soportado

por la mayoría de Sistemas Operativos

modernos implementando los controladores

necesarios para poder comunicarse con ellos

sin ser necesaria la instalación de ningún

driver adicional por parte del usuario .

Figura 1.

Page 8: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 8

Por otro lado, para la elección de los

sensores que debe tomar los datos de

temperatura y humedad se ha optado por un

sensor digital, ya que existen numerosos

modelos en el mercado y que a la vez aúnan las

lecturas de ambas variables en un mismo

sensor. La elección final del sensor fue para

el SHT75 de la casa Sensirion, que es

capaz de obtener ambos datos, con una gran

precisión y fiabilidad, además se conecta

directamente al microcontrolador ya que se

comunica mediante un bus I2C, además la casa

ofrece una biblioteca en lenguaje C con las

funciones necesarias para poder realizar la

lectura de este con lo que se elimina la

necesidad de utilizar electrónica asociada al

acondicionamiento de señal para estas

medidas.

Figura 2.

Como elementos finales, se ha implementado una bombilla como el elemento regulador

de temperatura que aportará la energía calorífica, pues es el sistema utilizado por

ejemplo, en mucho terrarios. No obstante esta simulará el funcionamiento de un

posible calefactor en otros casos.

Para el control de la conmutación de la bombilla se ha utilizado un Triac y un

OptoTriac con detector de paso por cero, este último como elemento de

seguridad, con el fin de aislar la parte de continua de la de alterna.

Para regular la humedad se estuvieron barajando varias opciones, dadas por los

diferentes tipos de sistemas de aspersión de suministro de nieblas de humedad

que se pueden encontrar en los invernaderos, para finalmente y tras la consulta a mi

tutor, se ha optado simplemente por montar un led indicador de funcionamiento en la

alimentación del emplazamiento de la posible bomba de aspersión, ya que no tiene

mucho sentido haber echo un desembolso económico en este sentido ya que el sistema

como inicialmente indicamos es meramente formativo.

Page 9: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 9

Para controlar el flujo de aire caliente y la

humedad en el ambiente se ha hecho uso

de dos ventiladores de tipo PC de 12V. Su

control se ha decidido realizar en PWM

dado que el propio microcontrolador lleva

incluidos dos módulos para este fin. Un

control en analógico en este caso hubiera

implicado utilizar electrónica extra sin

aportar ningún tipo de ventaja tangible.

La frecuencia del PWM ronda los 90KHz, lo

que nos proporcionará un sistema con

suficiente ancho de frecuencia para el

control de la velocidad de ambos

ventiladores.

Figura 3.

Page 10: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 10

DISEÑO DEL ESQUEMÁTICO

Para realizar el diseño electrónico y el enrrutado de la placa se ha utilizado el

software Eagle en su versión educacional, que se distribuye sin coste pero tiene

mermadas algunas de sus capacidades. Así en nuestra placa ha quedado fuera la

colocación del transformador, pues las dimensiones de la placa con la que nos permite

trabajar son menores que la finalmente hemos realizado. No obstante esto no ha

supuesto obstáculo importante.

A continuación se van a explicar cada una de las partes que componen el esquemático

de la placa controladora de adquisición de datos.

Etapa de alimentación

Esta parte del circuito es la encargada de rectificar y adecuar la señal de entrada

de la red de 220VCA a los 12VDC y 5VDC necesarios para el circuito. En ella

comentar que el transformador que conectará a la red de suministro eléctrico, se

le ha colocado un interruptor en el cable que conecta con él, aunque este no aparece

en el esquema.

La potencia del transformador utilizado es de 13VA de potencia máxima de salida.

El puente de diodos realiza la rectificación de la señal alterna de salida del

transformador y los condensadores a la salida de este eliminaran el rizado de la

señal rectificada. Una vez se tiene la tensión estabilizada se introduce en los

estabilizadores de tensión 7812 y 7805 y sus condensadores para eliminación de

ruido asociados con lo que se obtiene una señal limpia para alimentar al circuito.

Figura 4.

Page 11: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 11

Etapa del microcontrolador

A continuación se muestra la parte de la placa destinada al control del sistema, en la

siguiente imagen se puede ver la disposición de las E/S del PIC, cabe destacar que ha

sido utilizado un cristal de 20Mhz a partir del cual, y aprovechando la capacidad del

divisor de frecuencia interno del microcontrolador se puede llegar a generar

los 48MHz necesarios para obtener la velocidad máxima del puerto USB 2.0. El

condensador C3 es utilizado como filtro de baja frecuencia para el transceptor

USB interno del microcontrolador, el cual trabaja a 3.3V. También se ha colocado un

botón de Reset, que reinicializa el funcionamiento del microcontrolador, en caso que

las condiciones de operación lo requieran. Se ha dispuesto una etiqueta con un nombre

descriptivo en cada pin del PIC con la función de expresar el funcionamiento de

este de una manera visual.

Cabe mencionar la labor de los pines RB2 (Datos) y RB3 (Reloj), ya que podría resultar

algo confusa. Estas son las líneas de comunicación del bus serie del sensor SHT75, es

un bus propietario, aunque en funcionamiento similar al I2C. Además destacar el uso

de una resistencia de pull-up tal y como indican las especificaciones, para compensar la

caída de tensión de la señal y que esta pueda ser procesada por el micro sin errores.

Añadir además que la funcionalidad de los pines RC4 y RC5 se corresponde

con las líneas de datos diferenciales del puerto USB.

Figura 5.

Page 12: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 12

Otra parte importante del apartado de la etapa de control es la encargada de

transformar el PWM de salida del microcontrolador de 5VDC a los 12VDC necesarios

para el funcionamiento del ventilador.

Figura 6.

Para ello se ha configurado el transistor como interruptor, de tal forma que

cuando reciba un „1‟ lógico por el terminal de „base‟ entre en saturación y

circule corriente entre colector y emisor haciendo que de esta forma se

alimente el ventilador.

Importante es el uso de los diodos D1, D2 y D3, con ellos se pretende hacer circular la

energía acumulada en la bobina del ventilador o de la bomba de humidificación después

del corte y así evitar que sea destruido el transistor por una corriente inversa.

El transistor BD135 fue seleccionado pensando que debería soportar una

frecuencia de conmutación no superior a 100KHz, y que debería soportar una

corriente entre emisor-colector de al menos un amperio.

El circuito mostrado a continuación es

el encargado de realizar la

conmutación de la carga de alterna, es

decir, la bombilla en nuestro caso o de un

calefactor. Se ha utilizado el diagrama

ofrecido en el datasheet del optotriac

(MOC3041), con la salvedad de que se ha

prescindido de la red Snubber, ya que

la carga iba a ser completamente

Page 13: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 13

resistiva y por lo tanto no acumularía

energía.

Figura 8.

Para concluir con este apartado comentar que el conector USB utilizado en la

placa, lleva el pin de alimentación de 5VDC sin conectar a pista alguna, ya que la

alimentación de energía de la placa es propia de la misma y no se utiliza la que

suministra el propio bus. El conector correspondiente al sensor SHT75 conectan con

un cable en cuyo extremo se ubica el sensor, así se dispone de un cierto radio de

trabajo para ubicar el sensor en la posición que nos interese.

El led bicolor utilizado distingue entre dos estados del sistema, por un lado

tenemos que cuando esté Verde, la comunicación con el PC será correcta, mostrándose

de color Rojo para el caso contrario.

Page 14: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 14

DISEÑO DE LA PCB

Para obtener la placa física, en primer lugar se realizó el esquemático completo

mediante el editor de esquemáticos de EAGLE, para posteriormente realizar el ruteo

de la placa en el editor de placas del mismo programa y ayudado mediante la aplicación

de ruteo automático de la misma, realizando esta una gran ayuda para el

posicionamiento de los componentes. Comentar como ya se indico, el programa se

utiliza en versión educativa, por lo que sus opciones están reducidas, así queda fuera

de la placa la ubicación del transformador, puesto que las dimensiones de la tarjeta

que maneja son pequeñas.

Figura 9.

Page 15: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 15

Programación del microcontrolador

Para establecer la comunicación entre la tarjeta de adquisición y el PC, donde serán

procesados los datos y realizados los controladores se ha utilizado el PIC

18F2550 y en especial su particularidad de la comunicación vía USB. La programación

de este micro se ha realizado en C con el compilador de CCS, el código

fuente se adjunta en el ANEXO I; además este código, las bibliotecas para

USB y el del Sensor SHT75 también están incluidas.

Page 16: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 16

APLICACIÓN DEL PC

Diseño de la aplicación

Como se ha indicado la tarjeta se conecta a través del puerto USB al PC, para que

este realice las labores de control y supervisión del sistema, permitiéndole al usuario

la visualización de las variables de proceso así como la capacidad de interactuar con el

sistema (arrancando o

parando elementos) y modificando los diferentes parámetros de los controladores.

Figura 10.

La interfaz de la aplicación se ha escrito en Visual C# y como entorno de

desarrollo se ha utilizado la suite Visual Studio 2010 Express, que es la versión de

libre distribución del programa, la cual nos la hemos descargado directamente de la

página de Microsoft.

En un primer vistazo de la interfaz, se distinguen 4 zonas delimitadas y que

Page 17: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 17

corresponden:

*Control Calefactor: Reúne

esta zona los mandos de

accionamiento de la bombilla

calefactora y su dispositivo de

control.

*Control Humidificador: Reúne

esta zona los mandos de

accionamiento de la bomba de

agua de los difusores y su

dispositivo de control.

Figura 11.

*Control de Temperatura:

Reúne esta zona el display de

visualización de la

temperatura y su control con

los diferentes parámetros del

mismo que pueden ser

modificados.

*Control de Humedad: Reúne

esta zona el display de

visualización de la humedad y

su control con sus diferentes

parámetros.

Figura 12.

Básicamente las zonas de Control Calefactor y Control humidificador se han diseñado

de forma similar, al igual que las otras dos restantes Control de Temperatura y

Control de Humedad.

Page 18: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 18

Funcionamiento del sistema

En este apartado se hará una descripción del funcionamiento del sistema, así como una

descripción de los elementos de la interface.

Para echar a andar nuestro sistema comenzaremos por conectar la tarjeta a

suministro eléctrico, En este momento la tarjeta encenderá el led con color rojo

indicativo de que tiene energía pero no tiene canal de comunicación con el PC. Para

establecer esta, conectaremos el cable USB de la tarjeta en un puerto del PC, en ese

momento se producirá la enumeración, consistente en que el Host del PC le pregunta a

la tarjeta cuales son sus parámetros para identificarlo (VendorID y ProductID), así

como para asignarle una dirección al dispositivo para permitir la transferencia de

datos. Una vez realizado esto y si todo ha ido bien, el microcontrolador apagará el led

en rojo y encenderá el led en verde.

Ahora arrancamos nuestra aplicación y la interfaz gráfica se mostrará. Si pulsamos el

botón de Conectar Dispositivo el programa buscará un descriptor de dispositivo que

coincida con los valores que tiene prefijados de VendorID y ProductID y si los

encuentra activará el sistema de notificaciones y la transferencia de datos

comenzará.

Una vez el sistema se ha puesto en marcha, las indicaciones de la temperatura como

de la humedad empiezan a ser visualizadas y los distintos elementos se muestran en

reposo con sus controles en la posición de manual pudiéndose desde ese instante el

usuario interaccionar con el sistema.

Funciones de comunicación

Para dotar a nuestra aplicación de la comunicación mediante el puerto USB con la

tarjeta, hemos tenido que definir la clase de comunicación que se implantará y que en

nuestro caso será mediante protocolo HID (Human Interfase Devies). La clase nos

definen las funciones de comunicación que utilizan el conjunto de dispositivos USB y

que proveen al Host (PC) de las mismas.

Por ello, se ha agregado la clase easyHID.cs al proyecto de nuestra aplicación (Visual

C#) y a través de ella podemos llamar a las diferentes funciones de control que se

encuentran en mcHID.dll, una librería proporcionada por la empresa MecaniqueUK

para el control de dispositivos USB mediante protocolo HID.

- mcHID.dll (Librería de control). - easyHID.cs (Clase con las funciones de control definidas).

Page 19: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 19

Más abajo tenemos las llamadas a las diferentes funciones incluidas en la librería y

entre ellas podemos destacar las siguientes:

[DllImport("mcHID.dll")] public static extern bool Connect(IntPtr pHostWin);

Conecta la aplicación al controlador.

[DllImport("mcHID.dll")] public static extern bool Disconnect();

Desconecta la aplicación al controlador. [DllImport("mcHID.dll")]

public static extern bool Read(UInt32 pHandle, IntPtr pData);

Lee el reporte de entrada para ver si hay datos provenientes del dispositivo. El tama-

ño del reporte dependerá de la constante BUFFER_IN_SIZE. La función retorna 1 si

hay datos disponibles para leer y 0 si no los hay.

[DllImport("mcHID.dll")]

private static extern bool Write(UInt32 pHandle, IntPtr pData);

Escribimos un reporte de salida con los datos almacenados en la variable pData, que es

un puntero a un buffer no administrado. El tamaño del reporte dependerá de la varia-

ble BUFFER_OUT_SIZE. La función retorna 1 si se ha podido enviar el reporte y 0 en

el caso contrario.

[DllImport("mcHID.dll")]

public static extern UInt32 GetVendorID(UInt32 pHandle); [DllImport("mcHID.dll")] public static extern UInt32 GetProductID(UInt32 pHandle);

A través de estas funciones obtenemos el vendorID y el productID del dispositivo.

[DllImport("mcHID.dll")] public static extern void SetReadNotify(UInt32 pHandle, bool pValue); Activamos el servicio de notificaciones para recibir mensajes cada vez que se produce

un evento de lectura. El servicio se activa una vez que el dispositivo ya se ha conecta-

do al controlador.

[DllImport("mcHID.dll")] public static extern bool IsAvailable(UInt32 pVendorId, UInt32 pProductId);

A través de esta función obtenemos el estado de conexión del dispositivo

mediante el vendorID y el productID.

Page 20: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 20

Con esto ya hemos explicado todas las funciones que se usarán en el programa. Ahora

veremos el desarrollo de 2 de ellas: Write y Read, correspondientes a las funciones

para leer y escribir datos. public static bool Read(UInt32 pHandle, out byte[] pData) { IntPtr unmanagedBuffer = Marshal.AllocHGlobal(BUFFER_IN_SIZE); bool result = Read(pHandle, unmanagedBuffer); try { pData = new byte[BUFFER_IN_SIZE]; Marshal.Copy(unmanagedBuffer, pData, 0, BUFFER_IN_SIZE); } finally { Marshal.FreeHGlobal(unmanagedBuffer); } return result; }

Esta función lee el reporte de entrada para ver si hay datos disponibles. En primera

instancia asigna memoria con un tamaño igual a BUFFER_IN_SIZE a un puntero: IntPtr unmanagedBuffer = Marshal.AllocHGlobal(BUFFER_IN_SIZE);

Se utiliza el método Marshal, para poder trabajar con memoria no administrada.

Luego guarda el retorno de la función Read en la variable result, que corresponde a la

presencia de datos en el reporte de entrada. bool result = Read(pHandle, unmanagedBuffer);

A través del método try, crea un buffer llamado pData. Como es una porción de me-

moria no administrada, usa Marshal nuevamente y copia los datos usando el puntero

creado con anterioridad en el buffer pData, quedando los datos del reporte guardados

en este último. try { pData = new byte[BUFFER_IN_SIZE]; Marshal.Copy(unmanagedBuffer, pData, 0, BUF-FER_IN_SIZE);

Como el espacio de memoria que al que hacía alusión el puntero no se utiliza más y es

memoria no administrada, usamos Marshal para liberarla para otros procesos.

finally { Marshal.FreeHGlobal(unmanagedBuffer); }

Finalmente la función retorna con el valor que haya tomado result. return result;

Esta función escribe un dato en el reporte de salida. public static bool Write(UInt32 pHandle, byte[] pData)

Page 21: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 21

{ IntPtr unmanagedBuffer = Marshal.AllocHGlobal(BUFFER_OUT_SIZE); bool result; try { Marshal.Copy(pData, 0, unmanagedBuffer, BUFFER_OUT_SIZE); result = Write(pHandle, unmanagedBuffer); } finally { Marshal.FreeHGlobal(unmanagedBuffer); } return result; }

En primer instancia es igual que la función anterior, salvo que la variable result se le

asigna un valor luego de copiar los datos en el reporte de salida; para poder indicar si

los datos se han escrito correctamente.

Ahora que ya tenemos la clase easyHID.cs explicada, comenzamos con el núcleo prin-

cipal del programa.

Para saber si el dispositivo estaba conectado/desconectado o enviando datos, nece-

sitábamos leer los diferentes mensajes que entregaba el controlador. Por lo que nece-

sitamos una función que tome los mensajes de Windows, los procese y según el valor

que tomen realizar diferentes acciones. Por ello crearemos 3 funciones:

- Dispositivo _ conectado (En caso que el dispositivo esté conectado al host)

- Dispositivo _ desconectado (En caso de que desconectemos el dispositivo)

- Lee _ dispositivo (Si se recibe el mensaje de que hay datos disponibles)

El parámetro de cada una de las 3 funciones se da según el mensaje que se recibe por

parte del controlador, con lo cual la función queda de la siguiente manera. protected override void WndProc(ref Message message) { // Interceptamos los mensajes de windows. if (message.Msg == EasyHID.WM_HID_EVENT) // Si ha ocurrido algún evento... { switch (message.WParam.ToInt32()) // Intercepta el mensaje y opera según el valor recibido.... { case EasyHID.NOTIFY_PLUGGED: Dispositivo_Conectado((UInt32)message.LParam.ToInt32()); // Se ha conectado un dispositivo. break; case EasyHID.NOTIFY_UNPLUGGED: Dispositivo_desconectado((UInt32)message.LParam.ToInt32()); // Se ha desconectado un dispositivo. break; case EasyHID.NOTIFY_READ: Lee_datos((UInt32)message.LParam.ToInt32()); // Hay datos en el buf-fer de entrada. break; } } base.WndProc(ref message);

Page 22: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 22

}

Ahora tenemos que crear las 3 funciones dentro de la clase principal: private void Dispositivo_Conectado(UInt32 handle){} private void Dispositivo_desconectado(UInt32 handle) {} private void Lee_datos(UInt32 In_handle) {}

Con esto, cada vez que se produzca una notificación podremos realizar diferentes ac-

ciones en consecuencia.

Para conectar la aplicación al controlador y a su vez el dispositivo a dicho controlador,

utilizamos la función: EasyHID.Connect(Handle);

Y para poder ver si realmente estamos conectados con el entrenador USB hacemos

uso de la función: if (EasyHID.IsAvailable(EasyHID.VENDOR_ID, EasyHID.PRODUCT_ID) == true)

Con esto podemos detectar cualquier dispositivo conectado que coincida con el VID,

PID declarado en la aplicación.

Page 23: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 23

DISEÑO DE LOS CONTROLES

Como se ha comentado anteriormente , los controles denominados como Control

Calefactor y Control Humidificador se han diseñado de forma similar, al igual que las

otras dos restantes Control de Temperatura y Control de Humedad. Esto se debe a la

similitud de la naturaleza de las variables que se van a controlar.

Control Calefactor y de Humidificador

Atendiendo a que nuestro proyecto desarrollaría una solución para un sistema real, se

han diseñado estos controles suponiendo que los posibles sistemas a controlar fuesen

un calefactor en el caso de la temperatura y de una bomba que suministrara agua a

unos difusores en el caso del humificador. En ambos casos dichos sistemas se encon-

trarían accionados mediante su correspondiente relé, los cuales serían accionados por

las salidas RB0 y RB1 del microprocesador. Dicho lo cual, la idea con que se han defini-

do ambos controles ha sido la de regular la potencia entregada por los comentados

relés, mediante la regulación del ancho de pulso en que se encuentra activado los re-

les. Para ello se fija un tiempo definido como ciclo de trabajo que será el tiempo en el

que se encuentre activo los relés del total del tiempo definido como periodo. Ambos

tiempo son definidos por el usuario.

Figura 13.

Control temperatura y control humedad

Para estos controles la solución propuesta ha sido la de diseñar unos PID ya que se

aplican de manera general en la mayoría de los controles actuales y suponen la solucion

más ventajosa frente a tro tipo de controles.

Page 24: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 24

Los controles PID responden a la siguiente ecuación:

Donde e(t) es el error de la señal y u(t) es la entrada de control del proceso. Kp es la

ganancia proporcional, Ti es la constante de tiempo integral y Td es la constante de

tiempo derivativa.

En el dominio s, el controlador PID se puede escribir como:

El controlador PID tiene tres parámetros (Kp, Ti, Td ) los cuales interactúan unos con

otros y su ajuste suele presentar inconvenientes. Por lo que nos podemos ayudar de las

reglas de Ziegler/Nichols que nos proponen unos valores para los parámetros del con-

trol PID basado en un análisis del sistema a lazo abierto, ya que no contienen integra-

dores ni polos complejos. Siendo su respuesta a una entrada escalon similar a la de la

mostrada en la figura.

Page 25: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 25

Donde los coeficientes:

Según Zieggler/Nichols, nos definen los parámetros del controlador de la manera:

La realización de un controlador PID discreto viene dado por la transformada z:

Donde podemos sustituir por:

Page 26: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 26

Donde:

Existen distintas posibilidades para la realización práctica de un controlador PID. Una

de las más habituales es la realización en paralelo.

Se debe tener en cuenta que el tiempo de muestreo del sistema debe ser mucho me-

nor al tiempo de establecimiento del sistema en lazo abierto. En el modelo de Zie-

gler/Nichols se toma un valor de T< τ0/4 o también puede utilizarse T< γ0/10.

Un problema asociado a este tipo de controlador es el llamado “integral windup” el cual

puede provocar largos periodos de sobreimpulsos, motivados por los valores excesivos

que alcanza la señal de control debido a la acumulación en el integrador. Para evitar

este problema hemos limitado la señal de control entre un valor máximo y un valor

mínimo, impidiendo que el integrador actúe cuando se superan esos límites.

Page 27: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 27

PRESUPUESTO

Para realizar una estimación del coste económico del proyecto, se ha dividido los gas-

tos del mismo asociándolos a varios grupos diferentes:

Recursos Humanos: Mano de obra necesaria para la realización del proyecto.

Componentes y fabricación: Coste de los componentes y fabricación del circui-

to.

No se han contabilizado recursos hardware necesarios para la realización del proyec-

to, tales como soldador, multímetro, ordenador, ya que se trata de un proyecto uni-

versitario y son recursos a los que se tiene acceso libremente sin coste alguno para

cualquier estudiante de la universidad de Sevilla.

Tampoco se han tenido en cuenta posibles gastos de software, ya que todo el diseño

se ha realizado bajo software de libre distribución.

Recursos Humanos

Los recursos humanos del proyecto corren a cargo del proyectista, al que se le apli-

cará un sueldo de Ingeniero Junior hipotético de 1500€/mes, teniendo en cuenta que

en un mes se contabilizan unas 165 horas hábiles, se obtiene un salario de 9,09€/hora.

Las tareas realizadas por el ingeniero son el análisis de requisitos, diseño, implemen-

tación montaje y teste o de la placa de prueba del PCB. Resumiendo y concretando

horas:

Tarea Horas Coste

Análisis de requisitos 25 227,25

Diseño 70 636,3

Implementación 135 1227,15

Experimentación 50 454,5

TOTAL 280 2545,2€

Coste de los componentes y fabricación del PCB

Podemos realizar un presupuesto del proyecto detallando los componentes utilizados:

Cantidad Elemento Precio IMPORTE

Page 28: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 28

Unitario

1 SHT75 32,25 32,25

1 Transformador 12,3 12,3

1 PIC 18F2550 5,01 5,01

1 Puente diodo 0,7 0,7

1 Cristal 20MHz 0,27 0,27

1 Conector Hembra USB pla-

ca

0,6 0,6

1 Pulsador 0,41 0,41

1 LED Rojo/Verde 0,18 0,18

1 Zócalo 0,75 0,75

3 Transistor BD437 0,18 0,54

1 Triac BT136 0,68 0,68

1 MOC3041M 1,05 1,05

3 Diodo 1N4446 0,08 0,24

7 Bornas 0,45 3,15

1 Regulador 7805 0,57 0,57

1 Regulador 7812 0,65 0,65

2 Condensador 22pF 0,09 0,18

2 Condensador 100nF 0,12 0,24

1 Condensador electrolítico

47uF

0,25 0,25

2 Condensador electrolítico

470uF

0,4 0,8

2 Condensador electrolítico

4700uF

1,05 2,1

1 Resistencia 330 0,2 0,2

1 Resistencia 360 0,2 0,2

1 Resistencia 180 0,2 0,2

3 Resistencia 2K2 0,04 0,12

2 Resistencia 10K 0,08 0,16

1 Resistencia 1K 0,08 0,08

1 Placa virgen 11,8 11,8

-------- TOTAL ------ 75,68€

Page 29: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 29

Coste Total

Reuniendo los costea anteriores y añadiendo el IVA correspondiente del 21%

CONCEPTO COSTE

Componentes y Fabricación

Circuito

75,68€

Recursos Humanos 2545,2€

TOTAL 2620,88€

IVA 21% 550,38€

TOTAL 3171,26€

Page 30: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 30

CONCLUSION

El proyecto aquí presentado ha pretendido realizar un control de bajo coste para un

problema de control de temperatura y humedad. Para la ejecución del mismo, ha su-

puesto la unión de varias facetas como son el diseño del hardware con el software de

programación de nuestro PIC y la programación de una aplicación informática para la

visualización de las variables e interacción con el usuario final.

En cuanto a las posibles mejoras a realizar en el futuro, se contempla el registro de

los valores de las variables que permitieran el estudio posterior de la evolución de los

proceso, lo cual permitiría mejorar los procedimientos de sintonización de los contro-

les, como la implementación de otros sensores para que la lectura de las variables no

correspondiera de forma concreta a un punto, sino a la media de varios puntos, lo cual

supondría una lectura media de la temperatura de la habitación.

Otra mejora a considerar en el futuro sería trasladar las tareas de control desde la

aplicación informática a la tarjeta de control. Esta deslocalización del algoritmo impli-

caría una mayor fiabilidad del sistema, puesto que una pérdida de comunicación entre

ambas partes no implicaría la paralización de las tareas de control.

Page 31: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 31

BIBLIOGRAFIA

José María Angulo Usategui, Susana romero Yesa, Ignacio Angulo Martínez. Mi-crocontroladores PIC. Diseño práctico de aplicaciones. Mc Graw Hill, 2º Edición,

2006.

Páginas web de fabricantes de Microcontroladores

www.analog.com

www.atmel.com

www.microchip.com

www.intel.com

www.national.com

Tutoriales: Introducción a la Programación del PIC.

Entorno de desarrollo MPLAB www.microchip.com

Características del compilador de C CCS. www.ccsinfo.com

USB Implementers Forum, Inc. http://www.usb.org

Datasheet del microcontrolador PIC18F2550 disponible en www.microchip.com

Jan Axelson. USB Complete. Lakeview Research, 1º Edición 1999

Eduardo García Breijo, Compilador C CCS y simulador Proteus para microcontro-ladores PIC. Marcombo, Ediciones Técnicas, 1º Edición 2008.

Características de Microsoft Visual Basic, Visual C++ y Visual C#. Disponible en

Internet. http://www.microsoft.com

PIC18F2550 y USB.Desarrollo de aplicaciones. Moyano Jonathan.

Fco. Javier Ceballos. Visual C#. 3ª Edición. Ed. RAMA

Page 32: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 32

ANEXO 1:Programas del microcontrolador APLICACION_HID.c /******************************************************************** Programa para medición y control de temperaturas y humedad. Universidad de Sevilla 2013. *********************************************************************/ //========================================================================= #include <18F2550.h> // Definición de registros internos del PIC18F2550. #include "shtxx.h" //Registros del sensor. #include <stdlib.h> #fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,NOPBADEN // HSPLL: Utilizaremos un cristal de alta velocidad en conjunto con el PLL. // NOWDT: No vamos a usar el perro guardian. // NOPROTECT: Memoria no protejida contra lecturas. // NOLVP: No utilizamos el modo de programación con bajo voltaje. // NODEBUG: No utilizamos código para debugear. // USBDIV: signfica que el clock del usb se tomará del PLL/2 = 96Mhz/2 = 48Mhz. // PLL1: significa que el PLL prescaler dividirá la frecuencia del cristal. // para HS = 20Mhz, PLL = 5. con esto se obtiene: 20Mhz/5 = 4Mhz. // CPUDIV1: El PLL postscaler decide la división en 2 de la frecuencia de // salida del PLL de 96MHZ, si queremos 48MHZ, lo dejamos como está. // VREGEN: habilita el regulador de 3.3 volts que usa el módulo USB. // NOPBADEN: Todo el Puerto B como I/O digitales. // Usamos una frecuencia de trabajo de 48Mhz. #use delay(clock=48000000) // Incluimos librerías utilizadas por la aplicación. #include <pic18_usb.h> // Drivers's USB del PIC18F2550. #include <APLICACION_HID.h> // Definición de funciones y hardware utilizado en el programa. #include <Descriptor_easyHID.h> // Descriptores HID del proyecto. #include <USB.c> // Funciones del USB. // Usamos fast_io, en los puertos B y C. #use fast_io(b) #use fast_io(c) void USB_debug(){ LED_ON(LED_RED); // Enciende el led error y apaga el led USB_OK. LED_OFF(LED_GREEN); usb_wait_for_enumeration(); // Espera a ser enumerado por el host. LED_ON(LED_GREEN); // Enciende el led USB_OK y apaga el led USB_ERROR. LED_OFF(LED_RED); } float temperatura, humedad;

Page 33: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 33

void main(void) // Función Princi-pal. { // Variables globales. int8 recibe[USB_EP1_RX_SIZE]; // Declaramos la variable recibe de 32 bytes. int8 envia[USB_EP1_TX_SIZE]; // Declaramos la variable envía de 32 bytes. int8 valorPWM1=0; // Variable que contiene el valor del PWM1. int8 valorPWM2=0; // Variable que contiene el valor del PWM2. char ctemp[6], chumed[6]; shtxx_init(); set_tris_b(0b11111100); // RB0, RB1 salidas, el resto entradas. output_b(0x01); // Inicializamos las salidas a 0, excepto RB0. set_tris_c(0b00111000); setup_ccp1(CCP_PWM); setup_ccp2(CCP_PWM); setup_timer_2(T2_DIV_BY_1, 255, 1); set_pwm1_duty(0); // Ventilador 1 Apagado set_pwm2_duty(0); // Ventilador 2 Apagado usb_init(); // Inicializamos el stack USB. usb_task(); // Habilita el periferico usb y las interrupciones. USB_debug(); // Nos muestra el estado de conección del USB. while (TRUE) // Bucle infinito. { if(usb_enumerated()) // Si el dispositivo está configurado... { //Leemos sensor sht75 read_shtxx(temperatura, humedad); // Pasamos de valores numérico a caracteres sprintf(ctemp,"%2.2f", temperatura); envia[0]=0x00; envia[1]=ctemp[0]; envia[2]=ctemp[1]; envia[3]=ctemp[2]; envia[4]=ctemp[3]; envia[5]=ctemp[4]; envia[6]=ctemp[5]; sprintf(chumed,"%2.2f", humedad); envia[7]=chumed[0]; envia[8]=chumed[1]; envia[9]=chumed[2]; envia[10]=chumed[3]; envia[11]=chumed[4]; envia[12]=chumed[5]; usb_put_packet(1, envia, USB_CONFIG_HID_TX_SIZE, USB_DTS_TOGGLE); // Enviamos el pa-quete de datos por USB.

Page 34: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 34

if (usb_kbhit(1)) // Si hay un paquete de datos del host.. en el buffer lo tomamos y guardamos en la variable data. { usb_get_packet(1, recibe, USB_CONFIG_HID_RX_SIZE); // En el buffer lo tomamos del EP1 y lo guardamos en la variable recibe.... if(recibe[0]==ACTIVA_SALIDAS){ // Si recibe comando de control de salidas... switch(recibe[1]){ // Según el dato que recibe, activa o desactiva los led's. case LED_1: output_toggle(PIN_B0); // Cambia de estado el LED1. break; case LED_2: output_toggle(PIN_B1); // Cambia de estado el LED2. break; } } if(recibe[0]==PWM_CONTROL1) // Si recibimos el comando de control PWM1.. {valorPWM1=recibe[2]; set_pwm1_duty(valorPWM1); } // Tomamos el dato y lo procesamos. if(recibe[0]==PWM_CONTROL2) // Si recibimos el comando de control PWM2.. {valorPWM2=recibe[3]; set_pwm2_duty(valorPWM2); } // Tomamos el dato y lo procesamos. } } } }

Page 35: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 35

APLICACION_HID.h

// Definición de constantes y funciones: #define LED_GREEN PIN_C6 // Led USB_OK...( Dispositivo conectado al host ). #define LED_RED PIN_C7 // Led USB_ERROR... ( Dispositivo no detectado ). #define PWM1 PIN_C2 // Control PWM1. #define PWM2 PIN_C1 // Control PWM2. // Constantes varias: #define USB_CONFIG_HID_TX_SIZE 32 // Definimos el tamaño del endpoint de salida. #define USB_CONFIG_HID_RX_SIZE 32 // Definimos el tamaño del endpoint de entrada. // Comandos de entrada. #define ACTIVA_SALIDAS 0x0A // Comando para activar LED'S. #define PWM_CONTROL1 0x0B // Comando para activar PWM1. #define PWM_CONTROL2 0x0C // Comando para activar PWM2. #define LED_1 0x10 // Cambia de estado el LED 1. #define LED_2 0x20 // Cambia de estado el LED 2. // Función para prender y apagar led's. #define LED_ON output_high // Función para encender el LED. #define LED_OFF output_low // Función para apagar el LED. void USB_debug();

Page 36: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 36

shtxx.h

/////////////////////////////////////////////////////////////////////////////// // // // Driver file for SHTxx Temperature & Humidity Sensor // // // // ***** To initialise SHTxx sensor upon power up ***** // // // // Function : sht_init() // // Return : none // // // // // // ***** To measure and caluculate SHTxx temp & humid ***** // // // // Function : read_shtxx (temp, humid) // // Return : temperature & humidity in float values // // // /////////////////////////////////////////////////////////////////////////////// #define shtxx_data PIN_B2 #define shtxx_clk PIN_B3 #use delay(clock=48000000) //***** Function to alert SHTxx ***** void shtxx_transstart(void) { output_float(shtxx_data); //data high output_low(shtxx_clk); //clk low delay_us(1); output_high(shtxx_clk); //clk high delay_us(1); output_low(shtxx_data); //data low delay_us(1); output_low(shtxx_clk); //clk low delay_us(2); output_high(shtxx_clk); //clk high delay_us(1); output_float(shtxx_data); //data high delay_us(1); output_low(shtxx_clk); //clk low } //***** Function to write data to SHTxx ***** int1 shtxx_write_byte(int8 iobyte) { int8 i, mask = 0x80; int1 ack; //Shift out command delay_us(4); for(i=0; i<8; i++) { output_low(shtxx_clk); //clk low if((iobyte & mask) > 0) output_float(shtxx_data); //data high if MSB high else output_low(shtxx_data); //data low if MSB low delay_us(1);

Page 37: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 37

output_high(shtxx_clk); //clk high delay_us(1); mask = mask >> 1; //shift to next bit } //Shift in ack output_low(shtxx_clk); //clk low delay_us(1); ack = input(shtxx_data); //get ack bit output_high(shtxx_clk); //clk high delay_us(1); output_low(shtxx_clk); //clk low return(ack); } //***** Function to read data from SHTxx ***** int16 shtxx_read_byte(void) { int8 i; int16 iobyte = 0; const int16 mask0 = 0x0000; const int16 mask1 = 0x0001; //shift in MSB data for(i=0; i<8; i++) { iobyte = iobyte << 1; output_high(shtxx_clk); //clk high delay_us(1); if(input(shtxx_data)) iobyte |= mask1; //shift in data bit else iobyte |= mask0; output_low(shtxx_clk); //clk low delay_us(1); } //send ack 0 bit output_low(shtxx_data); //data low delay_us(1); output_high(shtxx_clk); //clk high delay_us(2); output_low(shtxx_clk); //clk low delay_us(1); output_float(shtxx_data); //data high //shift in LSB data for(i=0; i<8; i++) { iobyte = iobyte << 1; output_high(shtxx_clk); //clk high delay_us(1); if(input(shtxx_data)) iobyte |= mask1; //shift in data bit else iobyte |= mask0; output_low(shtxx_clk); //clk low delay_us(1); } //send ack 1 bit output_float(shtxx_data); //data high delay_us(1);

Page 38: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 38

output_high(shtxx_clk); //clk high delay_us(2); output_low(shtxx_clk); //clk low return(iobyte); } //***** Function to wait for SHTxx reading ***** void shtxx_wait(void) { int16 shtxx_delay; output_float(shtxx_data); //data high output_low(shtxx_clk); //clk low delay_us(1); for(shtxx_delay=0; shtxx_delay<30000; shtxx_delay++) // wait for max 300ms { if (!input(shtxx_data)) break; //if shtxx_data low, SHTxx ready delay_us(10); } } //***** Function to reset SHTxx communication ***** void shtxx_reset(void) { int8 i; output_float(shtxx_data); //data high output_low(shtxx_clk); //clk low delay_us(2); for(i=0; i<9; i++) { output_high(shtxx_clk); //toggle clk 9 times delay_us(2); output_low(shtxx_clk); delay_us(2); } shtxx_transstart(); } //***** Function to soft reset SHTxx ***** void shtxx_softreset(void) { shtxx_reset(); //SHTxx communication reset shtxx_write_byte(0x1e); //send SHTxx reset command delay_ms(15); //pause 15 ms } //***** Function to measure SHTxx temperature ***** int16 shtxx_measuretemp(void) { int1 ack; int16 iobyte;

Page 39: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 39

shtxx_transstart(); //alert SHTxx ack = shtxx_write_byte(0x03); //send measure temp command and read ack status if(ack == 1) return; shtxx_wait(); //wait for SHTxx measurement to complete iobyte = shtxx_read_byte(); //read SHTxx temp data return(iobyte); } //***** Function to measure SHTxx RH ***** int16 shtxx_measurehumid(void) { int1 ack; int16 iobyte; shtxx_transstart(); //alert SHTxx ack = shtxx_write_byte(0x05); //send measure RH command and read ack status if(ack == 1) return; shtxx_wait(); //wait for SHTxx measurement to complete iobyte = shtxx_read_byte(); //read SHTxx temp data return(iobyte); } //***** Function to calculate SHTxx temp & RH ***** void shtxx_calc(int16 temp, int16 humid, float &tc, float &rhlin, float &rhtrue) { float rh; //calculate temperature reading tc = ((float) temp * 0.01) - 40.0; //calculate Real RH reading rh = (float) humid; rhlin = (rh * 0.0405) - (rh * rh * 0.0000028) - 4.0; //calculate True RH reading rhtrue = ((tc - 25.0) * (0.01 + (0.00008 * rh))) + rhlin; } //***** Function to measure & calculate SHTxx temp & RH ***** void read_shtxx(float &temp, float &truehumid) { int16 restemp, reshumid; float realhumid; restemp = shtxx_measuretemp(); //measure temp reshumid = shtxx_measurehumid(); //measure RH shtxx_calc(restemp, reshumid, temp, realhumid, truehumid); //calculate temp & RH } //***** Function to initialise SHTxx on power-up ***** void shtxx_init(void)

Page 40: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 40

{ shtxx_reset(); //reset SHTxx delay_ms(20); //delay for power-up }

Page 41: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 41

Descriptor_easyHID.h

/////////////////////////////////////////////////////////////////////////// /// Descriptor_easyHID.h /// /// Escrito para funcionar con easyHID.dll /// /////////////////////////////////////////////////////////////////////////// #IFNDEF __USB_DESCRIPTORS__ #DEFINE __USB_DESCRIPTORS__ #ifndef USB_CONFIG_PID #define USB_CONFIG_PID 0x07D0 // PID easyHID, configurado por el usuario. #endif #ifndef USB_CONFIG_VID #define USB_CONFIG_VID 0x1781 // VID easyHID, configurado por el usuario. #endif #ifndef USB_CONFIG_BUS_POWER // El rango válido es 0...500. #define USB_CONFIG_BUS_POWER 100 // 100mA, corriente máxima que entregará el puerto. #endif #ifndef USB_CONFIG_VERSION // El número de versión está guardado en el descriptor, en formato bcd. // El rango válido es 00.00 to 99.99 #define USB_CONFIG_VERSION 0x0100 //01.00 #endif #ifndef USB_CONFIG_HID_TX_SIZE // El rango válido es 0-255 #define USB_CONFIG_HID_TX_SIZE 32 // Configurado por el usuario según aplicación. #endif #ifndef USB_CONFIG_HID_RX_SIZE // El rango válido es 0-255 #define USB_CONFIG_HID_RX_SIZE 32 // Configurado por el usuario según aplicación. #endif #ifndef USB_CONFIG_HID_TX_POLL // for full speed devices, valid range is 1-255 // for slow speed devices, valid range is 10-255 #define USB_CONFIG_HID_TX_POLL 10 #endif #ifndef USB_CONFIG_HID_RX_POLL // for full speed devices, valid range is 1-255 // for slow speed devices, valid range is 10-255 #define USB_CONFIG_HID_RX_POLL 10 #endif //Tells the CCS PIC USB firmware to include HID handling code. #ifdef USB_HID_DEVICE #undef USB_HID_DEVICE #endif #DEFINE USB_HID_DEVICE TRUE //the following defines needed for the CCS USB PIC driver to enable the TX endpoint 1 // and allocate buffer space on the peripheral

Page 42: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 42

#ifdef USB_EP1_TX_ENABLE #undef USB_EP1_TX_ENABLE #endif #define USB_EP1_TX_ENABLE USB_ENABLE_INTERRUPT //turn on EP1 for IN bulk/interrupt trans-fers #ifndef USB_EP1_TX_SIZE #if (USB_CONFIG_HID_TX_SIZE >= 64) // interrupt endpoint max packet size is 64. #define USB_EP1_TX_SIZE 64 #else // by making EP packet size larger than message size, we can send message in one packet. #define USB_EP1_TX_SIZE (USB_CONFIG_HID_TX_SIZE+1) #endif #endif #ifdef USB_EP1_RX_ENABLE #undef USB_EP1_RX_ENABLE #endif #define USB_EP1_RX_ENABLE USB_ENABLE_INTERRUPT //turn on EP1 for OUT bulk/interrupt transfers #ifndef USB_EP1_RX_SIZE #if (USB_CONFIG_HID_RX_SIZE >= 64) // interrupt endpoint max packet size is 64. #define USB_EP1_RX_SIZE 64 #else // by making EP packet size larger than message size, we can send message in one packet. #define USB_EP1_RX_SIZE (USB_CONFIG_HID_RX_SIZE+1) #endif #endif #include <usb.h> ////////////////////////////////////////////////////////////////// /// /// HID Report. Tells HID driver how to handle and deal with /// received data. HID Reports can be extremely complex, /// see HID specifcation for help on writing your own. /// ////////////////////////////////////////////////////////////////// const char USB_CLASS_SPECIFIC_DESC[] = { 6, 0, 255, // Usage Page = Vendor Defined 9, 1, // Usage = IO device 0xa1, 1, // Collection = Application 0x19, 1, // Usage minimum 0x29, 8, // Usage maximum 0x15, 0x80, // Logical minimum (-128) 0x25, 0x7F, // Logical maximum (127) 0x75, 8, // Report size = 8 (bits) 0x95, USB_CONFIG_HID_TX_SIZE, // Report count 32 bytes 0x81, 2, // Input (Data, Var, Abs) 0x19, 1, // Usage minimum 0x29, 8, // Usage maximum 0x75, 8, // Report size = 8 (bits) 0x95, USB_CONFIG_HID_RX_SIZE, // Report count 32 bytes 0x91, 2, // Output (Data, Var, Abs)

Page 43: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 43

0xc0 // End Collection }; //if a class has an extra descriptor not part of the config descriptor, // this lookup table defines where to look for it in the const // USB_CLASS_SPECIFIC_DESC[] array. //first element is the config number (if your device has more than one config) //second element is which interface number //set element to 0xFFFF if this config/interface combo doesn't exist const int16 USB_CLASS_SPECIFIC_DESC_LOOKUP[USB_NUM_CONFIGURATIONS][1] = { //config 1 //interface 0 0 }; //if a class has an extra descriptor not part of the config descriptor, // this lookup table defines the size of that descriptor. //first element is the config number (if your device has more than one config) //second element is which interface number //set element to 0xFFFF if this config/interface combo doesn't exist const int16 USB_CLASS_SPECIFIC_DESC_LOOKUP_SIZE[USB_NUM_CONFIGURATIONS][1] = { //config 1 //interface 0 32 }; ////////////////////////////////////////////////////////////////// /// /// 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 41 //config+interface+class+endpoint+endpoint (2 end-points) 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 ==1 USB_DESC_CONFIG_TYPE, //constant CONFIGURATION (CONFIGURATION 0x02) ==2 USB_TOTAL_CONFIG_LEN,0, //size of all data returned for this config ==3,4 1, //number of interfaces this device supports ==5 0x01, //identifier for this configuration. (IF we had more than one configura-tions) ==6 0x00, //index of string descriptor for this configuration ==7 #if USB_CONFIG_BUS_POWER 0x80, //bit 6=1 if self powered, bit 5=1 if supports remote wakeup (we don't), bits 0-4 unused and bit7=1 ==8 #else 0xC0, //bit 6=1 if self powered, bit 5=1 if supports remote wakeup (we don't), bits 0-4 unused and bit7=1 ==8

Page 44: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 44

#endif USB_CONFIG_BUS_POWER/2, //maximum bus power required (maximum milliamperes/2) (0x32 = 100mA) //interface descriptor 1 USB_DESC_INTERFACE_LEN, //length of descriptor =10 USB_DESC_INTERFACE_TYPE, //constant INTERFACE (INTERFACE 0x04) =11 0x00, //number defining this interface (IF we had more than one interface) ==12 0x00, //alternate setting ==13 2, //number of endpoins, except 0 (pic167xx has 3, but we dont have to use all). ==14 0x03, //class code, 03 = HID ==15 0x00, //subclass code //boot ==16 0x00, //protocol code ==17 0x00, //index of string descriptor for interface ==18 //class descriptor 1 (HID) USB_DESC_CLASS_LEN, //length of descriptor ==19 USB_DESC_CLASS_TYPE, //dscriptor type (0x21 == HID) ==20 0x00,0x01, //hid class release number (1.0) ==21,22 0x00, //localized country code (0 = none) ==23 0x01, //number of hid class descrptors that follow (1) ==24 0x22, //report descriptor type (0x22 == HID) ==25 USB_CLASS_SPECIFIC_DESC_LOOKUP_SIZE[0][0], 0x00, //length of report descriptor ==26,27 //endpoint descriptor USB_DESC_ENDPOINT_LEN, //length of descriptor ==28 USB_DESC_ENDPOINT_TYPE, //constant ENDPOINT (ENDPOINT 0x05) ==29 0x81, //endpoint number and direction (0x81 = EP1 IN) ==30 USB_EP1_TX_ENABLE, //transfer type supported (0x03 is interrupt) ==31 USB_EP1_TX_SIZE,0x00, //maximum packet size supported ==32,33 USB_CONFIG_HID_TX_POLL, //polling interval, in ms. (cant be smaller than 10 for slow speed) ==34 //endpoint descriptor USB_DESC_ENDPOINT_LEN, //length of descriptor ==35 USB_DESC_ENDPOINT_TYPE, //constant ENDPOINT (ENDPOINT 0x05) ==36 0x01, //endpoint number and direction (0x01 = EP1 OUT) ==37 USB_EP1_RX_ENABLE, //transfer type supported (0x03 is interrupt) ==38 USB_EP1_RX_SIZE,0x00, //maximum packet size supported ==39,40 USB_CONFIG_HID_RX_POLL //polling interval, in ms. (cant be smaller than 10 for slow speed) ==41 }; //****** 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. //NOTE: DO TO A LIMITATION OF THE CCS CODE, ALL HID INTERFACES MUST START AT 0 AND BE SEQUENTIAL // FOR EXAMPLE, IF YOU HAVE 2 HID INTERFACES THEY MUST BE INTERFACE 0 AND INTERFACE 1 #define USB_NUM_HID_INTERFACES 1 //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 1

Page 45: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 45

//define how many interfaces there are per config. [0] is the first config, etc. const char USB_NUM_INTERFACES[USB_NUM_CONFIGURATIONS]={1}; //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][1][1]= { //config 1 //interface 0 //class 1 18 }; #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 ==1 0x01, //the constant DEVICE (DEVICE 0x01) ==2 0x10,0x01, //usb version in bcd ==3,4 0x00, //class code ==5 0x00, //subclass code ==6 0x00, //protocol code ==7 USB_MAX_EP0_PACKET_LENGTH, //max packet size for endpoint 0. (SLOW SPEED SPECIFIES 8) ==8 USB_CONFIG_VID & 0xFF, ((USB_CONFIG_VID >> 8) & 0xFF), //vendor id ==9, 10 USB_CONFIG_PID & 0xFF, ((USB_CONFIG_PID >> 8) & 0xFF), //product id, don't use 0xffff ==11, 12 USB_CONFIG_VERSION & 0xFF, ((USB_CONFIG_VERSION >> 8) & 0xFF), //device release number ==13,14 0x01, //index of string description of manufacturer. therefore we point to string_1 array (see below) ==15 0x02, //index of string descriptor of the product ==16 0x00, //index of string descriptor of serial number ==17 USB_NUM_CONFIGURATIONS //number of possible configurations ==18 }; ////////////////////////////////////////////////////////////////// /// /// 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) /// //////////////////////////////////////////////////////////////////

Page 46: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 46

//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}; // Here is where the "CCS" Manufacturer string and "CCS HID Demo" are stored. // Strings are saved as unicode. // These strings are mostly only displayed during the add hardware wizard. // Once the operating system drivers have been installed it will usually display // the name from the drivers .INF. char const USB_STRING_DESC[]={ // Primer descriptor. 4, // Longitud del descriptor. USB_DESC_STRING_TYPE, 0x09,0x04, // Lenguaje id = Inglés (Definido por microsoft). // Segundo descriptor. 8, // Longitud del descriptor. USB_DESC_STRING_TYPE, // Descriptor del compilador utilizado. (STRING) (Puede ser el nombre de la compañía) 'C',0, 'C',0, 'S',0, // Tercer descriptor. 32, // Longitud del descriptor. USB_DESC_STRING_TYPE, // Descriptor del fabricante: MoyaPIC_easyHID. (STRING) 'M',0, 'o',0, 'y',0, 'a',0, 'P',0, 'I',0, 'C',0, '_',0, 'e',0, 'a',0, 's',0, 'y',0, 'H',0, 'I',0, 'D',0 }; #ENDIF

Page 47: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 47

ANEXO 2:Programas de la aplicación del PC Form1.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Diagnostics; using System.Windows.Forms; using System.Runtime.InteropServices; using MecaniqueUK; namespace WindowsFormsApplication1 { public partial class USB_FORM : Form { /***************************************************/ // Variables definidas por el usuario. UInt32 controlador; string ctemp, chumed; char temp1, temp2, temp3, temp4, temp5, temp6; char humed1, humed2, humed3, humed4, humed5, humed6; int salida_t = 0; int salida_h = 0; double ayuda_t, ayuda_h; int i = 0; int j = 0; int k = 0; int l = 0; int pepe_t, pepe_h; int boton_control_temp = 0; //Variable que indica si el control de temperatura está en Manual o Auto. double tempcamp, humedcamp, Prop_t, Derv_t, Inte_t, SP_t; double Er_t, Er_ant_t, Suma_Er_t, Sal_ant_t; double Prop_h, Derv_h, Inte_h, SP_h; double Er_h, Er_ant_h, Suma_Er_h, Sal_ant_h; int boton_control_humed = 0; //Variable que indica si el control de humedad está en Manual o Auto. int periodo_calef = 0; int ciclo_calef = 0; int cuenta_calef = 0; int periodo_humed = 0; int ciclo_humed = 0; int cuenta_humed = 0; /***************************************************/ public USB_FORM() { InitializeComponent(); MENSAJE_TOOL.SetToolTip(this.CONECTAR_DISPOSITIVO, "Botón que enlaza el dispositivo al controlador.");

Page 48: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 48

} private void FormMain_Load_1(object sender, EventArgs e) { timer1.Enabled = true; deshabilita_controles(); } private void FormMain_FormClosed(object sender, FormClosedEventArgs e) { EasyHID.Disconnect(); } private void Dispositivo_Conectado(UInt32 handle) { if (EasyHID.GetVendorID(handle) == EasyHID.VENDOR_ID && Easy-HID.GetProductID(handle) == EasyHID.PRODUCT_ID) { // Si el handler ha encontrado un dispositivo conectado... EasyHID.SetReadNotify(handle, true); // Activa el sistema de notificaciones. controlador = handle; } } private void Dispositivo_desconectado(UInt32 handle) { if (EasyHID.GetVendorID(handle) == EasyHID.VENDOR_ID && Easy-HID.GetProductID(handle) == EasyHID.PRODUCT_ID) { CONECTAR_DISPOSITIVO.BackColor = Color.Red; CONECTAR_DISPOSITIVO.ForeColor = Color.White; CONECTAR_DISPOSITIVO.Text = "CONECTAR DISPOSITIVO"; deshabilita_controles(); EasyHID.Disconnect(); MessageBox.Show("PROBLEMAS DE COMUNICACION\n LA APLICACION SE CERRARA ", "Alerta", MessageBoxButtons.OK, MessageBoxIcon.Warning); Close(); } } private void Lee_datos(UInt32 In_handle) { if (CONECTAR_DISPOSITIVO.Text == "DISPOSITIVO CONECTADO ") { byte[] BufferINP = new byte[EasyHID.BUFFER_IN_SIZE]; // Declaramos el buffer de entrada. if ((EasyHID.Read(In_handle, out BufferINP)) == true) // Si hay datos, los procesamos... { temp1 = (char)BufferINP[1]; temp2 = (char)BufferINP[2]; temp3 = (char)BufferINP[3]; temp4 = (char)BufferINP[4]; temp5 = (char)BufferINP[5]; temp6 = (char)BufferINP[6]; ctemp = temp2.ToString() + temp3.ToString() + ',' + temp5.ToString() + temp6.ToString(); tempcamp = Convert.ToDouble(ctemp); ctemp += " ºC";

Page 49: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 49

label11.Text = ctemp; humed1 = (char)BufferINP[7]; humed2 = (char)BufferINP[8]; humed3 = (char)BufferINP[9]; humed4 = (char)BufferINP[10]; humed5 = (char)BufferINP[11]; humed6 = (char)BufferINP[12]; chumed = humed2.ToString() + humed3.ToString() + ',' + humed5.ToString() + humed6.ToString(); humedcamp = Convert.ToDouble(chumed); chumed += " %H"; label12.Text = chumed; } } } protected override void WndProc(ref Message message) { // Interceptamos los mensajes de windows. if (message.Msg == EasyHID.WM_HID_EVENT) // Si ha ocurrido algún evento... { switch (message.WParam.ToInt32()) // Intercepta el mensaje y opera según el valor recibido.... { case EasyHID.NOTIFY_PLUGGED: Dispositivo_Conectado((UInt32)message.LParam.ToInt32()); // Se ha conectado un dispositivo. break; case EasyHID.NOTIFY_UNPLUGGED: Dispositivo_desconectado((UInt32)message.LParam.ToInt32()); // Se ha desconectado un dispositivo. break; case EasyHID.NOTIFY_READ: Lee_datos((UInt32)message.LParam.ToInt32()); // Hay datos en el buf-fer de entrada. break; } } base.WndProc(ref message); } private void OUT_DIGITAL_1_Click(object sender, EventArgs e) { if (j == 0) { OUT_DIGITAL_1.BackColor = Color.Green; j = 1; } else { OUT_DIGITAL_1.BackColor = Color.Red; j = 0; } byte[] BufferOUT = new byte[EasyHID.BUFFER_OUT_SIZE]; BufferOUT[0] = 0; // Report ID

Page 50: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 50

BufferOUT[1] = 0x0A; // Primero enviamos un comando de control al dispositivo: 0x0A (COMANDO_SALIDAS). BufferOUT[2] = 0x10; // Luego enviamos los datos de control de los LED'S. EasyHID.Write(controlador, BufferOUT); // Envía los datos. } private void OUT_DIGITAL_2_Click_1(object sender, EventArgs e) { if (k == 0) { OUT_DIGITAL_2.BackColor = Color.Green; k = 1; } else { OUT_DIGITAL_2.BackColor = Color.Red; k = 0; } byte[] BufferOUT = new byte[EasyHID.BUFFER_OUT_SIZE]; BufferOUT[0] = 0; // Report ID BufferOUT[1] = 0x0A; // Primero enviamos un comando de control al dispositivo: 0x0A (COMANDO_SALIDAS). BufferOUT[2] = 0x20; // Luego enviamos los datos de control de los LED'S. EasyHID.Write(controlador, BufferOUT); // Envía los datos. } private void B_Cont_temp_Click(object sender, EventArgs e) { if (boton_control_temp == 0) { B_Cont_temp.Text = "MANUAL"; Ind_cont_temp.BackColor = Color.Green; Ind_cont_temp.Text = "CONTROL AUTO"; boton_control_temp = 1; numericUpDown1.Enabled = false; REF1.Enabled = true; SP_t = tempcamp; label23.Text = string.Format("{0:F2}", SP_t); Er_t = 0; Er_ant_t = 0; Suma_Er_t = 0; Sal_ant_t= salida_t; } else { B_Cont_temp.Text = "AUTO"; Ind_cont_temp.BackColor = Color.Red; Ind_cont_temp.Text = "CONTROL MANUAL"; Sal_ant_t = ayuda_t; pepe_t = Convert.ToInt16(ayuda_t / 2.46); label22.Text = System.Convert.ToString(pepe_t) + '%'; numericUpDown1.Enabled = true; numericUpDown1.Value = Convert.ToDecimal(pepe_t); boton_control_temp = 0; REF1.Enabled = false;

Page 51: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 51

} } private void numericUpDown1_ValueChanged(object sender, EventArgs e) { pepe_t = Convert.ToInt16( numericUpDown1.Value); label22.Text = Convert.ToString(numericUpDown1.Value) + '%'; ayuda_t = pepe_t * 2.46; salida_t = Convert.ToInt16(ayuda_t); byte[] BufferOUT = new byte[EasyHID.BUFFER_OUT_SIZE]; BufferOUT[0] = 0; // Report ID BufferOUT[1] = 0x0B; // Primero enviamos un comando de control al dispositivo: 0x0B (COMANDO_PWM1). BufferOUT[3] = Convert.ToByte(salida_t); // Luego enviamos los datos del du-ty_cicle del PWM1. EasyHID.Write(controlador, BufferOUT); // Envía los datos. } private void textBox2_KeyPress(object sender, KeyPressEventArgs e) { if (e.KeyChar == Convert.ToChar(13)) { // Se pulsó la tecla Entrar e.Handled = true; if (i == 1) { SP_t = Convert.ToDouble(REF1.Text); label23.Text = string.Format("{0:F2}", SP_t); REF1.Text = ""; } if (i == 2) { Prop_t = Convert.ToDouble(kp1.Text); labelkp.Text = string.Format("{0:F5}", Prop_t); kp1.Text = ""; } if (i == 3) { Derv_t = Convert.ToDouble(kd1.Text); labelkd.Text = string.Format("{0:F5}", Derv_t); kd1.Text = ""; } if (i == 4) { Inte_t = Convert.ToDouble(ki1.Text); labelki.Text = string.Format("{0:F5}", Inte_t); ki1.Text = ""; } if (i == 5) { SP_h = Convert.ToDouble(REF2.Text); labelREF2.Text = string.Format("{0:F2}", SP_h); REF2.Text = ""; } if (i == 6) {

Page 52: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 52

Prop_h = Convert.ToDouble(kp2.Text); labelkp2.Text = string.Format("{0:F5}", Prop_h); kp2.Text = ""; } if (i == 7) { Derv_h = Convert.ToDouble(kd2.Text); labelkd2.Text = string.Format("{0:F5}", Derv_h); kd2.Text = ""; } if (i == 8) { Inte_h = Convert.ToDouble(ki2.Text); labelki2.Text = string.Format("{0:F5}", Inte_h); ki2.Text = ""; } } else if (e.KeyChar == Convert.ToChar(8)) { // Se pulsó la tecla retroceso e.Handled = false; } else if (e.KeyChar == ',') { TextBox ObjTextBox = (TextBox)sender; if (ObjTextBox.Text.IndexOf(',') != -1) { // Sólo puede haber una coma e.Handled = true; } } else if (e.KeyChar == '-' || e.KeyChar == '+') { TextBox ObjTextBox = (TextBox)sender; // Admitir - o + sólo en la primera posición: if (ObjTextBox.SelectionLength == ObjTextBox.TextLength) { // Todo el texto está seleccionado: se sobrescribe con el signo e.Handled = false; } else if (ObjTextBox.TextLength != 0) { // La primera posición ya está ocupada e.Handled = true; } } else if (e.KeyChar < '0' || e.KeyChar > '9') { // Desechar los caracteres que no son dígitos e.Handled = true; } } private void CONECTAR_DISPOSITIVO_Click(object sender, EventArgs e) { EasyHID.Connect(Handle); if (EasyHID.IsAvailable(EasyHID.VENDOR_ID, EasyHID.PRODUCT_ID) == true)

Page 53: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 53

{ //Si el dispositivo está conectado... habilita_controles(); CONECTAR_DISPOSITIVO.Text = "DISPOSITIVO CONECTADO "; CONECTAR_DISPOSITIVO.BackColor = Color.GreenYellow; CONECTAR_DISPOSITIVO.ForeColor = Color.Black; } else { CONECTAR_DISPOSITIVO.Text = "CONTROLADOR CONECTADO "; CONECTAR_DISPOSITIVO.BackColor = Color.Blue; CONECTAR_DISPOSITIVO.ForeColor = Color.White; } } private void timer1_Tick(object sender, EventArgs e) { statusStrip1.Items[0].Text = DateTime.Now.ToLongTimeString(); if (boton_control_temp == 1) { Er_t = SP_t - tempcamp; //Error ayuda_t = Sal_ant_t + (Prop_t * Er_t) + (Derv_t * (Er_t - Er_ant_t)) + (In-te_t * Er_t + Suma_Er_t); // Calculo de la salida Suma_Er_t = Inte_t * Er_t + Suma_Er_t; //Actualizacion del termino integral Er_ant_t = Er_t; //Actualización de error anterior if (ayuda_t > 246) { ayuda_t = 246; Suma_Er_t = 0; } if (ayuda_t < 0) { ayuda_t = 0; Suma_Er_t = 0; } salida_t = Convert.ToInt16(ayuda_t); byte[] BufferOUT = new byte[EasyHID.BUFFER_OUT_SIZE]; BufferOUT[0] = 0; // Report ID BufferOUT[1] = 0x0B; // Primero enviamos un comando de control al disposi-tivo: 0x0B (COMANDO_PWM1). BufferOUT[3] = Convert.ToByte(salida_t); // Luego enviamos los datos del duty_cicle del PWM1. EasyHID.Write(controlador, BufferOUT); // Envía los datos. Sal_ant_t = ayuda_t; pepe_t = Convert.ToInt16(ayuda_t / 2.46); label22.Text = System.Convert.ToString(pepe_t) + '%'; } if (boton_control_humed == 1) {

Page 54: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 54

Er_h = SP_h - humedcamp; //Error ayuda_h = Sal_ant_h + ( Prop_h * Er_h) + (Derv_h * (Er_h - Er_ant_h)) + (In-te_h * Er_h + Suma_Er_h);// Calculo de la salida Suma_Er_h = Inte_h * Er_h + Suma_Er_h; //Actualizacion del termino integral Er_ant_h = Er_h; //Actualización de error anterior if (ayuda_h > 246) { ayuda_h = 246; Suma_Er_h = 0; } if (ayuda_h < 0) { ayuda_h = 0; Suma_Er_h = 0; } salida_h = Convert.ToInt16(ayuda_h); byte[] BufferOUT = new byte[EasyHID.BUFFER_OUT_SIZE]; BufferOUT[0] = 0; // Report ID BufferOUT[1] = 0x0C; // Primero enviamos un comando de control al disposi-tivo: 0x0C (COMANDO_PWM2). BufferOUT[4] = Convert.ToByte(salida_h); // Luego enviamos los datos del duty_cicle del PWM2. EasyHID.Write(controlador, BufferOUT); // Envía los datos. Sal_ant_h = ayuda_h; pepe_h = Convert.ToInt16(ayuda_h / 2.46); label24.Text = System.Convert.ToString(pepe_h) + '%'; } if (button2.Text == "CONTROL AUTO") { if (periodo_calef > 0) { if (ciclo_calef > 0) { if (cuenta_calef == 0) { if (j == 0) { OUT_DIGITAL_1.BackColor = Color.Green; j = 1; byte[] BufferOUT = new byte[EasyHID.BUFFER_OUT_SIZE]; BufferOUT[0] = 0; // Report ID BufferOUT[1] = 0x0A; // Primero enviamos un comando de control al dispositivo: // 0x0A (COMANDO_SALIDAS). BufferOUT[2] = 0x10; // Luego enviamos los datos de con-trol de los LED'S. EasyHID.Write(controlador, BufferOUT); // Envía los datos. } } if ((cuenta_calef >= ciclo_calef)&&(j==1)) { OUT_DIGITAL_1.BackColor = Color.Red;

Page 55: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 55

j = 0; byte[] BufferOUT = new byte[EasyHID.BUFFER_OUT_SIZE]; BufferOUT[0] = 0; // Report ID BufferOUT[1] = 0x0A; // Primero enviamos un comando de control al dispositivo: // 0x0A (COMANDO_SALIDAS). BufferOUT[2] = 0x10; // Luego enviamos los datos de control de los LED'S. EasyHID.Write(controlador, BufferOUT); // Envía los datos. } cuenta_calef++; //incrementa contador label10.Text = string.Format("{0:D}", cuenta_calef) + " sg"; if (cuenta_calef >= periodo_calef) { cuenta_calef = 0; //reinicia contador label10.Text = string.Format("{0:D}", cuenta_calef) + " sg"; } } } } if (button3.Text == "CONTROL AUTO") { if (periodo_humed > 0) { if (ciclo_humed > 0) { if (cuenta_humed == 0) { if (k == 0) { OUT_DIGITAL_2.BackColor = Color.Green; k = 1; byte[] BufferOUT = new byte[EasyHID.BUFFER_OUT_SIZE]; BufferOUT[0] = 0; // Report ID BufferOUT[1] = 0x0A; // Primero enviamos un comando de control al dispositivo: 0x0A (COMANDO_SALIDAS) BufferOUT[2] = 0x20; // Luego enviamos los datos de con-trol de los LED'S. EasyHID.Write(controlador, BufferOUT); // Envía los datos. } } if ((cuenta_humed >= ciclo_humed) && (k == 1)) { OUT_DIGITAL_2.BackColor = Color.Red; k = 0; byte[] BufferOUT = new byte[EasyHID.BUFFER_OUT_SIZE]; BufferOUT[0] = 0; // Report ID BufferOUT[1] = 0x0A; // Primero enviamos un comando de control al dispositivo: 0x0A (COMANDO_SALIDAS). BufferOUT[2] = 0x20; // Luego enviamos los datos de control de los LED'S. EasyHID.Write(controlador, BufferOUT); // Envía los datos.

Page 56: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 56

} cuenta_humed++; //incrementa contador label17.Text = string.Format("{0:D}", cuenta_humed) + " sg"; if (cuenta_humed >= periodo_humed) { cuenta_humed = 0; //reinicia contador label17.Text = string.Format("{0:D}", cuenta_humed) + " sg"; } } } } } private void salirToolStripMenuItem_Click(object sender, EventArgs e) { EasyHID.Disconnect(); this.Close(); } private void habilita_controles() { // Habilita salidas digitales. Control_Calefactor.Enabled = true; Control_Humidificador.Enabled = true; Control_Temperatura.Enabled = true; Control_Humedad.Enabled = true; } private void deshabilita_controles() { // deshabilita salidas digitales. Control_Calefactor.Enabled = false; Control_Humidificador.Enabled = false; Control_Temperatura.Enabled = false; Control_Humedad.Enabled = false; } private void REF1_Enter(object sender, EventArgs e) { i = 1; } private void kp1_Enter(object sender, EventArgs e) { i = 2; } private void kd1_Enter(object sender, EventArgs e) { i = 3; } private void ki1_Enter(object sender, EventArgs e) { i = 4; }

Page 57: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 57

private void REF2_Enter(object sender, EventArgs e) { i = 5; } private void kp2_Enter(object sender, EventArgs e) { i = 6; } private void kd2_Enter(object sender, EventArgs e) { i = 7; } private void ki2_Enter(object sender, EventArgs e) { i = 8; } private void B_Cont_humed_Click(object sender, EventArgs e) { if (boton_control_humed == 0) { B_Cont_humed.Text = "MANUAL"; Ind_cont_humed.BackColor = Color.Green; Ind_cont_humed.Text = "CONTROL AUTO"; boton_control_humed = 1; numericUpDown2.Enabled = false; REF2.Enabled = true; SP_h = humedcamp; labelREF2.Text = string.Format("{0:F2}", SP_h); Er_h = 0; Er_ant_h = 0; Suma_Er_h = 0; Sal_ant_h = salida_h; } else { B_Cont_humed.Text = "AUTO"; Ind_cont_humed.BackColor = Color.Red; Ind_cont_humed.Text = "CONTROL MANUAL"; Sal_ant_h = ayuda_h; pepe_h = Convert.ToInt16(ayuda_h / 2.46); label24.Text = System.Convert.ToString(pepe_h) + '%'; numericUpDown2.Enabled = true; numericUpDown2.Value = Convert.ToDecimal(pepe_h); boton_control_humed = 0; REF2.Enabled = false; } } private void numericUpDown2_ValueChanged(object sender, EventArgs e) { pepe_h = Convert.ToInt16(numericUpDown2.Value); label24.Text = Convert.ToString(numericUpDown2.Value) + '%';

Page 58: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 58

ayuda_h = pepe_h * 2.46; salida_h = Convert.ToInt16(ayuda_h); byte[] BufferOUT = new byte[EasyHID.BUFFER_OUT_SIZE]; BufferOUT[0] = 0; // Report ID BufferOUT[1] = 0x0C; // Primero enviamos un comando de control al dispositivo: 0x0C (COMANDO_PWM2). BufferOUT[4] = Convert.ToByte(salida_h); // Luego enviamos los datos del du-ty_cicle del PWM2. EasyHID.Write(controlador, BufferOUT); // Envía los datos. } private void textBox1_KeyPress(object sender, KeyPressEventArgs e) { if (e.KeyChar == Convert.ToChar(13)) { // Se pulsó la tecla Entrar e.Handled = true; if (l == 1) { periodo_calef = Convert.ToInt16(textBox1.Text); label6.Text = string.Format("{0:D}", periodo_calef) + " sg"; textBox1.Text = ""; } if (l == 2) { if (periodo_calef >= Convert.ToInt16(textBox2.Text)) { ciclo_calef = Convert.ToInt16(textBox2.Text); label8.Text = string.Format("{0:D}", ciclo_calef) + " sg"; textBox2.Text = ""; } } if (l == 3) { periodo_humed = Convert.ToInt16(textBox3.Text); label27.Text = string.Format("{0:D}", periodo_humed) + " sg"; textBox3.Text = ""; } if (l == 4) { if (periodo_humed >= Convert.ToInt16(textBox4.Text)) { ciclo_humed = Convert.ToInt16(textBox4.Text); label26.Text = string.Format("{0:D}", ciclo_humed) + " sg"; textBox4.Text = ""; } }

Page 59: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 59

} else if (e.KeyChar == Convert.ToChar(8)) { // Se pulsó la tecla retroceso e.Handled = false; } else if (e.KeyChar < '0' || e.KeyChar > '9') { // Desechar los caracteres que no son dígitos e.Handled = true; } } private void button2_Click(object sender, EventArgs e) { if (button2.Text == "CONTROL MANUAL") { button2.Text = "CONTROL AUTO"; button2.BackColor = Color.LightGreen; cuenta_calef = 0; label10.Text = string.Format("{0:D}", cuenta_calef) + " sg"; if (j == 1) { OUT_DIGITAL_1.BackColor = Color.Red; j = 0; byte[] BufferOUT = new byte[EasyHID.BUFFER_OUT_SIZE]; BufferOUT[0] = 0; // Report ID BufferOUT[1] = 0x0A; // Primero enviamos un comando de control al disposi-tivo: // 0x0A (COMANDO_SALIDAS). BufferOUT[2] = 0x10; // Luego enviamos los datos de control de los LED'S. EasyHID.Write(controlador, BufferOUT); // Envía los datos. } OUT_DIGITAL_1.Enabled = false; } else { button2.Text = "CONTROL MANUAL"; button2.BackColor = Color.Tomato; OUT_DIGITAL_1.Enabled = true; } } private void textBox1_Enter(object sender, EventArgs e) { l = 1; } private void textBox2_Enter(object sender, EventArgs e) { l = 2; }

Page 60: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 60

private void button3_Click(object sender, EventArgs e) { if (button3.Text == "CONTROL MANUAL") { button3.Text = "CONTROL AUTO"; button3.BackColor = Color.LightGreen; cuenta_humed = 0; label10.Text = string.Format("{0:D}", cuenta_humed) + " sg"; if (k == 1) { OUT_DIGITAL_1.BackColor = Color.Red; k = 0; byte[] BufferOUT = new byte[EasyHID.BUFFER_OUT_SIZE]; BufferOUT[0] = 0; // Report ID BufferOUT[1] = 0x0A; // Primero enviamos un comando de control al dis-positivo: // 0x0A (COMANDO_SALIDAS). BufferOUT[2] = 0x20; // Luego enviamos los datos de control de los LED'S. EasyHID.Write(controlador, BufferOUT); // Envía los datos. } OUT_DIGITAL_2.Enabled = false; } else { button3.Text = "CONTROL MANUAL"; button3.BackColor = Color.Tomato; OUT_DIGITAL_2.Enabled = true; } } private void textBox3_Enter(object sender, EventArgs e) { l = 3; } private void textBox4_Enter(object sender, EventArgs e) { l = 4; } } }

Page 61: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 61

EasyHID.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.ComponentModel; using System.Runtime.InteropServices; namespace MecaniqueUK { class EasyHID { // HID specific... public const UInt32 VENDOR_ID = 6017; public const UInt32 PRODUCT_ID = 2000; public const int BUFFER_IN_SIZE = 32; public const int BUFFER_OUT_SIZE = 32; // HID events... private const int WM_APP = 0x8000; public const int WM_HID_EVENT = WM_APP + 200; public const int NOTIFY_PLUGGED = 0x0001; public const int NOTIFY_UNPLUGGED = 0x0002; public const int NOTIFY_CHANGED = 0x0003; public const int NOTIFY_READ = 0x0004; // HID interface... [DllImport("mcHID.dll")] public static extern bool Connect(IntPtr pHostWin); [DllImport("mcHID.dll")] public static extern bool Disconnect(); [DllImport("mcHID.dll")] public static extern UInt32 GetItem(UInt32 pIndex); [DllImport("mcHID.dll")] public static extern UInt32 GetItemCount(); [DllImport("mcHID.dll")] public static extern bool Read(UInt32 pHandle, IntPtr pData); [DllImport("mcHID.dll")] private static extern bool Write(UInt32 pHandle, IntPtr pData); [DllImport("mcHID.dll")] private static extern bool ReadEx(UInt32 pVendorId, UInt32 pProductId, IntPtr pDa-ta); [DllImport("mcHID.dll")] private static extern bool WriteEx(UInt32 pVendorId, UInt32 pProductId, IntPtr pDa-ta); [DllImport("mcHID.dll")] public static extern UInt32 GetHandle(UInt32 pVendorID, UInt32 pProductId); [DllImport("mcHID.dll")] public static extern UInt32 GetVendorID(UInt32 pHandle); [DllImport("mcHID.dll")] public static extern UInt32 GetProductID(UInt32 pHandle); [DllImport("mcHID.dll")] public static extern UInt32 GetVersionID(UInt32 pHandle); [DllImport("mcHID.dll")] public static extern UInt32 GetInputReportLength(UInt32 pHandle); [DllImport("mcHID.dll")] public static extern UInt32 GetOutputReportLength(UInt32 pHandle); [DllImport("mcHID.dll")]

Page 62: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 62

public static extern void SetReadNotify(UInt32 pHandle, bool pValue); [DllImport("mcHID.dll")] public static extern bool IsReadNotifyEnabled(UInt32 pHandle); [DllImport("mcHID.dll")] public static extern bool IsAvailable(UInt32 pVendorId, UInt32 pProductId); // Managed version of the read/write functions. public static bool Read(UInt32 pHandle, out byte[] pData) { IntPtr unmanagedBuffer = Marshal.AllocHGlobal(BUFFER_IN_SIZE); bool result = Read(pHandle, unmanagedBuffer); try { pData = new byte[BUFFER_IN_SIZE]; Marshal.Copy(unmanagedBuffer, pData, 0, BUFFER_IN_SIZE); } finally { Marshal.FreeHGlobal(unmanagedBuffer); } return result; } public static bool Write(UInt32 pHandle, byte[] pData) { IntPtr unmanagedBuffer = Marshal.AllocHGlobal(BUFFER_OUT_SIZE); bool result; try { Marshal.Copy(pData, 0, unmanagedBuffer, BUFFER_OUT_SIZE); result = Write(pHandle, unmanagedBuffer); } finally { Marshal.FreeHGlobal(unmanagedBuffer); } return result; } } }

Page 63: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 63

ANEXO 3: Bibliotecas de CCS

CCS proporciona bibliotecas para la conexión de un PIC al PC mediante USB mediante

el uso de un PIC con un periférico USB interno (como el PIC16C765 o la familia

PIC18F4550) o mediante el uso de cualquier PIC con un periférico externo USB (el

Nacional USBN9603 familia).

Funciones relevantes:

usb_init () Inicializa el hardware USB. Entonces va a esperar en un bucle infi-

nito para el periférico USB para ser conectado al bus (pero eso no significa que

haya sido enumerados por el PC). Permitirá el uso y la interrupción del USB.

usb_init_cs () Al igual que usb_init (), pero no espera a que el dispositivo se

conecta al bus. Esto es útil si el dispositivo no está bus y puede funcionar sin

una conexión USB.

usb_task () Si usa el sentido de conexión, y el usb_init_cs () para la inicializa-

ción, entonces periódicamente debe llamar a esta función para mantener un ojo

en el pasador de conexión de sentido. Cuando el PIC está conectado al bus, esta

función entonces perpare el periférico USB. Cuando el PIC está desconectado

del bus, se restablecerá la pila USB y periféricos. Permitirá el uso y la inte-

rrupción del USB.

Nota: En su solicitud, usted debe definir USB_CON_SENSE_PIN a la clavija

de conexión de sentido.

usb_detach () Elimina el PIC desde el autobús. Se llamará automáticamente

usb_task () si se pierde la conexión, pero puede ser llamado de forma manual

por el usuario.

usb_attach () Concede al PIC al bus. Se llamará automáticamente usb_task ()

si la conexión, pero puede ser llamado de forma manual por el usuario.

usb_attached () Si se utiliza pines sentido (USB_CON_SENSE_PIN), devuel-

ve TRUE si que pin es alto. Persona siempre devuelve TRUE.

Page 64: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 64

usb_enumerated () Devuelve TRUE si el dispositivo ha sido enumerado por el

PC. Si el dispositivo ha sido enumerado por el PC, eso significa que está en el

modo de funcionamiento normal y se puede enviar / recibir paquetes.

usb_put_packet (Punto final, los datos, len, TGL) Coloca el paquete de datos en

el búfer de punto final especificado. Devuelve TRUE si éxito, FALSE si el buf-

fer está todavía llena con el último paquete.

usb_puts (Punto final, los datos, len, tiempo de espera) Envía los siguientes da-

tos para el punto final especificado. usb_puts () difiere de usb_put_packet ()

en el que va a enviar mensajes de múltiples paquetes, si los datos no caben en

un paquete.

usb_kbhit (punto final) Devuelve TRUE si el punto final especificado en los da-

tos es el búfer de recepción.

usb_get_packet (Variable, ptr, max) Lee hasta un máximo de bytes del búfer

de extremo especificado y lo guarda en el ptr puntero. Devuelve el número de

bytes guardados en ptr.

usb_gets (variable, ptr, máximo, tiempo de espera) Lee un mensaje desde el

punto final especificado. La diferencia usb_get_packet () y usb_gets () es que

usb_gets () esperará hasta que un mensaje completo ha recibido, que un men-

saje puede contener más de un paquete. Devuelve el número de los bytes reci-

bidos.

Page 65: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 65

Archivos relevantes:

pic_usb.h Hardware controlador de capa de la familia de controladores PIC

PIC16C765 con un periférico USB interno.

pic_18usb.h Hardware controlador de capa de la familia PIC18F4550 contro-

ladores PIC con un periférico USB interno.

usbn960x.h Controladores de hardware para la capa externa Nacional

USBN9603/USBN9604 periféricos USB. Usted puede usar este periférico ex-

terno USB para añadir a cualquier microcontrolador.

usb.h Definiciones comunes y prototipos utilizados por el controlador USB

usb.c La pila USB, que se ocupa de la interrupción USB y USB solicitudes de

instalación de punto final 0.

usb_cdc.h Un conductor que lleva el anterior son los archivos para crear un

dispositivo USB CDC, que emula un dispositivo RS232 legado y se muestra como

un puerto COM en el Administrador de dispositivos de MS Windows.

Page 66: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 66

ANEXO 4: USB

Firmware para dispositivo esclavo USB de Clase HID Emanuel G. Aguirre, Pablo A. Di Giulio

Universidad Tecnológica Nacional, Facultad Regional San Francisco

1. Introducción

El Bus USB por Universal Serial Bus (en adelante USB), fue ideado para ser un bus de

extensión para PC, con el objetivo de llegar a ser un estándar de la industria.

Las posibles tasas de transferencia son: 1,5 Mbits/s, 12 Mbits/s y 480 Mbits/s, lo

cual lo hace útil para aplicaciones que van desde periféricos de PC hasta dispositivos

de video u otros que requieran alta tasa de transferencia de datos.

Otro motivo fue la creación de un bus que fuera independiente de la plataforma de

hardware utilizada, al hacer que gran parte del funcionamiento dependa del software.

Otro motivo es la creación de una arquitectura de bus que permitiera conectar los pe-

riféricos de la PC con un mismo conector y que además fuera Hot Plug And Play,

haciéndolo de esta forma más simple para el usuario; evitando así la multiplicidad de

conectores tales como el Puerto Serial, Puerto Paralelo, PS/2, Gameport, y demás de-

rivados del diseño original de la PC de IBM de los años 80.

Aún otro motivo es la reducción de costo. Dándose ésta en la reducción de cables de

cobre (por ser un bus de tipo serial), en la eliminación de la amplia variedad de conec-

tores (siendo todos reemplazados por un solo tipo).

La alternativa actual al USB es el bus FireWire (IEEE-1394), creado por Apple Com-

puter. El bus IEEE-1394 es más rápido y más flexible que el USB, pero es más caro. La

ventaja del USB es que es más útil para periféricos de baja tasa de transferencia de

datos, tales como periféricos de PC. Mientras que en el USB el Host es el que controla

las comunicaciones, el IEEE-1394 utiliza el modelo peer-to-peer en el cual los perifé-

ricos pueden comunicarse entre sí. El IEEE-1394 tiene una taza de transferencia

de 400 Mbits/s. Los 480 Mbits/s del USB 2.0 full-speed son actualmente superados

por el IEEE-1394b que llega a los 3,6 Gb/s.

La motivación principal para la realización de este trabajo fue profundizar en esta

tecnología, que actualmente es muy usada en el mundo, pero que en Argentina

se utiliza en forma escasa.

El objetivo del trabajo fue obtener el conocimiento y las aptitudes suficientes para

lograr la utilización del bus USB como interfaz con una PC para aplicaciones de uso

general. Luego se procedió a realizar la comunicación con el Driver del Host (PC) de la

Page 67: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 67

Clase HID del sistema operativo. El Driver del Host de la Clase HID está disponible

en todos los sistemas operativos de uso común en PCs.

La Clase HID, es una subclase de dispositivos USB cuya función es proveer a la PC de

una interfaz con el usuario (mouse, teclado, joystick, etc.). Está especificada como un

estándar, definido por el USB Implementers Forum y su versión actual es la HID 1.11.

2. Elementos del Trabajo y metodología

Los elementos utilizados para el presente trabajo fueron los siguientes:

-Placa de desarrollo con un Microcontrolador (MCU) Freescale 68HC908JB8 (Hard-

ware).

-Freescale CodeWarrior Development Studio v5.7 para MCUs 68HC(S)908 (Compila-

dor).

-Snoopy Pro v0.22 para Windows XP (USB Sniffer).

-Perisoft Bus Hound v6.0 para Windows XP (USB Sniffer).

En la arquitectura USB las capas de hardware y de software tienen a cargo distintas

funciones, tanto en el Esclavo como en el Host.

El MCU 68HC908JB8 se usó para implementar la capa de hardware del Esclavo USB.

El IDE CodeWarrior se utilizó para programar la capa de software del Esclavo USB,

simularla, y para grabarla en la memoria Flash del MCU. Los USB Sniffers se utiliza-

ron para analizar las estructuras de datos del sistema operativo que reflejan el tráfi-

co en el bus USB y así depurar el Firmware del MCU.

2.1. Arquitectura del bus USB

Para lograr un mínimo grado de comprensión del presente trabajo, es necesario anali-

zar los elementos del bus USB desde el punto de vista de los sistemas

de comunicaciones.

2.1.1. Elementos del USB

El USB es un bus ideado para intercambio de datos entre un computador anfitrión

(Host), y dispositivos conectados a él (Esclavos). Los periféricos conectados al USB

comparten el ancho de banda del bus mediante un protocolo basado en mensajes

(tokens).

Un sistema USB consta de 3 partes:

- Anfitrión USB (USB Host o Host).

- Dispositivos USB (USB devices).

Page 68: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 68

- Interconexión USB (USB interconnect).

Existe sólo un Host en un sistema USB. Los dispositivos USB proveen servicios o fun-

ciones al Host. La interconexión USB es la que soporta el tráfico entre el Host y los

dispositivos USB, es el canal da comunicación.

2.1.2. Topología

La topología física del USB es de tipo estrella jerarquizada. Con un máximo de 7

niveles de jerarquía.

La topología lógica del USB es de tipo estrella. Lo que implica que en un dispositivo

físico puede haber implementado más de un dispositivo lógico (por ej.: un teclado con

un mouse incluído).

2.1.3. Direccionamiento

El direccionamiento de dispositivos Esclavos USB se hace mediante un número de 7

bits, lo que hace posible direccionar hasta 128 dispositivos. En el caso de utilizar

HUBs, en teoría, pueden conectarse hasta 127 dispositivos USB por HUB.

Page 69: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 69

Dentro de cada dispositivo lógico USB existen uno o más Endpoints, que son recepto-

res independientes de datos.

El ruteo de los datos es de tipo Broadcast. Esto es, todos los esclavos dentro de una

jerarquía reciben los datos, pero solo los procesa el Esclavo al que están destinados

dichos datos.

2.1.4. Acceso al canal de comunicación

El protocolo de acceso al canal de comunicación (media access protocol) es de tipo po-

lled. Por lo tanto, cuando el Host se comunica con un Esclavo, lo hace mediante el envío

de un token con la dirección de dicho Esclavo al canal de comunicación (bus), solo el

Esclavo con esa dirección procesa el pedido del Host.

2.1.5. Tasas de transferencia de datos

Las posibles tasas de transferencia de datos para el USB son: 1,5 Mbits/s, 12

Mbits/s y 480 Mbits/s. La correspondiente denominación de cada una de ellas es:

- low-speed: 1,5 Mbits/s,

- full-speed: 12 Mbits/s,

- high-speed: 480 Mbits/s.

Cada una de las tasas de transferencia anteriores tiene ciertas características pro-

pias de funcionamiento y configuración.

2.1.6. Transmisión y codificación

Los datos son transmitidos en forma serie, en 2 líneas de datos complementarias de-

nominadas D+ y D-. Además se proveen 2 líneas de alimentación y de masa respectiva-

mente, las cuales pueden servir para que el dispositivo tome alimentación del Host (5

V, 500 mA máx.).

Para transmitir los datos en forma serie se utiliza la codificación Non-Return-

To-Zero-Inverted o NRZI. En este tipo de codificación, un 0 (cero) se representa sin

un cambio de nivel en la tensión, y un 1 (uno) se representa con un cambio de nivel en la

tensión. Conjuntamente, se utiliza el bit stuffing, técnica que consiste en insertar

un 0 (cero) cada 6 (seis) 1s (unos) consecutivos en el flujo de bits. Además, del bit

stuffing y de la codificación NRZI, se utilizan CRCs. Los CRCs se generan después del

bit stuffing.

2.2. Protocolo USB

Page 70: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 70

En el USB, lo datos se envían en paquetes. A su vez, los Paquetes se agrupan para for-

mar las Transacciones, y las Transacciones se agrupan para formar las Transferencias.

Las Transferencias son las estructuras de datos que tienen sentido para el Software

Client que corre en el Host, y que es el destinatario final de los datos enviados a o re-

cibidos desde el dispositivo lógico.

2.2.1. Endpoints, Buffers y Pipes

Cada canal lógico de comunicación entre el Host y el Esclavo está formado por una

tríada Endpoint-Pipe-Buffer. El Endpoint pertenece al Esclavo USB, el Buffer perte-

nece al Host, y el Pipe es la conexión lógica entre ambos.

Existen 2 tipos básicos de Endpoints: Los de Control y los de Datos. Los de Control

son utilizados para transferir información de configuración y estado entre Esclavo y

el Host. Los de Datos son utilizados para transferir datos que utiliza el software que

corre en el Host.

Cada Endpoint Está identificado por un número. Los Endpoints de Control pueden

transferir datos en ambas direcciones. La clasificación de los Endpoints de datos

según la dirección en la que transfieren los datos es:

- IN: Los datos van del Esclavo al Host.

- OUT: Los datos van del Host al Esclavo.

Los Endpoints se agrupan para formar Interfaces. Una Interface representa a un

dispositivo lógico USB.

Cada tipo de Endpoint está asociado a un tipo de Transferencia.

Page 71: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 71

2.2.2. Transferencias

Una Transferencia es un bloque de datos que conforma una estructura comprensible

para el Host o el Esclavo. Existen 2 tipos básicos de Transferencias, que estén direc-

tamente relacionadas a los tipos de Endpoints: las de Control y las de Datos.

Dentro de las Transferencias de datos existen 3 tipos:

- Transferencias de Interrupción (Interrupt Data Transfers): Baja tasa de transfe-

rencia de datos, es una reliable data transfer.

- Transferencias de Bultos (Bulk Data Transfers): Para transferir cantidades

relativamente grandes de datos en un solo envío. El ancho de banda disponible para

este tipo de transferencia varía en función de la disponibilidad de éste.

- Transferencias Isócronas (Isochronous Data Transfers): Ocupan un ancho de banda

del USB, cuya latencia es negociada en la configuración. Sirven para transmitir datos

a intervalos regulares de tiempo, es una unreliable data transfer.

Cada Endpoint de un dispositivo USB está asociado a un y sólo un tipo de Transferen-

cia. El Endpoint0 siempre realiza Control Transfers y todo los Esclavos USB lo tienen.

A la Pipe asociada al Endpoint0 se la denomina Default Control Pipe.

El Host obtiene la información sobre el tipo de transferencia que realizará cada End-

point durante el proceso de enumeración, cuando lee los Descriptores.

Las Transferencias de Control siempre inician con un paquete SETUP, el cual tiene

información sobre la función de configuración que el Host desee que el Esclavo realice.

Las Transferencias de datos siempre comienzan con paquetes IN u OUT.

2.3. Comportamiento de Esclavos USB

Un Esclavo USB tiene una cantidad finita de estados posibles.

Page 72: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 72

A continuación se describe cada uno de los posibles estados de un Esclavo USB:

- ATTACHED: Es el primer estado en que se encuentra el Esclavo apenas es conectado

físicamente al bus USB.

- POWERED: Se considera que un Esclavo USB está en este estado, cuando se ha

aplicado Vbus al dispositivo, o cuando se ha alimentado con una fuente externa.

- DEFAULT: Un Esclavo USB está en este estado después de que ha recibido una señal

de Reset USB.

Después de resetearse, éste puede comunicarse con el Host mediante el Endpoint0.

Cuando el proceso de reset ha sido completado con éxito, el dispositivo es capaz de

comunicarse a la velocidad correcta. La selección para low-speed y full-speed se hace

con resistores de terminación. Después de haber sido reseteado, el dispositivo debe

ser capaz de responder correctamente y devolver al host los Device Descriptor y

Configuration Descriptor, que contienen la información sobre el Esclavo.

- ADDRESSED: Un Esclavo USB se encuentra en este estado una vez que le ha

sido asignada una dirección USB por el Host.

Page 73: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 73

- CONFIGURED: Antes de que el Esclavo USB pueda prestar su utilidad, éste debe se

configurado. Desde el punto de vista del dispositivo, éste estará configurado una vez

que haya podido procesar correctamente un Request del tipo SetConfiguration().

- SUSPENDED: Este estado es usado para ahorrar energía. Un Esclavo entra en este

estado cuando no ha recibido un paquete EOP durante 3 ms. Un dispositivo debe

salir de este estado cuando detecta actividad en el bus. Durante este estado se man-

tiene la dirección USB que fue asignada al dispositivo USB.

2.3.1. Enumeración

Se denomina Enumeración (bus enumeration), al proceso, por el cual el Host identifica

a un dispositivo USB, leyendo sus Descriptores; y luego le asigna una dirección USB.

Además de detectar cuando un dispositivo es removido del bus, liberar la dirección

USB que este tenía asignada, y liberar los demás procesos asociados a las Pipes crea-

das para comunicarse con dicho dispositivo.

2.3.2. USB Device Requests

Todos los dispositivos USB responden a los Requests del Host mediante la Default

Control Pipe. Los Requests se manifiestan en las llamadas Control Transfers (Transfe-

rencias de Control). Una Transferencia de Control se reconoce porque comienza con un

paquete de tipo SETUP; a diferencia de los otros tipos de Transferencias que comien-

zan siempre con paquetes tipo IN u OUT.

Los Requests se dividen en:

- Standard Device Requests: Son los comunes a todos los tipos de dispositivos USB.

Sirven para que el Host identifique y configure un dispositivo durante el proceso

de Enumeración.

- Class Requests: Son los relativos a cualquier clase particular de dispositivo USB. Ca-

da clase de dispositivo (excepto las clases genéricas o definidas por los fabricantes,

vendor specific) está definida en una especificación de clase USB.

Cada clase tiene sus requisitos propios, tales como tipo y número mínimo de Endpoints;

además de otro tipo de Descriptor, que es llamado Report Descriptor (Descriptor de

Reporte), el cual indica al Host cómo deben interpretarse los datos que envía el Escla-

vo al Host según la función del Esclavo.

2.3.3. Descriptores

Los Descriptores son tablas en las que los Esclavos almacenan información sobre sus

características. Dichas tablas son no modificables por el Host (grabadas en ROM). Los

Page 74: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 74

Descriptores son jerárquicos. Algunos pueden contener información relativa a String

Descriptors, que tienen información para que el Host muestre al usuario.

El Host solicita los Descriptores a los esclavos USB mediante las Control Transfers.

Los Descriptores que están en los niveles más altos de la jerarquía de Descriptores,

informan al Host sobre la existencia de los Descriptores que están en los niveles más

bajos de la jerarquía de Descriptores.

A continuación se describen los Descriptores comunes a todos los tipos de Esclavos

USB:

- Device Descriptor: Contiene información sobre el máximo tamaño de paquete que

soporta el Endpoint0, cuántas configuraciones soporta el Esclavo, y otra información.

Es el primero que lee el Host.

- Configuration Descriptor: Existe uno por cada posible forma de operar del Esclavo

(solo puede haber una configuración activa en un determinado momento). Tiene

información sobre cuántas Interfaces existen por configuración.

- Interface Descriptor: Tiene información sobre el número de Endpoints (excepto el

Endpoint0) que utiliza al Interface y sobre la Clase a la que pertenece.

- Endpoint Descriptor: Existe uno por cada Endpoint de una Interface. Tiene informa-

ción sobre el número de Endpoint.

También sobre el tipo de Transferencia que realiza (Control, Interrupt, Bulk o Isoch-

ronous). Y también tiene información sobre el tamaño máximo de paquete del End-

point.

A continuación se describen los Descriptores básicos de las Clases USB:

- Class Descriptor: Especifica a qué Clase USB pertenece una Interface. También da

información sobre la longitud del Report Descriptor.

- Report Descriptor: Tiene información sobre cómo debe el Host interpretar las

Transferencias del Esclavo. Su estructura es totalmente diferente al del resto de los

Descriptores. En el contexto del USB, una Transferencia es equivalente a un Report, y

es un bloque de datos que el Host puede interpretar.

2.4. Modelo de capas del USB

El USB tiene su modelo particular de capas. En el cual existen 3 de ellas. Por lo gene-

ral, las 2 capas superiores se implementan en software y la inferior en hardware, tan-

to en el Esclavo como en el Host.

La Function Layer (Capa de Función) está formada por las Interfaces. Cada Interface

es está formada por un grupo de Endpoints. Los datos que se mueven no tienen forma-

to USB, tienen la estructura definida en el Report Descriptor; son los datos que co-

rresponden al par Client Software-Function.

Page 75: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 75

En la USB Device Layer (Capa de Dispositivo USB), la información transmitida entre

los pares son las Transacciones; que son entre Endpoints y Buffers.(estos últimos, im-

plementados en software en el Host).

En la USB Bus Interface Layer, los datos intercambiados entre los pares son Tran-

sacciones. Estas Transacciones están encuadradas dentro de los Frames generados a

intervalos regulares de tiempo por el Host Controller.

2.5. Clase HID

El nombre HID es la abreviatura de “Human Interface Devices”. Esta Clase, cuya ver-

sión actual es el estándar HID 1.11 fue ideada con el propósito de englobar a dispositi-

vos que permitan la interacción del usuario (ser humano) con el Host. Por lo tanto, los

requerimientos de ancho de banda son mínimos, y la transferencia de datos debe ser

confiable.

Los datos que los dispositivos HID envían al Host son interpretados por el HID Class

Driver del sistema operativo, para luego poder ser utilizados por la aplicación que los

requiera (Client Software).

Los dispositivos HID se comunican con el HID Class Driver mediante la (Default) Con-

trol Pipe o mediante Interrupt Pipes.

Los requisitos para la implementación de un dispositivo HID son:

- Control Endpoint (Endpoint0): obligatorio

- Interrupt IN Endpoint: obligatorio

- Interrupt OUT Endpoint: opcional

2.6. Hardware utilizado

Page 76: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 76

Para la implementación del Esclavo USB se utilizó un MCU Freescale (ex Motorola)

68HC908JB8 de 8 bits.

El MCU utilizado posee un módulo de Interfaz de bus USB (Esclavo) cuyos registros

de datos y control están mapeados en la memoria del MCU.

El módulo USB embebido en el MCU posee 3 Endpoints. El máximo payload de los End-

points de este dispositivo es de 8 bytes. El Endpoint0 es de Control. El Endpoint1 es

de tipo Interrupt IN. El Endpoint2 puede configurarse para funcionar como Interrupt

IN o como Interrupt OUT. Todos los Endpoints del MCU utilizado son low-speed, por

lo que tienen una tasa de transferencia de 1,5 Mbits/s; por lo que la máxima tasa de

transferencia de datos útiles es de 64 Kbits/s.

El módulo USB del MCU se configuró para trabajar de modo que produzca una Inte-

rrupción cada vez que se produzca un evento de envío o recepción en el bus USB.

2.7. Firmware desarrollado

El firmware del MCU en que se implementó el Esclavo USB HID se escribió en lengua-

je C.

El módulo USB del MCU se encarga de generar y decodificar los paquetes adicionales

a los datos, los CRCs, el bit stuffing y la codificación NRZI. Por lo que el firmware

debe encargarse de interactuar con los Drivers del sistema operativo.

Para que el Esclavo USB funcione correctamente, el firmware del MCU debe cumplir

con los siguientes:

- Contener los Descriptores.

- Implementar los Estados posibles de un Esclavo USB (Finite State Machine).

- Procesar los Standard Requests.

- Procesar los Class Requests.

- Enviar los Reports de acuerdo a lo definido en su(s) Report(s) Descriptor(s).

2.7.1. Implementación de Descriptores

Cada tipo de Descriptor se declaró como una estructura “const struct”, y luego se ini-

cializaron con sus correspondientes valores, excepto el Report Descriptor, que se de-

claró como un arreglo de caracteres.

Ya que cuando el Host solicita el Configuration Descriptor, el Esclavo debe enviar este

y todos sus Descriptores subordinados en forma concatenada, se creó una estructura

que los contuviera a todos; y es esta estructura la que se devuelve cuando se solicita

el Configuration Descriptor.

2.7.2. Implementación de Standard Requests

Page 77: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 77

Cada Standard Request se implementó como una función separada en el firmware.

Para identificar el tipo de Standard Request enviado por el Host, se leen los campos

de bits del paquete SETUP de la Control Transfer que contiene al Request.

La determinación de los parámetros del Standard Request solicitado también se hace

en base a una variable que forma parte del SETUP Packet. Como ejemplo, puede ci-

tarse que al Standard Request GetDescriptor() le corresponde un parámetro que es el

Descriptor solicitado.

Los parámetros son dependientes del Request. Existe un flag en los registros de con-

trol del módulo USB del Esclavo, que indica cuando un paquete es de SETUP.

2.7.3. Implementación de Class Requests

La decodificación de los Class Requests se hace con el mismo método que la decodifi-

cación de los Standard Requests. Con la única salvedad que los Class Requests y sus

parámetros son con referencia a la Clase USB implementada.

2.7.4. Reports

Todos los Reports (enviados al Host cuando este los solicita mediante el Endpoint co-

rrespondiente) deben tener siempre el tamaño y estructura declarados en el Report

Descriptor, los cuales dependen de la función a implementar en el Esclavo; en caso de

no cumplirse esto, el Host los recibirá, pero los descartará.

2.7.5. Otras consideraciones del firmware

El firmware debe, además, ser capaz de procesar un Bus Reset, el cual es una señal

enviada por el Host, y que es señalada por un flag en un registro de estado del MCU.

3. Resultados

Los resultados del trabajo se obtuvieron trabajando sobre una PC Host cuyo sistema

operativo era Microsoft Windows XP, la funcionalidad que presta el firmware imple-

mentado funciona de igual forma independientemente del Host al que se conecte el

dispositivo, ya que el USB es un Estándar de comunicación independiente de la plata-

forma y la Clase HID es también un Estándar. Por lo tanto, el dispositivo implementa-

do debe funcionar de igual forma en cualquier Host que corra un sistema operativo

que tenga un HID Class Driver.

Como ejemplos de uso de la Clase HID, se implementó el firmware para un teclado

USB, y también el firmware para un Mouse USB. No se implementó la parte física del

Page 78: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 78

teclado ni del mouse porque no eran los objetivos del trabajo. A pesar de esto, se si-

muló el funcionamiento del teclado y el del mouse, ambos en forma satisfactoria.

4. Discusión

Debido a que la programación MCUs involucra registros de hardware (programación de

bajo nivel), el único código que es migrable sin modificaciones a otro MCU es el código

que corresponde a los Descriptores. Lo anterior se debe a que cada fabricante de

MCUs define los registros de datos y control de la Interfaz de bus USB a su manera.

Por lo anterior, es importante tener un conocimiento de cómo funciona el USB. Sobre

todo en caso de tener que migrar a un MCU de otro fabricante.

En caso de necesidad de implementar un Esclavo USB que sea de otra Clase USB,

habrá que verificar la disponibilidad del Class Driver en el sistema operativo del Host.

Además, habrá que verificar los tipos, la cantidad, y la velocidad de los Endpoints que

se necesitan para implementar dicha Clase; y, en base a estos requerimientos, selec-

cionar el MCU a utilizar para la implementación de la Clase.

Pueden realizarse aplicaciones que hagan uso del bus USB, pero que no estén engloba-

das dentro de ninguna Clase USB.

Existen varias formas de hacer esto, y que no presentan mayor dificultad a la hora de

escribir el firmware para el esclavo. Pero, en estos casos, deberá escribirse un Driver

dedicado que haga uso de las funciones del núcleo (kernel) del sistema operativo para

el control del bus USB.

Es importante hacer notar que los Reports deben siempre ser del tamaño y estructura

declarados en el Report Descriptor; de otra manera, el Class Driver del sistema ope-

rativo del Host no reconocerá y descartará los Reports, aunque el Esclavo los envíe.

5. Conclusión

Se logró implementar un firmware que cumpla con las pautas de comunicación básicas

establecidas para un dispositivo USB de Clase HID. El firmware se escribió en lengua-

je C. Como aplicaciones de la Clase HID se simuló un teclado y también un mouse.

Pero, también podrían haberse simulado dispositivos tales como keypads, joysticks,

indicadores, etc.

Hasta puede realizarse adquisición de datos de baja velocidad (hasta 64 Kbits/s)

utilizando el hardware con Interrupt Endpoints low-speed que se utilizó y sirviéndose

del HID Class Driver del sistema operativo. Utilizando MCUs que dispongan de Inte-

Page 79: Fernando Bueno Zambruno Proyecto Final de Carrerabibing.us.es/proyectos/abreproy/50068/fichero/Proyecto.pdf · escuela superior de ingenieros de sevilla ingenierÍa en automÁtica

Fernando Bueno Zambruno Proyecto Final de Carrera

Ingeniero en Automática y Electrónica Industria 79

rrupt Endpoints fullspeed, la tasa máxima podría llegar a 1,216 Mbits/s, sirviéndose

del HID Class Driver del sistema operativo del Host.