Kitabı oku: «Programación gráfica para ingenieros», sayfa 3

Yazı tipi:

2.5 Proyectos

A partir de la versión 8.0 de LabVIEW se introduce la posibilidad de crear proyectos para gestionar de forma más eficiente las aplicaciones complejas desarrolladas en este entorno. El proyecto se almacena en un fichero XML con extensión .lvproj que contiene información de todos los ficheros incluidos en el proyecto. Estos ficheros pueden ser VIs, controles, ficheros de configuración, de documentación o cualquier otro archivo que el programador desee incluir.

Los proyectos se gestionan desde el Explorador de Proyectos (Project Explorer), que presenta, en forma de árbol desplegable, una categoría principal denominada My Computer, que incluye los ficheros que componen el proyecto y sus propiedades. Además de esta categoría derivan siempre otras dos:

 Dependencies, que muestra las dependencias del proyecto (por ejemplo, librerías compartidas).

 Build Specifications, que recoge la información para las distribuciones del proyecto (ejecutables, librerías, instaladores, etc.).


Figura 2.10. Explorador de Proyectos (Project Explorer).

Los ficheros de un proyecto se pueden agrupar en directorios o librerías que a su vez incluyen otros VIs (no confundir con las librerías .llb). Las librerías de un proyecto no contienen físicamente a los distintos VIs que la componen, sino que representan referencias a los mismos. Los ficheros de una librería pueden ser públicos (accesibles desde cualquier parte del proyecto) o privados (sólo accesibles desde otros VIs de esa misma librería).

3. Programación Estructurada y Tipos de Datos
3.1 Introducción

Todo programa requiere de una serie de instrucciones que permiten la ejecución condicional o repetitiva de su código. En el entorno de programación LabVIEW, este tipo de instrucciones se denominan estructuras e incluyen en su interior, de forma gráfica, el código a ejecutar de manera repetitiva o condicional.

3.2 Estructuras en LabVIEW

Las estructuras disponibles para la programación de instrumentos virtuales en LabVIEW se encuentran disponibles en la paleta de funciones del diagrama de bloques dentro de la categoría Programming » Structures, tal como se muestra en la Figura 3.1. A continuación se describe con detalle cada una de estas estructuras.


Figura 3.1. Estructuras de la paleta de funciones.

3.2.1 Estructuras iterativas

Podemos encontrar dos tipos de estructuras iterativas, también llamadas estructuras de ciclos o bucles: While Loop y For Loop, que analizaremos a continuación.

3.2.1.1 Bucle While (While Loop)

El bucle while repite el código que tenga en su interior hasta o mientras se cumpla una condición, que se evalúa en cada iteración (véase la Figura 3.2). Esta estructura dispone de dos terminales:

a) El terminal de iteración . En cada iteración del bucle aumenta su valor una unidad, empezando a contar desde cero.

b) El terminal condicional . El ciclo se repite hasta que recibe un valor booleano de verdadero o falso. A través del menú contextual (clic sobre el botón derecho del ratón), podrá elegirse que el bucle se detenga cuando el valor booleano sea verdadero (Stop if True ) o que continúe mientras sea verdadero (Continue if True ).


Figura 3.2. Estructura While Loop.

Los terminales de cualquier función suelen permitir, además de sus funciones específicas, una serie de funciones adicionales como crear constantes, controles o indicadores. Para ello se puede emplear su menú contextual (pulsando con el botón derecho del ratón sobre el objeto en el diagrama de bloques o bien utilizando la herramienta Object Shortcut Menu).

A continuación se presenta las principales opciones del menú contextual del bucle (véase la Figura 3.3):

Visible Item: oculta o visualiza la etiqueta de identificación.

Description and Tip: permite añadir comentarios.

Set Breakpoint: establece un punto de ruptura para depurar el VI.

Replace: cambia el bucle por For Loop, Timed Loop o por cualquier otra función con la opción paleta de estructuras (Structures Plette).

Remove Loop: borra la estructura pero sin eliminar el código de su interior.


Figura 3.3. Menús contextúales de la estructura While Loop (clic botón derecho del ratón).

La opción Add Shift Register (registro de desplazamiento), añade dos terminales a cada lado de la estructura. Estos terminales sirven para transferir un valor desde una iteración del bucle a la siguiente o, visto de otro modo, tener acceso a un valor de una iteración anterior.


Figura 3.4. Registro de desplazamiento (Shift Register) en un bucle While.

Tal como se muestra en la Figura 3.4, en la primera iteración se leerá el valor 15 en el terminal de la izquierda, se le sumará 1 y se escribirá en el terminal de la derecha el valor 16. Este valor será leído en la siguiente iteración y se le volverá a sumar 1, repitiéndose este proceso hasta que sea igual o mayor a 20. En este momento recibirá un valor verdadero el terminal condicional (Stop if True) y se terminará el ciclo.

El Feedback Node, presente en la misma paleta de estructuras funciona de forma similar al Shift Register. Consta de dos terminales:

a) El terminal inicializador, situado sobre el borde izquierdo de la estructura, proporciona el valor inicial al nodo.

b) El terminal Feedback Node, con forma de flecha, es el encargado de trasladar el valor leído a la siguiente iteración.

En la Figura 3.5 se muestra un ejemplo de empleo del Feedback Node para realizar la misma función que en el ejemplo de la Figura 3.4.


Figura 3.5. Ejemplo de utilización de Feedback Node.

La entrada o salida de datos a un While Loop se hace a través de túneles, que se crean de forma automática en los laterales cuando son cruzados con el cableado. Dichos túneles se muestran mediante un cuadrado. Por defecto, un túnel de salida en un bucle while proporcionará, una vez finalizado el bucle, el valor correspondiente a la última iteración. Existe la opción de modificar el comportamiento de un túnel de salida mediante su menú de contexto asociado (botón derecho de ratón) mediante la opción Enable Indexing, en cuyo caso se proporcionará un array con todos los valores generados durante las sucesivas iteraciones del bucle. Este comportamiento se estudiará con más detalle en el apartado de Arrays.

La Figura 3.6 ilustra un ejemplo de las alternativas en la utilización de túneles. En el borde derecho de la estructura hay tres túneles. El primero no tiene habilitada la característica de indexado, por lo que en el indicador Túnel: último valor se mostrará el último valor generado una vez finalizado el bucle. En el indicador Shift Register se mostrará el mismo valor. El tercer túnel tiene habilitado el indexado, por lo que proporcionará a su salida un array con todos los valores generados en las sucesivas iteraciones. Por ello el tercer indicador es de tipo array.


Figura 3.6. Ejemplo de utilización de túneles en bucle while.

3.2.1.2 Bucle For (For Loop)

El bucle For (For Loop) repite el código ubicado en su interior un número de veces que se fija inicialmente. Este número de iteraciones no se podrá modificar en su interior. Dispone de dos terminales:

a) El terminal de iteración , similar al indicado para el bucle While Loop.

b) El terminal de conteo permite fijar el número de repeticiones del bucle. Se simboliza con la letra “N” y está ubicado en la esquina superior izquierda.


Figura 3.7. Estructura For Loop.

En este bucle también se emplea Shift Register y Feedback Node del mismo modo que se ha explicado para el bucle While Loop. Los menús contextuales son también muy similares, al igual que el empleo de túneles.

3.2.1.3 Funciones de Temporización en Estructuras

Con frecuencia es necesario temporizar la ejecución de una estructura iterativa. Las funciones ilustradas en la Figura 3.8, disponibles en Timing de la paleta de funciones, permiten temporizar el tiempo de ejecución de ambos bucles.


Figura 3.8. Funciones de temporización.

La función Wait introducirá un retardo especificado en milisegundos, mientras que la función Time Delay lo hará en segundos a través de su terminal de entrada Delay Time (s). La función Wait Until Next ms Multiple introduce una espera hasta que el reloj del sistema sea múltiplo del valor asignado a su terminal de entrada millisecond multiple. De este modo se garantiza un retardo de ejecución del bucle con un período fijo de tiempo. En todos los casos, el retardo se puede especificar mediante una constante en el diagrama de bloques, un control en el panel frontal o cablearse al resultado de otras funciones dentro del bucle. La Figura 3.9 muestra un ejemplo de bucle for con temporización. El bucle se ejecutará diez veces, con una iteración cada 100 milisegundos (especificados mediante la constante conectada al terminal de entrada de la función Wait Until Next ms Multiple). En cada iteración se genera un número aleatorio entre 0 y 1 (función Random Number (0-1)), se muestra en el indicador number (0-1) y se produce la espera hasta que el reloj del sistema llegue al próximo múltiplo de 100 ms.


Figura 3.9. Ejemplo de temporización en un bucle For.

3.2.2 Estructuras de casos y eventos

Estas estructuras se caracterizan por contener varios subdiagramas, de los cuales sólo uno se ejecuta en función de una condición. Además, sólo uno de los subdiagramas es visible en cada momento.

3.2.2.1 Estructuras de casos (Case Structure)

Permite ejecutar el código correspondiente a cada uno de sus subdiagramas en función de la condición seleccionada y puede utilizarse para dos o más condiciones. Es por tanto equivalente a sentencias de tipo if o switch en lenguajes de programación textuales.

Tal como ilustra la Figura 3.10, esta estructura incluye un identificador y un terminal selector:

 El identificador se ubica en la parte superior, formado por un menú desplegable, donde se muestran los distintos Casos. Su selección permite ver y editar el subdiagrama a ejecutar para cada caso. Desde el menú de contexto se pueden añadir nuevos casos y eliminar o duplicar los existentes. El orden de los subdiagramas se puede modificar con la opción Rearrange Case.

 El terminal selector está ubicado en el lateral izquierdo con el símbolo “?”. Se encarga de evaluar la condición que le llega para seleccionar el subdiagrama a ejecutar.

Los datos que se pueden conectar al selector del Case son los siguientes:

 Booleano: actuará como una sentencia if..then..else en un lenguaje textual. El selector booleano sólo podrá tomar los valores verdadero o falso (True, False). Si se cumple la condición verdadera se ejecutará el código correspondiente al subdiagrama True, y si no, la correspondiente al subdiagrama False.

 Numérico: la condición será que el número del selector sea igual al mostrado en el menú del Case. Cuando queramos ejecutar el mismo código para un rango de valores deberemos escribirlos separados por comas en el menú del Case, por ejemplo “3, 4, 5, 6”. Se debe utilizar números enteros (control numérico azul). Para datos enum o ring se puede escribir el nombre del ítem en lugar del valor numérico.

 String: se diferencia del numérico en que el menú desplegable del identificador se utilizará texto encerrado entre comillas. La condición será que el texto sea igual al del selector. Se puede conectar un String Control o un Combo Box de la subpaleta String & Path de la paleta de Controles del Panel Frontal.

 Cluster de Error (Error Cluster): actúa del mismo modo que con un booleano, y la condición será que la variable Status del cluster de error sea verdadera. Dispone de dos subdiagramas: Error y No Error.

Dependiendo de que el tipo de dato que se le conecte al selector sea booleano, String o numérico, éste tomará un color verde, magenta o azul, respectivamente.

Cuando el selector se conecta a un String o a un dato numérico es obligatorio disponer de un caso que se ejecute por defecto. Se puede realizar escribiendo en el identificador una coma y seguido Default o seleccionando Make This The Default Case en el menú contextual. Al igual que con las estructuras iterativas, se pueden pasar datos a través de túneles.


Figura 3.10. Ejemplos de uso de la estructura Case con distintos tipos de datos para la condición.

3.2.2.2 Estructura de eventos (Event Structure)

Es una estructura similar a la de casos (véase la Figura 3.11). Permite ejecutar una u otra parte del código, en función de diferentes eventos relacionados con nuestra aplicación, tales como clics o movimientos del ratón, de ventanas para maximizar o minimizar, pulsación de teclas, etc.


Figura 3.11. Estructura de eventos (Event Structure).

Durante la ejecución, se espera a que se produzca un evento, y entonces se ejecuta el subdiagrama que se le haya asociado. Esta estructura tiene siempre un evento por defecto: el Timeout. Asociado a este evento, en la esquina superior izquierda aparece un término denominado Event Timeout que se utiliza para asignar el tiempo en milisegundos para el cual se produce su ejecución. El valor por defecto para este terminal es de -1 (nunca se produce timeout).

Del mismo modo que la estructura Case, dispone de varios subdiagramas y un identificador en la parte superior. En este identificador se muestra la condición que produce la ejecución de su subdiagrama asociado. Los subdiagramas se gestionan del mismo modo que en la estructura Case (añadir, eliminar, duplicar, etc.). Los eventos se configuran mediante la ventana Edit Events (menú de contexto » Edit Events Handled by This Case …, o al añadir nuevos casos), tal como se muestra en la Figura 3.12.

En la lista de eventos predefinidos existen dos tipos:

 Los marcados con una flecha verde, sin interrogación al final.

 Los marcados con una flecha roja, terminados en interrogación y con el mismo nombre que los anteriores. Estos eventos funcionan como filtros (Filter Event) y se evalúan antes de la acción asociada al evento. Además, pueden desactivar el evento utilizando el terminal Discard? que aparece. En la Figura 3.13 se muestra una estructura de este tipo que evita que el usuario cierre el panel frontal.

En la parte izquierda de cada subdiagrama de esta estructura se muestran los terminales Event Data Node que proporcionan información relacionada con el evento como, por ejemplo, una referencia al control o el tipo de evento.

Cuando se utilicen este tipo de estructuras, hay que tener en consideración algunas recomendaciones:

 La estructura de eventos debe utilizarse dentro de un bucle while loop.

 No debe utilizarse una estructura de eventos dentro de otra.

 Si la estructura de eventos está dentro de un bucle while y éste contiene un control de Stop de tipo latch (comportamiento mecánido del control), la estructura de eventos debe contener un caso asociado al cambio de valor de dicho control.Figura 3.12. Cuadro de diálogo de edición de eventos.Figura 3.13. Ejemplo de uso de Filter Event.

 Los cambios de valor en los controles del panel frontal sólo generan eventos cuando el cambio se produce en la interfaz de usuario, pero no cuando se alteran mediante el programa (utilizando, por ejemplo, variables locales).

3.2.3 Estructuras de secuencia (Flat Sequence y Stacked Sequence)

En un lenguaje textual, las instrucciones del programa se ejecutan secuencialmente en el orden en que aparecen. En LabVIEW, una función se ejecuta cuando tiene disponible todos los datos de entrada.

Cuando sea necesario que un subdiagrama se ejecute antes que otro se debe utilizar una estructura de secuencia. Cada subdiagrama estará contenido en un frame o marco, y éstos se ejecutarán en el orden de aparición. Existen dos estructuras de secuencia: Flat Sequence y Stacked Sequence, tal como se muestra en la Figura 3.14.


Figura 3.14. Estructuras Flat Sequence (izquierda) y Stacked Sequence (derecha).

Flat Sequence funciona de igual forma que Stacked Sequence, sólo que es más visual. Su diseño recuerda a los fotogramas de una película. Los frames se ejecutan uno tras otro, siguiendo el orden de izquierda a derecha. Los datos pueden cablearse directamente desde un frame a otro a través de túneles.

Stacked Sequence tiene un menú en la parte superior donde se indica la numeración del frame que se muestra, el número total de frames que contiene y además da la opción de situarse en otro. Para crear túneles entre un frame y los demás, es necesario utilizar la opción Sequence Local del menú contextual.

Presionando con el botón derecho del ratón en el borde de ambas estructuras, aparece un menú contextual que permite crear frames, editar, borrar, cambiar el tipo de secuencia, etc.

3.2.4 Estructuras temporizadas. Timed Loop y Timed Sequence

Las estructuras temporizadas aparecieron en la versión 7.1 de LabVIEW con el objetivo de ser utilizadas en aplicaciones de tiempo real.

La estructura Timed Loop repite el código ubicado en su interior con unas condiciones temporales hasta que se cumple una determinada condición (véase la Figura 3.15). Está disponible en el diagrama de bloques (Functions » Programming » Structures » Timed Structures) y su representación es similar a la de un while loop rodeado de un borde azul. A diferencia del bucle while en un Timed Loop no es necesario establecer una condición de parada o continuación. Además, incluye varios nodos que pueden extenderse/contraerse para mostrar más o menos datos. Éstos son:

 El nodo de entrada a la izquierda, fuera del bucle. Permite configurar los parámetros temporales del bucle bien mediante un asistente, bien cableando los terminales de datos.

 Nodo de salida a la izquierda, dentro del bucle. Proporciona información sobre la iteración anterior: si se ha producido error (Error), tiempo esperado y real de finalización (Expected End[i-1], Actual End[i-1]), si se ha finalizado a tiempo (Finished Late?[i-1]), etc.

 Nodo de entrada a la derecha, dentro del bucle. Permite modificar de manera dinámica los parámetros de tiempo de la estructura para la siguiente iteración. Estos parámetros son los mismos que los del nodo de entrada externo al bucle, a excepción del nombre del bucle y de la fuente de reloj.

 Nodo de salida a la derecha, fuera del bucle. Proporciona información del bucle una vez que ha finalizado su ejecución.Figura 3.15. Estructura Timed Loop.

La configuración en los nodos de entrada se puede realizar cableando valores a sus terminales o bien haciendo doble click sobre ellos, en cuyo caso se muestra un cuadro de diálogo de configuración como el que se muestra en la Figura 3.16. A continuación se describen los parámetros de configuración más importantes:

 Fuente de reloj (Loop Timing Source). Dependiendo de la plataforma hardware sobre la que se esté ejecutando la aplicación, se podrán seleccionar diferentes fuentes de reloj (Timing Source). En el caso particular de un ordenador personal, esta fuente será un reloj de 1KHz del sistema operativo. La fuente de reloj también se puede crear externamente al Timed Loop en el diagrama de bloques mediante el VI Creat Timing Source (Programming »Structures » Timed Structures) y cablearlo al terminal de fuente de reloj. En la paleta Timed Structures se dispone de otras funciones para la sincronización de Timed Loops (Syncronize Timed Structure Starts) o para establecer el inicio de cada una de las estructuras (Buiding Timing Source Hierarchy).


Figura 3.16. Cuadro de diálogo de configuración de Timed Loop.

 Period. Es el intervalo de tiempo entre el inicio de una iteración y la siguiente.

 Priority. Establece la prioridad de ejecución de un bucle respecto a los demás. Un mayor valor corresponde a mayor prioridad.

 Offset. Tiempo que el bucle espera antes de iniciar la primera ejecución.

 Deadline. Tiempo máximo de que dispone el bucle para ejecutar el código alojado en su interior. Si la ejecución no se realiza en dicho tiempo el terminal Finished Late[i-1]? tomará valor True.

 Action on Late Iterations. Permite configurar cómo se debe comportar el bucle cuando la ejecución del código supone más tiempo del establecido. Se pueden saltar iteraciones (Discard missed periods) o bien volver a sincronizar la siguiente iteración con el período (Maintain original phase).

Además, es posible añadir frames a un Timed Loop mediante la opción Add Frame After o Add Frame Before del menú de contexto que aparece al hacer clic con el botón derecho del ratón sobre su marco. Cada uno de los subdiagramas se ejecutará de forma secuencial con sus propias especificaciones temporales. Si se modifican los parámetros temporales en el nodo derecho del primer subdiagrama, dichos parámetros serán los utilizados en el segundo.


Figura 3.17. Utilización de varios frames en una estructura Timed Loop.

La estructura Timed Sequence presenta las mismas características en cuanto a su comportamiento temporal. La única diferencia es que no se repite la ejecución de sus subdiagramas, por lo que no se especifica el periodo y no tiene condición de parada/continuación, tal como se ilustra en la Figura 3.18.


Figura 3.18. Estructura Timed Sequence.

Türler ve etiketler

Yaş sınırı:
0+
Hacim:
398 s. 298 illüstrasyon
ISBN:
9788426720665
Yayıncı:
Telif hakkı:
Bookwire
İndirme biçimi: