7. Estructura de programación para el laboratorio JAVA. 7.1. Introducción. Después de realizar el laboratorio remoto con el programa LabVIEW vimos la necesidad de cambiar bruscamente de idea, aunque LabVIEW tiene la potencialidad suficiente para desempeñar la función de motor para el laboratorio remoto observamos que no es suficientemente flexible como para continuar desarrollándolo. Por este motivo se apostó por utilizar software libre para el desarrollo de esta nueva implementación. El software libre tiene generalmente varias ventajas fundamentales: x Su coste de utilización es normalmente cero o muy bajo. x Carecen de licencias de uso muy restrictivo. x Permiten total flexibilidad de programación del usuario. Para ello se utilizará JAVA, aunque será necesario programar parte en C debido a que los drivers usados para comunicarse con el osciloscopio que necesitamos utilizar están en esa plataforma. Parte de este laboratorio basado en JAVA se elaboró en el proyecto final de carrera de Joaquín Manuel Suárez Benítez llamado Arquitectura software para instrumentación remota basada en la API de JAVA JNI a través del bus GPIB. Partiremos de este proyecto pero pronto veremos que prácticamente se tendrá que comenzar desde cero usando solamente algunos trozos de código. Conforme avanza este capítulo se comentará los diversos cambios realizados. 7.2. Estructura del laboratorio original. En este apartado estructuraremos el laboratorio creado en el proyecto anteriormente indicado. Vemos que contiene dos partes diferenciadas, una es la encargada de comunicarse con el instrumento de medida en cuestión, a través de una librería dinámica realizada en C. La otra parte esta realizada en JAVA e intenta reproducir el osciloscopio con todas sus funciones. Para hacer comunicar estas dos partes es necesario tener un interfaz común entre los dos lenguajes, para ello se utilizará JNI. También es necesidad comunicar los comandos a los instrumentos, para ello se utilizará el Bus GPIB que utiliza comandos SCPI estandarizados, creando una interfaz para tal cometido. Hay que poner especial hincapié en observar que en este laboratorio solo se ha desarrollado un elemento (osciloscopio) de tres que constituyen, en un inicio, todo el laboratorio. Todos estos bloques se sintetizan en una interfaz de la siguiente estructura. - 47 - Osciloscopio Usuario Figura 20. Arquitectura general de funcionamiento 7.2.1. JNI (Java Native Interface). Debido a sus características multiplataforma y a su coste cero decidimos utilizar el lenguaje de programación JAVA3 para el desarrollo de dicha implementación. Es un lenguaje multiplataforma, podemos usarlo en diversos sistemas operativos ya que hay versiones de Java para casi todos los sistemas operativos. Es totalmente portable gracias a que es un lenguaje compilado e interpretado, es decir, el código Java es compilado solo una vez en un PC cualquiera y el código resultante es un código independiente de la plataforma llamado Bytecode4. Luego se usa un intérprete de Java distinto según el sistema operativo que use nuestra máquina. Ahora bien, ¿cómo usar el lenguaje Java para que se comunique con la DLL del bus GPIB? Java no puede usar directamente una DLL cualquiera simplemente cargándola. Para solucionar esto se usa el lenguaje C como un lenguaje intermediario. Con el lenguaje C podemos usar las librerías del bus GPIB e incluso directamente la DLL del adaptador. Bien, ahora la pregunta es, ¿cómo comunico Java con el lenguaje C? Usando una API de Java llamada JNI. Esta API permite usar código nativo, es decir, código escrito en un lenguaje distinto al de Java e insertarlo en nuestra aplicación como si de Java se tratara. 3 Java es un lenguaje de programación orientado a objetos desarrollado por Sun Microsystems a principios de los años 90. El lenguaje en sí mismo toma mucha de su sintaxis de C y C++, pero tiene un modelo de objetos más simple y elimina herramientas de bajo nivel, que suelen inducir a muchos errores, como la manipulación directa de punteros o memoria. 4 El bytecode es un código intermedio más abstracto que el código máquina. Habitualmente es tratado como un fichero binario que contiene un programa ejecutable similar a un módulo objeto, que es un fichero binario producido por el compilador cuyo contenido es el código objeto o código máquina. - 48 - Figura 21. Comunicación del lenguaje JAVA con lenguaje C Esta API hace que podamos usar librerías dinámicas con JAVA, el inconveniente es que hacemos que parte del sistema no tenga las ventajas de JAVA que comentamos anteriormente. Sin embargo, actualmente es la mejor opción encontrada hasta el momento. 7.2.2. Interconexión de equipos a través del bus GPIB. Necesitamos hacer una conexión desde los instrumentos a controlar hasta el PC, inicialmente estos instrumentos se componen solamente de un osciloscopio. Pero debido a motivos históricos se usó el Bus GPIB para hacer el laboratorio remoto anterior, por tanto, nos basaremos en el estudio que se ha hecho a este Bus para facilitar la implementación de este nuevo laboratorio. Para hacer esta conexión usaremos un adaptador USB-GPIB de Agilent, el modelo utilizado es el 82357A. Figura 22. Adaptador USB-GPIB de Agilent - 49 - 7.2.3. Interacción entre comandos GPIB y el lenguaje C. Una vez hemos realizado el conexionado, debemos instalar el software que nos viene con el adaptador GPIB del fabricante. Este software viene incluido en un CD de instalación y se llama Agilent IO Libraries Suite, éste contiene una serie de programas y librerías de Agilent las cuales nos permitirán acceder al dispositivo que queramos controlar. Entre todas las librerías que incluye podemos destacar la existencia en el directorio include de una serie librerías que nos serán útiles para hacer uso en nuestro trabajo del bus GPIB con el lenguaje C. De estas librerías de dicho CD de instalación solo nos van a interesar realmente 2 archivos. x El fichero de cabecera ni488.h x La librería dinámica GPIB-32.dll El fichero ni488.h nos permite acceder mediante punteros a las funciones definidas en el estándar GPIB. Las funciones en sí mismas vienen recogidas en la librería dinámica GPIB-32.dll. Una librería dinámica que contiene en tiempo de ejecución todas las funciones del estándar IEEE 488.2. Esta librería dinámica es solo usable en Microsoft Windows. Punt1 = funcion1; Punt2 = funcion2; ……... ni488.h funcion1 { ……… } funcion2 { ……… } GPIB-32.dll Figura 23. Relación entre ni488.h y GPIB-32.dll Ahora hay que hacer uso de las funciones GPIB definidas en la librería GPIB-32.dll desde un programa escrito en C, nos queda definir qué funciones GPIB son las que se pueden usar desde C y cuales son sus parámetros necesarios. Las funciones GPIB que se van a usar en este proyecto se reducen concretamente a cinco. Para una explicación detallada de todas las funciones GPIB usables desde C revise el manual de usuario de National Instruments, Function Reference NI-488.2. - 50 - Tabla 4. Funciones GPIB usadas Nombre función Parámetros Objetivos (int BdIndx, int pad, int sad, int tmo, int eot, int eos) (int) ibdev BdIndx Indica la interfaz de acceso para el dispositivo. pad Dirección primaria GPIB del dispositivo. sad Dirección secundaria del instrumento. tmo Valor del temporizador de entrada/salida. eot modo EOI del dispositivo. eos carácter EOS y modos. (int ud, void *rdbuf, long count) (int) ibrd ud Descriptor de dispositivo. count Número de bytes a ser leídos del bus GPIB. Obtener identificador del instrumento. Leer cadena de caracteres por el bus GPIB. Devuelve los errores producidos en la lectura a través de la variable ibsta. (int ud, void *wrtbuf, long count) (int) ibwrt ud Descriptor del dispositivo. wrtbuf Dirección del buffer que contiene los bytes del comando a escribir. count Número de bytes a ser escritos. (int ud, int v) (int) ibonl ud descriptor de dispositivo o interfaz. v Indica que interfaz o dispositivo se pone offline. (int ud) (int) ibclr ud descriptor de dispositivo o interfaz. Escribir cadena de caracteres por el bus GPIB. Devuelve los errores producidos en la escritura a través de la variable ibsta. Libera el identificador del instrumento poniéndolo fuera de línea. Devuelve el estado del instrumento a través de la variable ibsta. Reinicializa el instrumento especificado en ud. Devuelve el estado del instrumento a través de la variable ibsta. De esta forma, dadas estas funciones, los pasos para usar un instrumento pasa por: 1. Inicializar el instrumento usando la función ibdev. 2. Leer y/o escribir comandos GPIB a través de las funciones GPIB usando ibrd y ibwrt respectivamente. 3. Poner fuera de línea el instrumento una vez hayamos terminado de usarlo, usando ibonl. 7.2.4. Estudio del funcionamiento interno. Veremos un esquema de como estaría compuesta la arquitectura general de funcionamiento del proyecto. - 51 - Osciloscopio Usuario Figura 24. Arquitectura general de funcionamiento En apartados anteriores hemos explicado como se construirían estructuralmente cada bloque de carácter general, ahora tenemos que ser capaces de comprender el funcionamiento de una forma global haciendo hincapié en el proyecto desarrollado en particular. La parte programada en JAVA tiene un doble cometido, muestra en pantalla un entorno gráfico que se compone de una pantalla similar a la que tiene el osciloscopio y la botonería para el manejo de dicho osciloscopio. También hace la comunicación con la parte realizada en C a través del la API denominada JNI. La programación en C es la que se encarga de enlazar con la librería dinámica (GPIB32.DLL) que contiene las funciones necesarias para comunicarse con el osciloscopio a través del bus GPIB. Estas funciones se han comentado anteriormente 7.2.4.1. Entorno JAVA. Esta parte se puede dividir en diferentes bloques donde en cada bloque están contenidos varios archivos. Figura 25. Diagrama de bloques del funcionamiento general Explicaremos detalladamente cada bloque indicando que archivos están involucrados y que función desempeña. 7.2.4.1.1. Interfaz gráfica. - 52 - La interfaz gráfica constituye el punto de interacción gráfica entre usuario y máquina. Esta interfaz está constituida por 3 paneles. x Panel Izquierdo: panel de representación de los datos procedentes del osciloscopio. x Panel Derecho: panel de controles. Aquí aparecen representados los controles más habituales del osciloscopio. Los eventos de ratón provocados sobre estos controles generan eventos que realizan acciones sobre el bus GPIB, ya sea directa o indirectamente. x Panel Inferior: recoge los controles que se usan en los distintos menús del osciloscopio. Figura 26. Interfaz gráfica del osciloscopio remoto Para realizar gráficamente estos paneles se ha hecho uso del paquete gráfico Swing que se encuentra en JAVA. La implementación de la interfaz gráfica viene recogida en los archivos miosciloscopio.java, miosciloscopioaux.java, y miscontroles.java. - 53 - Figura 27. Archivos utilizados para crear la interfaz gráfica Miosciloscopio.java se encarga de inicializar todos los paneles y de crear la pantalla del osciloscopio. Miosciloscopioaux.java incluye la funcionalidad de los 6 botones inferiores de la pantalla comprobando y actualizando las variables bandera para moverse por los menús. De esta clase surgen 6 clases, una por cada botón inferior. Cada una de estas clases es nombrada con el formato “bX” siendo X un número entre 1 y 6. El panel derecho se encuentra implementado en la clase miscontroles.java que incluye la composición de todo el panel derecho con los controles del osciloscopio. La captura de los eventos de ratón realizados sobre el panel derecho e inferior es realizada en la siguiente lista de archivos clasificados en subsistemas junto a una breve descripción. Tabla 5. Archivos implicados en la captura de los eventos de ratón Subsistema Archivos Implicados ActionBotonCursor1.java ActionBotonCursor2.java ActionBotonCursors.java Sistema de cursores ActionBotonDown.java ActionBotonUp.java ActionBotonLeft.java ActionBotonRight.java Medidas tensión ActionBotonMedidaVoltage.java Descripción Controlan la activación y desactivación del cursor 1 y/o 2. Controla el sistema de banderas para el despliegue del menú Cursors. Comprueba la situación de los cursores (previamente mira si están activos para moverse o no) y posteriormente los ajusta convenientemente en base al rango temporal o el rango de tensión. Controla el sistema de banderas para el despliegue del primer submenú de Voltage - 54 - Medidas tiempo ActionBotonTime.java Display ActionBotonDisplay.java Autoscale Activar/desactivar canales ActionBotonAutoscale.java Delay Posición y ActionBotonActivaCanal.java ActionBotonDelayLeft.java ActionBotonDelayRight.java ActionBotonPosY.java ActionBotonTriggerDown.java ActionBotonTriggerUp.java Trigger ActionBotonTriggerSource.java Slope/coupling Mode ActionBotonAcoples.java ActionBotonMode.java Botón time/div ActionBotonTimebase.java Botón volt/div ActionBotonVoltdivision.java Botón holdoff ActionBotonHoldoff.java Controla el sistema de banderas para el despliegue del primer submenú de Time Controla el sistema de banderas para el despliegue del menú Display Invoca función Autoscale. Controla que canal se está representando. Introduce un retraso a la izquierda/derecha de la posición central en la señal de entrada. La cantidad de retraso introducido depende del rango temporal en ese momento que se calcula y se actualiza. Esta clase implementa las acciones a realizar cuando se pulsa el botón Posición Y, sumándole o restándole un offset según el caso. Estas clases aumentan o reducen progresivamente el nivel de trigger. Esta clase actualiza las banderas para mostrar el primer submenú de fuentes de trigger. Activa las banderas necesarias para que el menú Slope/Coupling aparezca Actualiza las banderas para mostrar el menú del botón Mode Esta clase ajusta la base de tiempos de nuestro osciloscopio al que se indica en el cajetín adjunto al botón Time/div en el panel de controles. Esta clase ajusta la base de tensión del canal de nuestro osciloscopio al que se indica en el cajetín adjunto al botón Volt/div en el panel de controles Ajusta el valor de holdoff de nuestro osciloscopio Los eventos de ratón sobre los controles del panel derecho e inferior provocan la ejecución del bloque “Auxiliar” o directamente del bloque “ControlGpib” dependiendo del evento de ratón realizado. 7.2.4.1.2. Auxiliar. Este bloque es usado cuando las peticiones que se realicen desde la interfaz gráfica requieran un tratamiento previo y/o posterior de la información del osciloscopio en el entorno - 55 - Java. Este bloque se encarga de recoger las peticiones procedentes del tratamiento de la captura de eventos de ratón (bloque Interfaz gráfica) cuando dichas peticiones así lo requieran y las transforma en otras peticiones aptas para su envío por el bus GPIB (bloque ControlGpib). El bloque auxiliar se comunicará con el bloque “ControlGpib” indicándole cuales de las funciones de dicho bloque quiere realizar y con qué parámetros. El bloque auxiliar viene recogido en el fichero miclase.java. 7.2.4.1.3. Control Gpib. Este bloque recoge las peticiones aptas desde Java que requieran el uso del bus GPIB y las envía al bus GPIB en formato adecuado. La funcionalidad de este bloque viene recogida en los ficheros ControlGpib.java y ControlGpib.h. Dentro del bloque ControlGpib cabe destacar la clase ControlGpib.java. Esta clase incluye la declaración de todas las funciones escritas en lenguaje nativo C y el nombre de la librería dinámica desde donde se cargará el contenido de las susodichas funciones. 7.2.4.2. Librería dinámica en C (DLL). Esta parte es la más dependiente tanto del sistema operativo como del propio elemento de medida, por tanto es la pieza más delicada de todo el sistema. Se encarga de comunicarse con el driver del bus GPIB a través de las funciones GPIB contenidas en la librería dinámica GPIB-32.DLL, estas funciones se han comentado anteriormente. Para usar estas funciones en la interfaz JAVA hay que hacer uso del módulo JNI ya que se tratan de funciones escritas en C. Esta parte de la comunicación se encarga el bloque ControlGPIB. En nuestro caso se crea una librería dinámica llamada migpib.dll y contiene 9 funciones que se encargan de transmitir y recibir información a través del bus GPIB mediante las 5 funciones GPIB que usaremos de GPIB-32.DLL. Cada una de estas funciones tiene una funcionalidad distinta, algunas de ellas solo es necesario transmitir el comando al bus pero en otras precisamos obtener algún valor leyendo de éste para modificarlo en la interfaz gráfica. A continuación mostraremos en una tabla estas 9 funciones indicando si es necesaria respuesta y una breve descripción de su funcionalidad. - 56 - Tabla 6. Funciones de migpib.dll Nombre función ¿Respuesta? Funcionalidad Sí Pide los puntos que generan la forma de onda en la pantalla del osciloscopio, en función del canal. Se obtiene un Array con los puntos requeridos. Impone el comando para realizar el autoescalado. Dependiendo de la variable “opcion” se pide al bus una medida diferente dentro de las opciones disponibles en el osciloscopio. Devuelve un string con el valor requerido. Impone el comando GPIB que se le ha pasado en los parámetros como un string. Impone el comando GPIB que se le ha pasado al bus GPIB y se lee de él una respuesta que se pasa como un string. Impone el comando GPIB que se le ha pasado al bus GPIB y se lee de él, si recibe respuesta se manda “true”, si no “false”. Pide la posición de los cursores tanto verticales (tensión), como horizontales (tiempo) y lo devuelve en un string. Indica al osciloscopio en que posición se tienen que colocar los cursores verticales (de tensión) y horizontales (de tiempo). Impone el tipo de adquisición que se quiere hacer. ObtenerOnda Autoscale No Obtenermedidas Sí imponercomando No solicitarcomando Sí solicitarestado Sí PideCursor Sí PoneCursor Sí AjusteDisplay No Figura 28. Como se observa se disponen de un número elevado de funciones para gestionar el bus GPIB. 7.3. Carencias y necesidad de mejora. El sistema completo tiene funcionalidad al 100% y es capaz de manejar el osciloscopio como si el manejo estuviera haciéndose localmente, sin embargo tiene varios puntos que suponen un handicap a la hora de la gestión y manutención del recurso. Todo esto es debido a la poca estructuración del proyecto y la poca generalidad de éste, realizándose exclusivamente para un instrumento del laboratorio haciéndose prácticamente imposible la reutilización de algún fragmento de código programado. Tenemos la necesidad de ampliar el sistema hacia otros elementos del laboratorio, actualmente se encuentra implementado solamente un entorno para un osciloscopio, el modelo para el que se ha realizado es el HP 54603B. Sería interesante implementar un generador de ondas y una fuente de alimentación, incluso otro modelo de osciloscopio, intentando modificar lo mínimo posible el código. - 57 - Figura 29. Osciloscopio que se encuentra implementado actualmente Nos vemos imposibilitados para realizar esta acción ya que el código escrito no tiene ninguna modularidad. La parte gráfica y la parte de comunicación con el controlador GPIB están entremezcladas y para realizar algún cambio es necesario modificarlo todo. Por tanto la ampliación hacia otros instrumentos de medida es demasiado complicada si utilizamos el sistema empleado actualmente. Una posible opción para evitar este molesto problema es diferenciar la interfaz gráfica con la de comunicación, así en el momento de corrección o ampliación no será necesario buscar en un largo código complejo y desestructurado. La idea es tener una parte común a todos los instrumentos y otra específica que forme la interfaz gráfica. La parte común se encargará de comunicar los comandos GPIB a dicho bus, esto se hace de la misma forma independientemente del instrumento con el que se comunique. Por tanto tendríamos tantas interfaces como instrumentos dispongamos y solamente un entorno de comunicación con el bus GPIB. En este proyecto actualmente es imposible independizar debido a que los comandos GPIB se generan cuando se pulsa algún botón en la interfaz gráfica. A continuación se muestra un esquema de cómo se comportaría el sistema cuando se conectan varios elementos al bus GPIB. - 58 - Figura 30. Ejemplo de modulación conectando 3 elementos al bus GPIB Se ve de forma clara que solamente necesitamos crear una interfaz gráfica para introducir un nuevo elemento en nuestro laboratorio remoto. De hecho, se ha pensado en introducir también un analizador lógico y un analizador de espectros. Al modular y separar funcionalidad se pueden independizar las diferentes partes, así se podría ejecutar la interfaz gráfica en cualquier otro ordenador, como por ejemplo un cliente. Hasta se puede dar otra vuelta de tuerca ya que la interfaz gráfica se puede programar en otro lenguaje distinto a JAVA, con solamente definir un protocolo de comunicación entre estos elementos. En el capítulo orientado al Bus GPIB se comenta que los estándares SCPI no especifican el lenguaje de los comandos GPIB sino un estilo de formato, es decir, los comandos SCPI no son iguales en todos los instrumentos, solamente es necesario que sigan unos patrones que se especifican en las normas. Por tanto, cada vez que tengamos un nuevo elemento necesitamos un juego de comandos nuevos y por lo general será diferente a cualquier otro, aunque conserven la forma cada empresa crea sus comandos GPIB propios. Esto es contraproducente en nuestro actual sistema ya que esos comandos GPIB se generan dentro del código mezclándose con el interfaz gráfico. Cualquier adaptación a un nuevo instrumento partiendo del que existe se convierte en una ardua y larga tarea para cualquier programador. La idea más sencilla a desarrollar trata de independizar estos comandos GPIB a la programación, un ejemplo de ello puede ser almacenarlos en un archivo de texto, por tanto cada instrumento dispondría de un archivo que contuviera sus comandos específicos. Así si cambiamos de elemento solamente tendremos que cambiar de fichero para solucionar el problema. - 59 - En la actualidad, en el sistema, la parte programada en C tiene mucho peso con respecto a la totalidad del mismo. Se ha comprobado que es necesario pasar alguna funcionalidad de esta parte a la de JAVA y hacer un poco más ligero el fragmento del sistema generado en C. La idea de utilizar JAVA para realizar el laboratorio surge al tener la obligación moral de inculcar la disciplina de software libre GPL. JAVA junto con la mayoría de programas para su desarrollo aparecen bajo esta licencia, como por ejemplo Eclipse 5 , sin embargo tenemos que tener especial cuidado porque los programas para desarrollar el lenguaje C son de licencia privada en su mayoría, de hecho en el proyecto anterior se utilizó Borland C++ que tiene licencia privativa perteneciente a Borland Software Corporation6. Se optó por cambiar este entorno de desarrollo, para ello se hizo una búsqueda y se seleccionó un programa llamado Dev-C++ de la empresa de software Bloodshed. Ya tenemos la certeza que estamos realizando un proyecto de coste cero debido a los programas software libre. 7.4. Estructura del nuevo laboratorio. Viendo todas las carencias de la estructura del proyecto original se optó por hacer un desarrollo de un nuevo laboratorio mucho más estructurado, orientado a una mejora importante basado en la generalidad para hacer un uso de éste lo más independientemente posible del instrumento y del sistema operativo. La solución consiste en disminuir peso a la parte programada en C que se comunica con los drivers del bus GPIB y en dividir la parte de JAVA en dos, una para la comunicación de forma generalizada para todos los instrumentos de medida que se puedan conectar al bus GPIB y la otra parte se encarga de realizar la interfaz gráfica de cada instrumento específico. Así también podremos tener solamente el entorno gráfico en el cliente, estando la parte de comunicación en el servidor. Veremos a continuación una gráfica mostrando dicha configuración. 5 Eclipse es un entorno de desarrollo integrado de código abierto independiente de una plataforma para desarrollar lo que el proyecto llama "Aplicaciones de Cliente Enriquecido", opuesto a las aplicaciones "Cliente-liviano" basadas en navegadores. Esta plataforma, típicamente ha sido usada para desarrollar entornos de desarrollo integrados, como el IDE de Java llamado Java Development Toolkit (JDT) y el compilador (ECJ) que se entrega como parte de Eclipse (y que son usados también para desarrollar el mismo Eclipse). 6 Borland Software Corporation (anteriormente Borland International, Inc.) es una compañía de software, ubicada en Scotts Valley, California, Estados Unidos, conocida sobre todo por sus herramientas de programación, especialmente Turbo Pascal que evolucionó hasta el actual Delphi. Borland nació en 1983 cuando el joven danés - 60 - Figura 31. Arquitectura general del nuevo laboratorio Es importante darse cuenta que tenemos ahora dos tipos de comunicación, una que se encarga del bus GPIB usando el controlador GPIB y otra que trata de comunicarse con el entorno gráfico a través de Internet, en esta parte haremos uso de ficheros que hacen de buffer tanto de entrada como de salida. De esta forma hacemos más versátil nuestro programa ya que la parte del cliente que contiene el entorno gráfico puede estar programada en cualquier tecnología, la hacemos independiente del servidor. Figura 32. Bloques de uso de nuestro programa en el servidor Se va a realizar una exposición del programa realizado de forma gradual, paso a paso comenzando por el instrumento y terminando por el cliente. - 61 - 7.4.1. Programas utilizados para el desarrollo de la aplicación. Como se comentó en el apartado anterior, uno de los motivos importantes para realizar este proyecto es usar programas con licencia GPL, es decir, que sean software libre. Se ha conseguido este propósito ya que todos los programas usados son software libre. Primeramente con el adaptador USB-GPIB debería venir mediante algún soporte digital los drivers necesarios para controlarlo. En nuestro caso estamos usando uno de la organización Agilent y viene con un CD que contiene el Agilent IO Library Suite 14.0, se trata de un conjunto de programas, librerías y documentación necesarios para poder controlar cualquier instrumento conectado bajo esta interfaz. Para comunicarse con el controlador del bus GPIB necesitamos desarrollar un programa en C. El motivo de por qué se tiene que hacer está explicado en capítulos anteriores. Para desarrollarlo necesitamos un entorno de desarrollo integrado ya que proveen un marco de trabajo amigable para la mayoría de los lenguajes de programación. En proyectos anteriores se usó un programa con licencia privada, nuestro deseo es trabajar con licencias gratuitas con software libre por tanto a partir de aquí se usará Dev-C++. MinGW es el compilador que usa este entorno de desarrollo, es la implementación de los compiladores GCC para la plataforma Win32, que permite migrar la capacidad de este compilador en entornos Windows. Es un fork de Cygwin en su versión 1.3.3. Además MinGW incluye un conjunto de la API de Win32, permitiendo un desarrollo de aplicaciones nativas para esa plataforma, pudiendo generar ejecutables y librerías usando la API de Windows. Para el desarrollo JAVA sería conveniente también utilizar un entorno de desarrollo, para ello disponemos de infinidad de posibilidades. Debido a su extenso uso y su elevada distribución en Internet se ha optado por usar Eclipse, actualmente es el IDE más usado de las características que se está buscando. Vimos que en el laboratorio creado se establecía una librería dinámica (DLL) para poder controlar las funciones que gestionan el bus GPIB. Su nombre es migpib.dll, conservaremos ese archivo aunque será totalmente distinto. La funcionalidad de esta parte es transmitir los comandos GPIB a través de unas funciones GPIB, hay dos métodos, imponer un comando al bus y hacer una pregunta, en el primero solamente hay que mandar el comando y en el segundo hay que mandarlo y leer la respuesta del mismo bus. Por tanto se pensó en realizar solamente dos funciones, una que cumpla la funcionalidad de imponer comando y otra que sea de pregunta al bus. - 62 - GPIB GPIB Figura 33. Nuevas funciones para migpib.dll Comentaremos las funciones que se han realizado. Se trata de dos funciones, llamadas Escribir y EscribirLeer. Tabla 7. Nuevas funciones de migpib.dll Nombre función ¿Respuesta? Escribir No EscribirLeer Sí Funcionalidad Impone el comando GPIB que se le ha pasado en los parámetros como un string. Impone el comando GPIB que se le ha pasado al bus GPIB y se lee de él una respuesta que se pasa como un string. La función Escribir es simple, al principio carga la librería que tiene las funciones GPIB y luego escribe en el bus GPIB con una de esas funciones. No necesita devolver nada ya que solamente se trata de una imposición. En cambio, la función EscribirLeer es bastante más compleja, aunque lo único que cambia es que después de escribir la petición debemos leer tantas veces haga falta hasta terminar la respuesta. Al final se devuelve esa respuesta. 7.4.2. Clases comando e instrumento. La orientación a objetos promete mejoras de amplio alcance en la forma de diseño, desarrollo y mantenimiento del software ofreciendo una solución a largo plazo a los problemas y preocupaciones que han existido desde el comienzo en el desarrollo de software: la falta de portabilidad del código y reusabilidad, código que es difícil de modificar, ciclos de desarrollo largos y técnicas de codificación no intuitivas. En nuestro programa vamos a tener dos clases, inicialmente, que serán el comando que se manda al bus y el instrumento al que se manda. Vemos que se asemeja bastante a la realidad. Crearemos tantos objetos instrumentos como instrumentos en la realidad haya y tantos objetos comandos como buses tengamos a los que mandar comandos GPIB. - 63 - Vemos una gráfica que indica la estructura que hemos creado para crear un instrumento y ser capaces de mandar comandos GPIB. Pantalla Instrumento Int interfaz Int dirppal Int dirsec Int index String identificador Boolean estado Comando Migpib.dll Escribir (interfaz, comando) mandar (instrumento, ”comando”) ControlGpib obtenerIDN () EscribirLeer (interfaz, comando) compruebaEstado () Figura 34. Diagrama con las clases Instrumento y Comando para comunicación con el bus GPIB La clase comando solamente contiene un método que se encarga de mandar el comando que especifiquemos al instrumento que hayamos creado con antelación. Para crear ese instrumento existe la clase instrumento que contiene las características propias que diferencian a cada elemento. Esta función mandar usa las definiciones que se hacen en ControlGpib.java de las funciones que programamos en C. 7.4.3. Ventana para comunicación de forma local. Existe una ventana de comunicación para hacerlo de forma local teniendo así la posibilidad de realizar pruebas y comprobar el comportamiento en el mismo servidor. Este programa solamente utiliza las dos clases anteriormente explicadas, instrumento y comando, se crean los tres instrumentos que componen actualmente el laboratorio con sus propiedades y con un objeto de la clase comando mandamos comandos GPIB de cada uno de los instrumentos. Para esta sencilla aplicación es suficiente con usar solamente AWT. Mostraremos a continuación la ventana generada. - 64 - Figura 35. Ventana de comunicación local Los instrumentos implementados son el osciloscopio (Agilent DSO3062A), el generador de funciones (Agilent 3320A) y la fuente de alimentación (Agilent E3631A). En la zona inferior de la ventana se hace la selección del instrumento al que mandar los comandos y en la zona superior se manda los comandos y se recibe el resultado que se obtiene. Mostraremos a continuación un esquema del funcionamiento del programa, haciendo hincapié en los objetos creados y la zona que usa cada uno de ellos. Figura 36. Esquema del funcionamiento del programa 7.4.4. Uso de properties para el juego de instrucciones. El juego de instrucciones de cada instrumento es grande y en la mayoría de los casos diferente para cada elemento, tener este juego de instrucciones en el código es un grave error, ya que cada modificación implicaría la recompilación del código. Sería importante tener almacenado ese juego de instrucciones en un archivo de texto para cada instrumento, así solamente trabajaremos con la creación o modificación de esos archivos para hacer modificaciones en el juego de instrucciones. - 65 - Para hacer esto las API’s de Java disponen de una clase llamada Properties que nos permite hacer todo lo que queremos, que es crear ficheros de configuración complejos y manejarlos con facilidad. Tanto la estructura de la clase como la sintaxis de los ficheros de propiedades están comentadas en la documentación del API y puede ser consultada online. Para cargar estos archivos hemos creado una clase que se encarga de cargar con el nombre que le hayamos indicado. Se trata de la clase Instrucciones, en ella solamente existe un método que se encarga de cargar el objeto juego de clase properties que hemos creado con anterioridad. Figura 37. Adicción de la clase Instrucciones Cada vez que creamos un objeto Instrumento hacemos la carga del archivo properties perteneciente a dicho instrumento a través del método carga que se encuentra en la clase Instrucciones. Veremos como se ha implementado el programa creado para la comunicación local. - 66 - Pantalla Instrumento Comando Migpib.dll osciloscopio Escribir (interfaz, comando) generadorOnda ControlGpib comando EscribirLeer (interfaz, comando) fuenteAlimentacion Properties Instrucciones Agilent, 3320A. gpib juego Agilent, DSO3062A. gpib Agilent, E3631A. gpib Figura 38. Uso de properties en el programa de comunicación local 7.4.5. Comunicación con el cliente a través de ficheros. El sistema tiene un funcionamiento local, necesitamos hacer una comunicación con otro ordenador para que el funcionamiento sea remoto. Hay que ser capaz de hacer lo mismo que hacíamos con la ventana local pero a través de un ordenador cliente. La ventana de comunicación local la dejamos apartada para usos de gestión en el servidor y comprobación, necesitamos un programa principal nuevo que haga la gestión de la comunicación. Es decir, un main que gestione la comunicación con el instrumento remoto y sea capaz de hacérselo saber al instrumento real mediante el mismo método usado en la comunicación local, aprovechando las mismas clases y objetos que creamos con anterioridad. La forma más fácil de hacerlo es mediante archivos de texto que funcionan como buffer de comandos para los diferentes instrumentos. Esta manera es la más genérica posible, cualquier lenguaje de programación puede leer y escribir archivos. Habrá dos archivos, uno de entrada y otro de salida, en el de entrada el instrumento remoto volcará los comandos que quiera que actúen sobre el instrumento real, y el en el de salida el bus GPIB escribirá los resultados de las preguntas que se le han pedido. - 67 - La parte de comunicación JAVA y la de la librería dinámica en C no debemos cambiarla ya que está pensada de manera global para usarse con cualquier instrumento y tecnología. Se tendrá que crear una clase main que cree los instrumentos y cargue sus instrucciones, a continuación lea del buffer de entrada, gestione esa información dependiendo de lo que requiera y devuelva en el buffer de salida el resultado si es necesario. Mostraremos la estructura de las clases creadas, se observará que prácticamente es la misma forma que anteriormente ya que la única diferencia es que leemos de un archivo en vez de un campo en una ventana. Figura 39. Estructura de las clases del programa final Como en nuestro caso tenemos 3 instrumentos para la creación del laboratorio remoto, se ha realizado este programa con estos instrumentos, en un futuro próximo se podrá ir ampliando a más elementos. A continuación se muestra una figura con los objetos que hemos tenido que crear de cada clase para el funcionamiento de este laboratorio en concreto. - 68 - Osciloscopio Comunicacion In.buffer Main Comunicación remota G. Ondas Out.buffer Instrumento Comando F. Alimentacion Migpib.dll osciloscopio Escribir (interfaz, comando) generadorOnda ControlGpib comando EscribirLeer (interfaz, comando) fuenteAlimentacion Properties Instrucciones Agilent, 3320A. gpib juego Agilent, DSO3062A. gpib Agilent, E3631A. gpib Figura 40. Funcionamiento del programa final para el laboratorio remoto con 3 instrumentos Este es a grosso modo el programa final creado, se pueden hacer mejoras pero estarán explicadas en el último apartado, funcionalmente es muy bueno porque gestiona cualquier instrumento con bus GPIB y podremos cargar su juego de instrucciones sin tener que volver a reprogramar. 7.5. Mejoras realizadas. A la hora de comenzar a hacer este laboratorio con tecnología JAVA nos encontramos un proyecto totalmente funcional, pero con un gran fallo, debido a su exclusividad, a la hora de plantearse ampliar los elementos que componen el laboratorio desechamos continuar o adaptar este entramado ilegible de código. Realmente solamente nos era útil la parte realizada en C y su comunicación con JAVA, la ya referenciada JNI, a partir de esto se comenzó a realizar un programa totalmente nuevo con unas características superiores a su antecesor. Este apartado resumirá de forma global y breve cuales han sido las mejoras con respecto a este anterior programa. Primeramente se comentará que todo el desarrollo se ha hecho con programas software libre, por tanto, el coste en este aspecto es cero. - 69 - Como prioridad teníamos hacer esta aplicación abierta, es decir, hacer el acceso al bus GPIB de forma genérica para que en cualquier momento otro elemento con bus GPIB pueda ser añadido al programa y monitorizarlo con éste. Otro tema importante es la portabilidad, la aplicación anterior contenía mucha programación en C, lo cual lo hace un programa más ligero (debido a la rapidez del lenguaje) pero menos portable. Debemos dar más peso a la parte de JAVA y hacer más ligera la de C, para que a la hora de portar la aplicación necesitemos hacer los mínimos cambios posibles. Una de las consecuencias es que el programa se hará más lento ya que JAVA es un lenguaje interpretado, actualmente este problema no tiene mucha influencia debido a la evolución tecnológica que están sufriendo los ordenadores. Por todas estas causas se ha realizado esta aplicación, con las características de versatilidad, máxima portabilidad, fácilmente ampliable debido a su generalidad. - 70 -