LabVIEW: Entorno gráfico de programación

- -
- 100%
- +
Las definiciones de tipos y definiciones de tipos estrictos (Type Def. y Strict Type Def.) se usan para enlazar todas las instancias de un control o indicador a un mismo fichero *.ctl. De esta forma, al modificar el fichero se modifican todas las instancias. Se puede elegir el tipo cuando se crea el control mediante una lista desplegable en la barra de herramientas junto al botón Edit/Customize Mode.
Las Type Definitions definen el tipo de datos de un control. Cuando el tipo de datos cambia, todos los controles asociados a él también cambian. En el menú contextual de una instancia se puede seleccionar Auto-Update from Type Def. para desactivar la actualización automática.
Un Strict Type Definition hace que todas las instancias sean iguales, no sólo el tipo de datos sino también en características como el rango, tamaño, color, etc. De esta forma, si se modifica la definición se actualizarían todas las instancias. Desde el menú contextual se puede eliminar el enlace entre la instancia y la definición.
1.2.3. Funciones
Esta paleta es la que se muestra al trabajar sobre el Diagrama de Bloques; con ella se puede acceder a las diferentes funciones, subVI y estructuras disponibles.

Figura 1-13. Paleta de funciones.
Al igual que con el menú de controles, en éste también hay varios submenús que se dividen dependiendo de la aplicación. Las funciones más usadas son las del submenú Programming.
El primero de los submenús de Programming es Structures. Contiene elementos que son equivalentes a las instrucciones de control de los lenguajes convencionales, es decir, son los bucles como WHILE o FOR y la estructura condicional CASE además de otras. Más adelante se dedica un capítulo completo a las estructuras.

Figura 1-14. Paleta de estructuras.
Los siguientes menús de Programming se dividen atendiendo al tipo de datos. Están los datos simples, como los numéricos, booleanos y strings (texto); además de los compuestos, como los clusters y arrays. Cada uno de estos menús tiene funciones para trabajar con esos datos.

Figura 1-15. Paletas de tipos de datos numéricos, booleanos y texto.
Los datos numéricos se dividen en enteros, de coma flotante y complejos, y dentro de cada uno puede haber distintos tamaños. Se puede cambiar de unos a otros mediante el menú contextual > Representation. Si se aplican dos números, por ejemplo un entero y otro flotante a una función, ésta cambiará automáticamente el tipo de los datos (coercion) para que así se pueda operar con ellos. Los booleanos únicamente pueden tener dos valores: Verdadero (TRUE) o Falso (FALSE), por esto son los apropiados para crear botones.
Los tipos de datos compuestos están, como su nombre indica, formados por otros datos, por lo que no se puede hablar simplemente de arrays sino que se debe decir array de números, array de booleanos, etc. Los arrays, también llamados arreglos, son listas ordenadas de valores, mientras que los cluster son un conjunto desordenado de otros datos y son equivalentes a los STRUCT del lenguaje C. Para indicar de qué están compuestos los datos, basta con arrastrar constantes de otros tipos de datos en el interior de los arrays o clusters.

Figura 1-16. Paletas de datos tipo arrays y clusters.
En la figura 1-17 pueden verse varios datos de cada uno de los distintos tipos vistos hasta ahora. En la parte izquierda se representan como controles, en el centro como constantes y en la derecha como indicadores. Obsérvese el sentido de la flecha blanca en el lateral de los controles e indicadores. Ésta sirve para diferenciarlos: si apunta hacia afuera será un control (lectura de datos), y si apunta hacia dentro será un indicador (escritura de datos). Además, el color del control será indicativo del tipo de datos al que corresponde. En el capítulo 3 se estudiarán los tipos de datos en detalle.
Mediante el menú contextual puede accederse a diferentes opciones. Así para los numéricos se puede elegir su formato de representación; para los strings, la forma en que se visualizarán (normal, contraseña, hexadecimal, etc.). En los arrays se les pueden añadir dimensiones, etc.

Figura 1-17. Diferentes tipos de datos.
Al igual que con los controles, el método para usar las funciones y los VI de la paleta de funciones es ‘arrastrar y colocar’. La diferencia entre una función y un VI es que las funciones son objetos con una funcionalidad fija y sin Panel Frontal, mientras que los VI son programas hechos en LabVIEW por National Instruments u otros programadores que sí tienen Panel Frontal. Se puede acceder a un VI haciendo doble clic sobre él. Los VI disponibles están en librerías dentro del directorio %directorio de instalación de LabVIEW%\vi.lib.
Las funciones y VI generalmente operarán sobre una o varias entradas y proporcionarán una o más salidas. A las entradas se les conectará un dato del tipo requerido que puede provenir de un control, una constante o una salida de otro VI o función y a su salida se podrá conectar un indicador o una entrada de algún VI o función.

Figura 1-18. Función And.
1.2.4. Personalización de los menús
Las paletas de controles y de funciones pueden personalizarse y también se pueden añadir nuevos menús basados en VI creados por uno mismo o por otros programadores.
Cuando se crean menús nuevos, por convención, los VI y controles se guardan en %directorio de instalación de LabVIEW%\user.lib y los nuevos menús deben crearse dentro del submenú User Libraries y User Controls.
Para modificar el aspecto de las paletas hay que ir a Tools > Advanced > Edit Palette Set (Figura 1-19). Al hacerlo se abren las dos paletas principales y se puede navegar por ellas de forma normal, pero no se pueden arrastrar los VI y controles al Diagrama de Bloques y al Panel Frontal, sino que en cada VI y submenú aparece un menú desplegable con una serie de opciones que permiten añadir nuevos menús y VI, modificar iconos, hacer que cuando se usen no se añada el VI como subVI sino su código (Place VI Contents), etc.

Figura 1-19. Modificación del aspecto de paletas.
El esquema de los menús de las paletas se guarda en un fichero con extensión *.MNU. Una vez que se han realizado y guardado los cambios, ya están disponibles los nuevos menús y se podrán utilizar como cualquier menú nativo de LabVIEW.

Figura 1-20. Submenú de la librería de usuario.
También en Tools > Options > Control/Function Palettes hay varios parámetros para cambiar su aspecto. Por último hay que decir que si no se encuentra un VI entre todos esos menús o submenús también se dispone de la opción de buscar un VI o control por su nombre mediante el botón Search de la parte superior de las paletas.
Una opción avanzada y poco conocida es personalizar el menú Tools, para lo cual simplemente hay que guardar los programas que queramos que aparezcan en el directorio Project de la carpeta de instalación de LabVIEW.
1.3. Creación de programas
En LabVIEW la programación se realiza en el Diagrama de Bloques. Un programa habitualmente está formado por:
• Controles: sirven de entrada para los datos.
• Funciones, VI y estructuras: realizan una o varias operaciones con esos datos.
• Indicadores: sirven de salida para los datos.
Los datos ‘circulan’ por el programa mediante cables, que sirven para unir unos elementos con otros. Para realizar la conexión se utiliza la herramienta Connect Wire de la paleta de herramientas. Un cable tendrá una única fuente (control, constante o salida de otro elemento) y uno o varios destinos (indicador o entradas de otros elementos) de tipos compatibles. El cableado, en general, debe ser lo más corto posible manteniendo una claridad suficiente. Una opción útil que aparece en el menú contextual de los cables es Clean Up Wire que realiza un trazado automático de la ruta del cable. También se puede hacer un cableado automático de todo el diagrama en Edit > Clean Up Diagram. Un buen trazado del cableado no sólo es más elegante sino que también puede hacer que el programa tenga unas prestaciones superiores en cuanto a memoria utilizada, pero sobre todo será más fácil de mantener y modificar.
En la figura 1-21 puede verse un programa en LabVIEW. Consta de dos entradas, una de tipo string (String de entrada) y otra numérica (Número de entrada). La función String Length (puede encontrarse en el menú Programming > String de la paleta de funciones) obtiene el número de caracteres de la entrada de texto; esa cantidad es numérica y se suma a la otra entrada mediante la función Add (Programming > Numeric). El programa tiene dos salidas: la primera de ellas es una copia duplicada de la entrada tipo string, y la segunda es la suma de la longitud de la anterior más la entrada numérica. Los Label de ambas funciones se han mostrado mediante su menú contextual > Visible Items.

Figura 1-21. Programa sencillo en LabVIEW.
Una vez creado el programa, se deben introducir los datos iniciales en los controles del Panel Frontal, ejecutarlo presionando el botón Run (CTRL+R) y, cuando acabe, ver los resultados en los indicadores. La figura 1-22 muestra la ejecución del programa anterior.

Figura 1-22. Ejecución del programa anterior.
LabVIEW es un lenguaje compilado para obtener un alto rendimiento. Cuando un programa ha sido modificado y se va a guardar o ejecutar, generalmente se recompila. Al compilar el código del Diagrama de Bloques pasa a código máquina. El código compilado hará llamadas a otras funciones de librerías externas (LabVIEW Run-Time Engine) para tareas como dibujar gráficos o acceso a ficheros.
1.4. Flujo de ejecución
Al lenguaje de programación que usa LabVIEW también se le llama lenguaje G. La mayoría de los lenguajes se basan en una programación imperativa, que es simplemente una sucesión de operaciones. Sin embargo, el lenguaje G no usa una programación imperativa sino una ejecución basada en el flujo de datos (dataflow).
Un programa en LabVIEW consiste básicamente en una serie de funciones unidas mediante cables. Los datos ‘circulan’ o ‘fluyen’ por los cables. Una función sólo podrá ejecutarse cuanto tenga disponibles todos los datos que le sirven como entradas. Esta forma de ejecutar un programa favorece el paralelismo y es más apropiada para sistemas multiprocesador y multihilo, y también es más parecida al funcionamiento de los circuitos hardware e incluso al lenguaje VHDL.
A continuación se mostrarán una serie de imágenes para explicar el flujo de ejecución de LabVIEW mediante un ejemplo.
El programa consiste en dos operaciones matemáticas: la suma de dos números y la multiplicación del resultado de ésta por un tercer número. En la figura 1-23 se puede ver el programa y los datos de entrada en el Panel Frontal.

Figura 1-23. Programa para analizar el flujo de ejecución.
El primer paso de la ejecución llevará los datos de los controles Operando A, Operando B y Operando C a las entradas de las funciones Add y Multiply. En la figura 1-24 puede verse que las entradas disponibles están marcadas con un punto. El flujo de datos se indica con flechas en paralelo a los cables.

Figura 1-24. Valores disponibles en las entradas de la función Add.
La función Add tiene disponibles los valores de sus dos entradas; sin embargo, la función Multiply necesita el valor de otra entrada que no tiene disponible. Por lo tanto, en el siguiente paso se podrá ejecutar la función Add pero no Multiply. Cuando se ejecute el resultado de la suma, su valor pasará al indicador A+B, que lo mostrará en el Panel Frontal, y también circulará hasta la entrada que faltaba de la multiplicación, lo que permite que en el siguiente paso pueda ejecutarse.

Figura 1-25. Siguiente paso de la ejecución.
Finalmente, el resultado de la multiplicación pasa al indicador (A+B)*C y el programa finaliza.
En el ejemplo anterior el orden de ejecución es fijado por la forma de cablear unas funciones con otras. En la figura 1-26 pueden verse dos programas. En el primero ocurre lo mismo; el orden de ejecución lo fija el cableado: primero se ejecutará Increment y después Square Root. En el segundo programa hay dos funciones pero entre ellas no existe ninguna dependencia de datos, por lo que no habrá ningún orden en la ejecución de Decrement y Square; podemos considerar que ambas se ejecutan en paralelo.

Figura 1-26. Flujo de ejecución.
1.5. VI y subVI
Los ficheros con los programas creados en LabVIEW se llaman VI (Virtual Instrument). En muchas ocasiones un programa será de un tamaño tal que habrá que separarlo en varios ficheros o habrá alguna sección de código que convenga reutilizarla varias veces. Un VI puede contener a otro de forma que el segundo sería un subVI del primero; el concepto es equivalente a las funciones o procedimientos de un lenguaje tradicional.

Figura 1-27. Programa que utiliza diferentes funciones.
En el ejemplo de la figura 1-27 puede verse un programa que tiene como entradas Límite superior y Límite inferior. Estas entradas se limitan de forma programada a 360 y 0 respectivamente mediante las funciones de comparación Less?, Greater? y Select. A las salidas de las funciones de comparación se obtendrá un valor TRUE si la comparación es cierta y FALSE en caso contrario. Select funciona como un multiplexor: a su salida estará el valor de la entrada superior (T) si la señal de selección (?) es cierta, y el de la entrada inferior (F) si es falsa. Por otra parte, Random Number (0-1) genera un número aleatorio entre cero y uno.
La parte central del programa resta las dos entradas y el resultado lo multiplica por la suma del límite inferior y el número aleatorio. Con esto se consigue generar un número aleatorio comprendido entre los dos límites indicados, que nunca serán mayores de 360 y menores de 0.
Finalmente, este número generado se empleará como el valor de un ángulo en coordenadas polares, y de él se obtendrá la parte real e imaginaria.
En el ejemplo anterior puede ser deseable hacer una función que se encargue de la generación del número aleatorio entre dos límites, es decir, hacer que esa parte del código sea un VI distinto, de forma que pueda ser usado en otras ocasiones. La forma más sencilla de conseguir esto es seleccionando la parte deseada del Diagrama de Bloques e ir a Edit > Create SubVI. Al hacerlo, el código seleccionado será sustituido por el icono de un VI. Con un doble clic sobre este icono se accederá al código de este subVI.

Figura 1-28. Crear un subVI seleccionando una parte del programa.
Otra forma de crear un VI es definiendo de forma manual su interfaz. La interfaz es la forma en que se realizarán las conexiones cuando se use como subVI dentro de otro VI. El primer paso será guardar el VI, después situarse en su Panel Frontal y hacer clic con el botón secundario del ratón sobre el icono del VI (parte superior derecha) para desplegar su menú contextual, como se puede ver en la figura 1-29. En el menú contextual se mostrará el conector, que es el equivalente a la cabecera de las funciones en otros lenguajes. En el conector se podrán añadir o eliminar terminales, que son los lugares donde se conectarán los cables cuando se use como subVI. Para asignar un control o indicador a un Terminal, se debe seleccionar la herramienta Connect Wire y hacer clic en el terminal y en el control o indicador asociado del Panel Frontal. En ese momento el terminal se coloreará indicando el tipo de datos.
Por claridad se recomienda conectar las entradas a la izquierda y las salidas a la derecha. También se puede indicar si la conexión de un terminal debe ser obligatoria (Required), normal (Recommended) u opcional (Optional). En la ventana de ayuda contextual los terminales se mostrarán en negrita, de forma normal u ocultos respectivamente. Si en el Panel Frontal se había indicado algún valor por defecto en alguna entrada, éste será el valor que tenga el control si no se le conecta un cable cuando se use como subVI. Como regla de estilo podemos recomendar que se indique el valor por defecto en el Label de cada control al final entre paréntesis.
Además del terminal, también se puede crear un icono que represente al VI cuando se coloque en el Diagrama de Bloques de otro VI. En la ventana de la figura 1-30, aparecen en la parte izquierda diferentes pestañas con las diversas opciones para hacer el dibujo, y a la derecha el icono y una barra de herramientas típica de un programa de edición de imágenes.

Figura 1-29. Creación del terminal de un subVI.
Esta herramienta se ha mejorado desde la versión 2009. Entre las nuevas mejoras destaca el empleo de capas (pestaña Layers), de plantillas (Templates) y de imágenes prediseñadas (Glyphs).
Dentro de las plantillas podemos hacer que el icono de un VI sea rectangular en lugar de cuadrado. Esto se suele utilizar cuando únicamente hay una en trada o una salida. Yendo un paso más allá, podemos hacer cualquier forma al icono, como triángulos, borrando todo el contenido en el icono fuera del contorno que queramos darle.
Si se está creando una librería o familia de subVI, es conveniente dar a todos un estilo parecido. Para ello, se pueden usar las plantillas que vienen por defecto o crear y emplear nuestras propias plantillas e imágenes prediseñadas (File > Save as > Template).
Por último, hay que decir que puede accederse a opciones especiales haciendo doble clic sobre algunas herramientas, como seleccionar el tipo de letra con doble clic sobre la herramienta de texto, seleccionar todo con la de select o sobre el dibujo del cuadrado.

Figura 1-30. Editor del icono de un VI.
Desde el menú contextual del icono o desde File > VI Properties se accederá a las propiedades del VI, en las que se podrá ver información y modificar parámetros del VI como:
• General: información sobre la versión, cambios sin salvar, etc.
• Memory Usage: espacio que ocupan las distintas partes que componen el VI.
• Documentation: información sobre el VI. Al usarlo como subVI aparecerá en la ventana de ayuda contextual y un enlace a un fichero de ayuda en el que se podría ampliar la información.
• Revision History: configuración e información sobre el historial del VI.
• Editor Options: algunos parámetros que afectan a la hora de crear el VI.
• Protection: permite bloquear y/o proteger con contraseña el código del fichero.
• Window Appearance: configuración de la ventana que mostrará el Panel Frontal al usuario cuando el VI se ejecute.
• Window Size: tamaño de la ventana del programa cuando se ejecute.
• Window Run-Time Position: posición de la ventana del programa cuando se ejecute.
• Execution: afecta a la forma de ejecución de un VI; para más información consultar el tema acerca de multihilo.
• Print Options: configura la forma en que se imprimirá un VI.
Una vez creado el VI, el siguiente paso será usarlo. Para insertar un VI dentro de otro se puede usar el método de arrastrar y soltar desde el directorio donde esté almacenado hasta el Diagrama de Bloques del VI. También se puede usar Select a VI… desde la paleta de funciones o colocar el VI dentro de un menú de la paleta de funciones.
Como puede verse en las propiedades de un VI (File > VI Properties > Memory Usage), internamente un VI se compone de un espacio de datos, el código compilado, el Panel Frontal y el Diagrama de Bloques. Al cargar un VI se llevará a memoria el espacio de datos y el código compilado; el Panel Frontal y el Diagrama de Bloques se cargarán cuando LabVIEW lo considere necesario.
1.5.1. Librerías
Cada VI se guardará como un fichero. Para agrupar varios VI se puede emplear una librería, la cual es otro fichero con extensión *.LLB. Hay varios métodos para crear una librería:
• En un fichero nuevo, File > Save as > New LLB.
• En Tools > LLB Manager > File > New LLB.
También se puede convertir un directorio que contenga VI en una librería y viceversa desde Tools > LLB Manager (Figura 1-31). Después se debe seleccionar el directorio o librería deseado y se elige Edit > Convert. La ventaja de las librerías es que, a la hora de distribuir una aplicación, todos los ficheros necesarios pueden estar empaquetados en un único archivo.
Desde el LLB Manager se podrá marcar uno o varios VI como Top Level, lo que provoca que, cuando la librería se abra desde la línea de comandos, se abra directamente el VI ‘principal’. Una vez creada la librería, se podrá trabajar con ella desde LabVIEW como si fuera un directorio más, pero para el sistema operativo será sólo un fichero.


