Una aplicación de LabVIEW bien diseñada es esencial para maximizar la eficiencia cuando se trata de desarrollo de software y mantenimiento. Este documento presenta construcciones básicas, patrones de diseño y arquitecturas relacionadas específicamente con el diseño de software en LabVIEW. Este contenido no es extenso, pero proporciona un punto de partida útil con algunos de los elementos de diseño de software de LabVIEW más comunes. Siga los enlaces en el documento para obtener información más detallada.
Cada una de las siguientes secciones describe una construcción común utilizada en la programación de LabVIEW para realizar una tarea específica. Estar familiarizado con estas construcciones básicas lo ayudará a reconocer y comprender más fácilmente su uso en una aplicación de LabVIEW.
Las definiciones de tipo (a menudo abreviadas como "typedefs") le permiten especificar un tipo de datos que se definirá de manera consistente en toda su aplicación. Por ejemplo, aquí hay una definición de tipo de clúster:
Cuando arrastra esta typedef en un panel frontal o un diagrama de bloques, aparecerá como un clúster, pero con un triángulo negro en la esquina superior izquierda en sus terminales y constantes:
Typedefs son extremadamente útiles para definir tipos consistentes en su aplicación. Para ilustrar esto, observe lo que sucede si agregamos un nuevo parámetro (en este caso, una ruta de configuración) a la typedef:
Al modificar la typedef en una sola ubicación (el archivo fuente typedef .ctl), este cambio se propaga automáticamente a toda la aplicación:
Si el clúster no fuera un typedef, entonces todas las instancias del clúster (en los paneles frontales y diagramas de bloques) en toda su aplicación deberían actualizarse manualmente. Con raras excepciones, debe escribir typedef en todos los clústeres y enums que usted crea al escribir sus aplicaciones de LabVIEW .
Al usar typedefs, mejora la capacidad de mantenimiento de su código al utilizar tipos de datos compartidos de una sola fuente.
La estructura de eventos proporciona la capacidad de responder a eventos de la interfaz de usuario y eventos programáticos en un diagrama de bloques de LabVIEW . Por ejemplo, puede registrarse para que se ejecute un diagrama de eventos cuando cambie un valor de control del panel frontal. También puede registrarse para eventos que se generan de manera programática en un diagrama de bloques con la función Generate User Event.
Una estructura de eventos generalmente se coloca dentro de un ciclo While para que el código pueda responder a múltiples eventos durante la ejecución del código. Configure la estructura de eventos para tener diferentes marcos para los diferentes eventos que desea detectar. Cada marco de evento contiene el código de manejo que se ejecuta cada vez que ocurre ese evento.
Explore los siguientes proyectos que se incluyen con LabVIEW para ver varios ejemplos que ilustran eventos de la interfaz de usuario y eventos programáticos:
La variable global funcional (también conocida como "FGV", "LabVIEW 2 Style global" o "Action Engine") es un mecanismo de almacenamiento de datos. La FGV almacena datos en un registro de desplazamiento no inicializado o en un nodo de retroalimentación no inicializado y le permite tener acceso a esos datos en cualquier lugar (ej. "globalmente") dentro de una aplicación. El diagrama de bloques de un FGV VI básico se muestra a continuación y contiene Data in y Data out, junto con un enum Operation con dos acciones ("Set" y "Get"):
La funcionalidad proporcionada por esta simple FGV get/set es equivalente a usar una variable global. En la práctica, su FGV probablemente realizará funciones adicionales además de "set" y "get".
Puede utilizar la FGV para almacenar referencias y realizar operaciones más sofisticadas. Por ejemplo, observe la FGV de E/S de archivo a continuación (que ilustra el uso de un registro de desplazamiento no inicializado en lugar de un nodo de retroalimentación). Esta FGV almacena la referencia del archivo entre llamadas sucesivas y realiza varias acciones distintas (Open, Read, Write y Close) dentro de un solo VI.
Tenga en cuenta que las FGV son tan susceptibles a las condiciones de carrera como las variables globales. Como regla general, debe evitar escribir en datos globales en más de un lugar en su código.
Un subpanel es un control del panel frontal que puede mostrar el panel frontal de otro VI. Usar un subpanel le permite diseñar una interfaz de usuario dinámica en la que puede intercambiar secciones enteras de su IU especificando un VI diferente para mostrar en el subpanel. El subpanel también fomenta el desarrollo de aplicaciones modulares, donde las agrupaciones lógicas de elementos del panel frontal pueden estar contenidas dentro de VIs separados. Con este diseño, usted puede modificar VIs individuales que se muestran dentro de los subpaneles sin cambiar el código de otros VIs de pantalla o del VI de la aplicación principal.
El siguiente ejemplo escanea una carpeta en busca de VIs complementarios y llena un anillo de texto con esos complementos. Cuando usted selecciona un elemento en el anillo de texto, el VI complementario correspondiente se inserta en el subpanel en el VI principal. Esta construcción le permite agregar nuevos VIs complementarios en el disco sin realizar ningún cambio en el VI principal.
Ejecute el siguiente ejemplo que se incluye en LabVIEW para experimentar más con los subpaneles:
Por defecto, los VIs en LabVIEW no son reentrantes. Esto simplemente significa que solo se puede ejecutar una instancia de un VI a la vez. Entonces, en el siguiente diagrama, una de las instancias de subVI del 'Process.vi' debe esperar hasta que la otra termine.
Si desea que varias instancias de un VI puedan ejecutarse en paralelo, debe hacer que el VI sea reentrante. Para hacer esto, vaya a File > VI Properties > Execution y cambie la configuración de 'Reentrancy' a Ejecución de Shared clone reentrant execution o Preallocated clone reentrant execution.
Una vez que cambie un VI para que sea reentrante, se pueden ejecutar varias instancias en paralelo:
Considere hacer que sus VIs sean reentrantes en los siguientes escenarios:
Tenga en cuenta que las variables globales funcionales casi siempre serán no reentrantes porque mantienen datos de estado global que toda su aplicación necesita compartir.
Ejecute el siguiente ejemplo que se incluye en LabVIEW para experimentar con VIs reentrantes:
La mayoría de las veces que llama a un VI desde otro VI, utilizará una llamada subVI normal. Al llamar a un subVI, el diagrama de llamada debe esperar hasta que el subVI haya terminado de ejecutarse antes de que pueda continuar. Este es un ejemplo de llamada síncrona.
Sin embargo, en algunas situaciones, una aplicación puede requerir que usted inicie un subVI, pero continúe con la ejecución del VI que llama mientras el subVI continúa ejecutándose. Este es un ejemplo de una llamada asincrónica. Con las llamadas de VI asincrónico, usted puede ejecutar dinámicamente cualquier número de VIs en paralelo. Además, el uso de VIs reentrantes le permite generar un número arbitrario de instancias del mismo VI y dejar que se ejecuten asincrónicamente.
En el siguiente ejemplo, el VI de llamada, llama asincrónicamente a varias instancias del Process.vi reentrante. Cada VI se ejecuta de manera independiente y devuelve datos al VI de llamada cuando ha terminado. El VI de llamada puede ejecutar otro código de diagrama de bloques en paralelo y no esperar a que finalicen las instancias del VI de proceso.
Explore el siguiente proyecto que se incluye en LabVIEW para ver varios ejemplos que ilustran más detalles sobre las llamadas de VI asincrónico:
La programación orientada a objetos se facilita en LabVIEW a través de las clases de LabVIEW. La programación orientada a objetos de LabVIEW usa conceptos de otros lenguajes de programación orientados a objetos como C++ y Java, incluyendo estructura de clases, encapsulación y herencia. Puede usar estos conceptos para crear código que sea más fácil de mantener y modificar sin afectar otras secciones del código dentro de la aplicación. Hay muchos patrones de diseño orientado a objetos que se pueden aplicar a LabVIEW. Estos se describen en el documento Applying Common Object-Oriented (OO) Design Patterns to LabVIEW.
Explore los proyectos en la siguiente carpeta que se incluyen en LabVIEW para ver varios ejemplos que ilustran los conceptos básicos de la programación con las clases de LabVIEW:
Un patrón de diseño es un mecanismo teórico para ejecutar código sincrónico o asincrónico. La mayoría de las arquitecturas del mundo real (consulte la sección a continuación) utilizan uno o más patrones de diseño como parte de su mecanismo de ejecución principal. Comprender el comportamiento de los patrones de diseño en esta sección puede ayudarlo a comprender mejor el comportamiento de arquitecturas más complejas construidas en base a estos patrones de diseño.
Una máquina de estado es la implementación del diagrama de bloques de LabVIEW de un diagrama de estado o diagrama de flujo. Un "estado" dado tendrá una lógica de diagrama de bloques para determinar el siguiente estado a ejecutar. Algunas máquinas de estado son controladas por una interfaz de usuario, en la que la instrucción del usuario o la lógica del diagrama de bloques pueden determinar qué estado se ejecutará a continuación.
Una máquina de estado básica de LabVIEW consta de estos componentes principales:
Explore el siguiente proyecto que se incluye en LabVIEW para aprender más sobre las máquinas de estado:
Cree su propio proyecto basado en máquina de estado en LabVIEW con la plantilla de proyecto Simple State Machine; vaya hasta el menú File de LabVIEW >> Create Project >> Simple State Machine. Usted puede modificar esta plantilla como punto de partida para su propia aplicación.
El patrón de diseño productor/consumidor ilustra cómo usar una cola para compartir datos entre múltiples ciclos que se ejecutan a diferentes velocidades. El ciclo que contiene una función Enqueue Element es el "productor" y el ciclo que contiene una función Dequeue Element es el "consumidor". El uso de una cola garantiza que los datos no se pierdan si los ciclos se ejecutan a diferentes velocidades.
Una cosa a tener en cuenta sobre el patrón de diseño productor/consumidor es que es en gran parte teórico. En la práctica, rara vez verá el patrón fundamental de productor/consumidor en el código del mundo real. En cambio, es mucho más probable que vea el Queued Message Handler.
Ejecute el siguiente ejemplo que se incluye en LabVIEW para aprender más sobre el uso de colas para compartir datos entre ciclos:
El Queued Message Handler (QMH) es una implementación del patrón de diseño productor/consumidor que también incluye una estructura de eventos para la interfaz de usuario y la generación de eventos programáticos. El Event Handling Loop (EHL) contiene una estructura de eventos que pone en cola (produce) mensajes para el Message Handling Loop (MHL), que los quita de la cola (consume). El MHL también puede generar mensajes para sí mismo según sea necesario. Los "mensajes" en este caso son clústeres que contienen una de caracteres (que impulsa la estructura del caso en el MHL) y una variante, que puede contener datos específicos del mensaje de cualquier tipo. En el QMH, el MHL también puede comunicarse con el EHL con eventos de usuario.
Explore el siguiente proyecto que se incluye en LabVIEW para aprender más sobre QMH:
Cree su propio proyecto basado en QMH en LabVIEW con la plantilla de proyecto Queued Message Handler; vaya hasta el menú File de LabVIEW >> Create Project… >> Queued Message Handler.
Para que una aplicación de LabVIEW grande sea extensible y fácil de mantener, debe estar bien diseñada.
Imagine una aplicación de LabVIEW teórica que prueba un dispositivo. Habrá código para configurar la aplicación, conectar al dispositivo, realizar medidas, mostrar datos, registrar datos, manejar condiciones de error y muchas más funciones.
Si toda la funcionalidad descrita de esta aplicación reside en el mismo diagrama de bloques de LabVIEW , será imposible desarrollar, probar y depurar las características de la aplicación de forma aislada. Por ejemplo, si hay un problema en el código de registro, no hay manera de depurar solo el registro sin ejecutar toda la aplicación. Además, realizar un cambio en el código de registro podría afectar inadvertidamente a otras partes de la aplicación ya que todo reside dentro del mismo VI.
Cada una de las funciones descritas anteriormente serían más adecuadas como un proceso asincrónico, donde cada función es modular y se puede desarrollar, probar y depurar de forma independiente. También se necesitaría un mecanismo de comunicación robusto entre los procesos.
Un enfoque estructurado para implementar el código de LabVIEW para facilitar este tipo de diseño modular asincrónico se llama una arquitectura. Algunos equipos de LabVIEW desarrollan sus propias arquitecturas. Esta puede ser una tarea difícil, ya que existen muchas consideraciones, obstáculos y limitaciones asociadas con el desarrollo de la infraestructura de código y mensajes necesarios para implementar una aplicación asincrónica de LabVIEW exitosa. Además, la cantidad de código estándar requerido para implementar un framework robusto requiere suficientes herramientas dentro del framework para automatizar tareas repetitivas (para ayudar a los desarrolladores a evitar errores al intentar programar manualmente el código a nivel del framework).
Afortunadamente, este arduo trabajo ya ha sido realizado por múltiples entidades (dentro y fuera de NI) que ofrecen sus arquitecturas de nivel de consumidor a la comunidad de LabVIEW . Dos de las arquitecturas de LabVIEW más populares en uso en la actualidad son Actor Framework y DQMH.
Actor Framework (AF) es una arquitectura soportada por NI que se incluye en LabVIEW. Es una implementación orientada a objetos del queued message handler (QMH). En lugar de marcos de ciclo de manejo de mensajes en una estructura de caso y funciones de Enqueue Element, las clases de mensajes proporcionan VIs de método 'Do' para ejecutar código específico dentro de un Actor Core VI.
El diseño basado en clases de AF proporciona un framework extensible para implementar actores secundarios que heredan el comportamiento de los actores principales, lo que no es posible con el enfoque QMH estándar basado en la estructura de casos. Además, toda la funcionalidad del framework principal (inicialización, mensajes, respuesta a errores, etc.) se puede aumentar o anular en un actor dado en virtud del diseño orientado a objetos del framework.
Explore el siguiente proyecto que se incluye en LabVIEW para aprender más sobre Actor Framework:
Cree su propio proyecto basado en AF en LabVIEW con la plantilla de proyecto Actor Framework; vaya hasta el menú File de LabVIEW >> Create Project… >> Actor Framework.
Tenga en cuenta que el éxito con Actor Framework se basa en un sólido conocimiento de la programación orientada a objetos, junto con una instrucción y comprensión adecuadas del framework en sí. Hay numerosos recursos disponibles para capacitación de AF . Algunos de los más populares son:
Cuando usted comienza a usar la arquitectura AF en sus propias aplicaciones, puede interactuar con otros usuarios en Actor Framework – NI Community User Group para hacer preguntas y discutir sobre prácticas recomendadas con otros programadores.
El Delacor Queued Message Handler (DQMH®) utiliza un mecanismo similar al QMH estándar para la comunicación en un proceso determinado (o "módulo"), pero la comunicación entre módulos asincrónicos se lleva a cabo con User Events. DQMH no es una arquitectura orientada a objetos, aunque emplea clases de LabVIEW para algunos componentes menores del framework.
DQMH es una arquitectura de terceros, desarrollada y mantenida por el Consorcio DQMH. El objetivo principal del equipo de diseño de DQMH original era proporcionar un framework gratuito a la comunidad de LabVIEW que sea accesible para los desarrolladores de nivel CLAD/CLD.
Puede instalar DQMH usando VI Package Manager.
Una vez instalado el paquete DQMH, puede explorar el siguiente proyecto para aprender más:
Hay innumerables recursos de capacitación disponibles para DQMH. Cuando usted comienza a usar la arquitectura DQMH en sus propias aplicaciones, puede interactuar con otros usuarios en DQMH Consortium Toolkits – NI Community User Group para hacer preguntas y discutir sobre prácticas recomendadas con otros programadores.
DQMH® es una marca registrada de DQMH Consortium, LLC.
AF y DQMH son las arquitecturas de LabVIEW más populares en todo el mundo, pero de ninguna manera son las únicas. Otras arquitecturas disponibles para la comunidad de LabVIEW incluyen: