Executing Perl scripts in LabVIEW

The project that I am currently working on requires Perl scripts to be executed through a LabVIEW application which configures the UUT. As Perl is not natively supported by Windows and LabVIEW (I might be wrong here), other tools are needed in order to execute the scripts correctly.

As the scripts were developed on Linux, there was never an issue running them before developing the LabVIEW application.

Running Perl scripts on Windows

First we need to be able to execute the Perl scripts on Windows, then we can move on to LabVIEW.

The tool I am using is called Cygwin.

Cygwin is:

  • a large collection of GNU and Open Source tools which provide functionality similar to a Linux distribution on Windows.
  • a DLL (cygwin1.dll) which provides substantial POSIX API functionality.

To install Cygwin, these are the steps I took:

  • Download and install the your require for your PC
  • Select the Root Directory (C:\Users\gpayne)
  • Select the Local Package directory (C:\cygwin)
  • Select Available Download Sites: http://cygwin.mirror.constant.com
  • When selecting packages make sure you select perl(under Interpreters Group) and ssh (under Net Group) packages.
  • Ensure to add the shortcut to the desktop (We will use this later)

Once installed, running the shortcut on the desktop will open a terminal.

Cygwin Mintty terminal

The pwd command will give you the location and should be the same as set by the Root Directory above.

Create a Perl script in that directory. As an example I have created a Perl script that just prints a number for 5 seconds and then exits. To run the script, enter ./Test_Script.pl in the command line and watch as it runs.

#!/usr/bin/perl -s

my $number = 5;
while($number--)
{
print "$number\n";
sleep 1;
}
exit 0;

Cygwin Mintty terminal running Perl script

Running Perl scripts in LabVIEW

To execute an external application from LabVIEW, one way is to use the System Exec vi. This covers executing the application/script, however Windows is still not able to run a Perl script if it is just called.

The first thought that popped in my mind was to use a batch file.

Using Windows batch (*.bat) files

After doing a bit of research, I found a simple way of calling the Perl script, using bash.exe from a batch file.

@echo off

C:
chdir C:\Users\gpayne\bin

bash --login -c "./Test_Script.pl"
exit 0

This batch file, navigates to the bin directory that was installed by Cygwin and executes the Perl script using bash. The batch file then exits when the script completes.

To accomplish this in LabVIEW is really simple. Just pass the path of the batch file into the command input of System Exec and run the vi. The file runs and the output is reported.

LabVIEW system exec batch file Perl script

LabVIEW system exec batch file Perl script output

This is great because now we can run a Perl script on Windows through LabVIEW and get the Standard Output and Return Code once the script is complete.

This worked well until I started seeing times when the batch file would not exit. I tried all the escape codes that you can call on exit but nothing worked consistently.

The Perl script would execute perfectly every time when run in the terminal, but when run from the batch file and LabVIEW, it would not.

This was not acceptable so I had to look for another way to execute the script successfully every time.

Using Cygwin and Mintty.exe

As the Perl script worked perfectly when run in the terminal, I started looking at ways of replicating it from within LabVIEW. First was to look at what was run when you double click the desktop shortcut. The target points to C:\Users\gpayne\bin\mintty.exe -i /Cygwin-Terminal.ico - and this is what got me started.

I noticed that the application that is run is called Mintty.exe so I took a look at the help file. To get the help file, just type mintty --help at the terminal.

Cygwin Mintty terminal help

I was not interested in the --icon option, but the --exec option looked promising. This got me thinking of what I wanted to execute using Mintty.exe. I needed to execute my Perl script using bash.

So I started to build up my string that I would write to System Exec in LabVIEW. After some trial and error, I was successful in executing the Perl script. This is what I came up with.

C:\Users\gpayne\bin\mintty.exe -e /bin/bash -c '/home/gpayne/Test_Script.pl'

The bash help files are also helpful so from the terminal type bash --help or bash -c "help set".

This would execute the Perl script with bash running in Mintty. This was all good until I noticed that the standard output was not being reported back to LabVIEW. I needed the standard output as this is what I parse to determine if the script was successful or not.

This is very easily solved by piping the standard output from the script to a file and then get LabVIEW to read the file once the script exits. This does add an extra step, but by executing the script in this way, it runs and exits cleanly every time, being much more reliable than using the batch file. This is my final string that was used.

C:\Users\gpayne\bin\mintty.exe -e /bin/bash -c '/home/gpayne/Test_Script.pl > StandardOutput.txt'

 LabVIEW system Mintty bash Perl script output

After trying both methods, I settled on using Mintty instead of Windows batch files. They seemed a lot more reliable over many executions.

This method can surely be expanded to running Python scripts too, which I will leave for another day.

As usual, please direct any questions, comments or tips to my email or on Google+.

Greg

LabVIEW: Built Application Version Property

A LabVIEW project that I have previously worked on had many different components, each with there own version numbering. A global variable was used to READ the version numbers when the application was run.

This worked well, but became rather cumbersome when we had to manually change the global variable each time we modified or built the application. This became apparent and very frustrating when a build would be run, which could easily take an hour or two to complete, and only when running the application did we realise that we forgot to update the global or save its default value.

I thought there must be an alternative so went about exploring the application properties and methods. As it turned out, it is really quick and easy to pull the application version number from the built executable in LabVIEW.

LabVIEW Application Version main

LabVIEW Application Version subvi block diagram

Only two property nodes and one method are needed to get the version number from the built application. First you need to get the type of application that is being run. An enumerated type is returned and if this vi is run from within an application, the App.Kind property will be “Run TIme System”. In this case, pass in the path to the executable, and then get a reference to the FileVersionInfo. The FileVersion property can then be read. This will be the same value as set in the Version Information setting of the Application Properties.

Application Version Information properties

The App.Kind property can be used in a number of ways when you want specific settings to be applied only when running in certain environments.

I hope you find this useful and as usual the project used in the post can be downloaded below.

Download Build Version Property

Greg

LabVIEW Actor Framework – Linked Network Actor (LNA)

Following on from the LabVIEW Actor Framework Basics post, I wanted to continue the project showing how to use a Linked Network Actor. The Linked Network Actor (LNA) library uses network streams to communicate between Actors across a network connection. You can download the library and read all about the details over on the community page.

Either start at the beginning of the previous post, or just download the project here.

Once you have the project open, start by creating a new class, Remote Actor, and setting its inheritance to Actor.

LabVIEW Actor Framework Remote Actor Inheritance

Next you need to add the Linked Network Actor library to your project. If you used VIPM to install the library, you can find the lvlib in the following location. C:\Program Files (x86)\National Instruments\LabVIEW 2013\vi.lib\NI\Actors\Linked Network Actor

LabVIEW Actor Framework Linked Network Actor.lvlib

For your newly created Remote Actor, follow the steps in the previous post for overriding ‘Pre Launch Actor.vi’, ‘Actor Core.vi’ and ‘Stop Core.vi’. You will also need to create a launcher VI to start the Remote Actor. All these steps have been covered before and you will be left with four VIs that look as follows.

LabVIEW Actor Framework Pre Launch Init

LabVIEW Actor Framework Actor Core

LabVIEW Actor Framework Stop Core

LabVIEW Actor Framework Remote Launcher

You will now have a normal Actor that can be run from the launcher and will stop cleanly when the front panel of the Actor Core is closed.

Adding the Linked Network Actor – Remote Actor

Create a global VI which is used to define the Remote Actor identity, Local Actor identity and the IP Address of the Remote Actor. I have used a global VI in this example to keep these settings in one place, but in a proper application, these values should be saved in some sort of config file and then added in using the constructors.

Actor Framework LNA names

Now we need to create the Launch LNA VI and the Kill LNA VI. The Launch LNA VI will be run from the Remote Actor Core and the Kill LNA VI will be run from the Remote Stop Core.

In the Launch LNA VI, you need to launch an instance of ‘Linked Network Actor.lvclass’. However, before the Actor is launched, a few properties need set. Using the global VI from above, set the name to be RemoteActor, set a buffer size and a timeout. Once these properties are set, the Actor can be launched using the Remote Actor as the enquerer. Make sure to set the front panel to FALSE and wire the Remote LNA Enqueuer into the private data of Remote Actor. This enqueuer will be needed later when we want to send messages.

LabVIEW Actor Framework Remote Actor Launch LNA

Next we need to create the Remote Kill LNA VI which wraps the Send Normal Stop VI and is called from the Remote Stop Core. This will stop the Remote LNA when the Remote Actor is stopped.

LabVIEW Actor Framework Remote Kill LNA

Local Actor

Once we have the Remote LNA running, we need a local LNA that is going to connect to it. Once this connection is made, messages can be sent between Actors across a network.

Again we need to create a Launch LNA and Kill LNA VI which will be launched by the Parent (local) Actor Core and stopped by the Parent (local) Stop Core respectively. Both VIs are similar to the Remote version, except for a few additions to the Launch LNA VI.

In the Parent Launch LNA VI, we need to specify connection URL which consists of the Remote Name and Remote IP Address. Once this URL has been constructed, we can run the ‘Send Connect.vi’ which is part of the LNA library.

LabVIEW Actor Framework Parent Launch LNA

The Parent Kill LNA VI also uses the Send Normal Stop VI and is run from the Parent Stop Core.

Sending a Message

Once you have the Remote LNA and Parent LNA set up, all you need to do is create a method to run and build a message using the Actor Framework Message Maker tool. Then when you want to send a message, unbundle the LNA enqueuer and wire the message into the ‘Send Transmit Network Message.vi’. This will execute the remote method referenced in the message Do.vi.

LabVIEW Actor Framework Send LNA Message

If you need to send data as part of the message, you will be able to add the data to the message using property nodes.

Messages can now be sent across a network with ease.

As usual the working project can be found below and if you have any comments or advice, please send me an email or alternatively leave a comment on Google+. When running the program, make sure you start Remote Actor first, and then Launch the Parent Actor. It must be done this way as the Parent connects to the Remote.

Download Actor Framework LNA LabVIEW Code

LabVIEW: Tips, Tricks and Saving Time

I have been rather busy over the last few weeks at work. The inspiration for blog posts hasn’t been flowing that well so I decided to put a list of a few simple tips together. Although I have been using LabVIEW for a few years, these are things that I have only recently come across that have made my programming life that little bit easier/efficient.

Array element names:

One of the great things about arrays is that you can change the settings of on element and that change gets applied to each element inside of that array. I came across a use case the other day where I wanted each element in the array to have a specific name. Due to the nature of arrays, each element’s properties are identical, this cannot be done.

LabVIEW Array elements names_1

A way to get around this is to add a string indicator to the cluster and place it where you want the name to appear. Then when you create the array, all you need to do is specify a name for each element using a Bundle by Name function. The best string to use is a Classic >> String & Path >> Simple String and then make the background transparent.

LabVIEW Array elements names_2

LabVIEW Array elements names_3

By initialising the array first, you can name each element. You still have all the control as you would normally with the array functions, this just provides a neat way to display arrays on a front panel.

For Loop efficiency:

If you have a For Loop and each iteration does not rely on the previous iteration, there is an option which can be enabled which can speed up the execution of the entire for loop. For small For Loops this most probably will not make much difference, but when working with large For Loops which process a lot of data, you should notice a difference.

For Loop efficiency_1

By right clicking on the For Loop, select Configure Iteration Parallelism…

For Loop efficiency_2

Enable the setting and you will notice ‘P’ terminal has been added below for ‘N’. By setting this number, 10 in the above example, you are saying that instead of executing a single iteration at a time, you want the first 10 iterations to execute in parallel, then the next 10 and so forth.

Case Structure efficiency:

When I am using case structure with an enum as the selector, I always wire up my error cluster, data cluster and any other wires that are shifted between cases using the Linked Input Tunnel option. This means that whenever you create new cases within that structure, the wire automatically gets wired.

Case Structure efficiency_1

This might not seem like such a big deal, but does help when pushed for time. It is also pretty easy to forget to wire a terminal up and have to come back to it when you have a broken run arrow.

Another setting for the Case Structure selector when using strings, is to set the selector to no be case sensitive. This setting should not be used all of the time, but does come in handy in some use cases.

Case Insensitive Case Structure

Customising controls:

Controls are relatively easy to customise when you know which ones are best to use and where to start.

Start with a blank control file (.ctl) and place down the control you want to edit. I find that the best controls to edit are the Classic Controls. Below I have added a Gauge from the Classic Controls pallet.

Customising Controls_1

Click on the spanner in the toolbar and you will notice that the control gets split into its elements. I have changed the background colour so that the element borders can be seen clearer.

Customising Controls_2

By using the Tools Pallet and the paint brush, you are able to change the colour of each element within the gauge. If you want the add an image to the background, the white area in the above image, right click on the background, select Import from File at Same Size. Then select the file and it will appear as the background image.

Customising Controls_3

Once you have edited the control as you need, click on the tweezer and the control will be taken out of edit mode.

Customising Controls_4

This is a very quick and rough example, but you can now make very complex and graphical designs with the help of some image editing software to get the base images.

Quick Drop:

I have been using the basic quick drop for a while now and I know many people do use it so am not going to go into it with too much detail. One point that I would like to make is something that I only found out this week. You are able to configure the settings and also use shortcuts instead of typing the whole word of the function.

To get to the settings window, use CTRL+space to bring up the quick drop window, then select Configure in the bottom right corner of the window. Here you will be able to change the settings, add short cuts and view what all you can do with quick drop.

Quick Drop

CTRL+T is one that I found out about this week and am already using it every day.

That’s about all for today. When I think of some more tips and tricks I will be sure to update this post or write a new one if I can get a few more. The vi’s that I have used in the above examples can be found below.

If you have any comments, tips or advice, please send me an email or leave a comment on Google+ as I have disabled comments here to try and control spam.

Download Tips and Tricks LabVIEW Code

Greg

LabVIEW Actor Framework Basics

I have tried a number of times over the last year or so to get my head around the Actor Framework in LabVIEW. I started by reading the recommended starting point and went through all the examples, templates and hands-on. After trying a number of times, unsuccessfully, I put it to one side for another day.

My two main stumbling points, I felt, was not having a project to implement the framework in and not really knowing where to start. All the examples that I worked through started with a relatively large project and I could not find an example that starts with an empty project and builds up from there.

Last week a colleague explained the basics to me and over the last two weeks I have been working on a large project using the Actor Framework. I am finally getting an understanding of it and seeing the potential power in using the framework. Below is an example/tutorial on how to start from an empty project.

Recommended reading

Now for my example

Start off with an empty project and add three virtual folders named, Launcher, Parent Actor and Child Actor.

LabVIEW Actor Framework empty project

  • Launcher: Main vi which is used to start the program. Launches Parent Actor
  • Parent Actor: Main Actor which will launch Child Actor
  • Child Actor: Another Actor that can do things

The Parent Actor and Child(ren) Actor(s) will be created in a similar way. The main differences are the way in which they are started. I will explain how to create the Child Actor and then only show the differences in creating the Parent Actor.

You need to add Actor Framework.lvlib to your project. This is needed so that the classes we are going to create can inherit from Actor.lvclass. Actor Framework.lvlib can be found in C:\Program Files (x86)\National Instruments\LabVIEW 2013\vi.lib\ActorFramework\.

Child(ren) Actor

Create a new Class inside the Child Actor folder and save it.

LabVIEW Actor Framework Child Class

Create virtual folders called Messages and Framework Overrides.

LabVIEW Actor Framework Child Class 2

Change the inheritance of Child Actor.lvclass to inherit from Actor.lvclass.

LabVIEW Actor Framework Child Class Inheritance

Create three vi’s that override the Actor Core, Pre Launch Init and Stop Core. Pre Launch Init will be used to create a string notifier and Stop Core will be used to clean up the notifier. These vi’s are called before and after Actor Core is launched and stopped respectively. Actor Core will be the main vi that is run. This is where your Actor’s functionality happens. Save these vi’s and add them to the Framework Overrides folder in the project.

LabVIEW Actor Framework Override

Follow the following steps to be able to stop the Child Actor when Actor Core is closed.

Child Actor.lvclass:Pre Launch Init.vi

  • Create a notifier with an empty string for the data type
  • Use the notifier out terminal to create a control, rename it stop notifier and then move it into Child Actor.lvclass private data cluster.
  • Bundle the notifier out into the Child Actor object

LabVIEW Actor Framework Pre Launch Init

LabVIEW Actor Framework Private Data

Child Actor.lvclass:Stop Core.vi

  • Unbundle the stop notifier from the Child Actor object
  • Release the notifier

LabVIEW Actor Framework Child Class Stop Core

Child Actor.lvclass:Actor Core.vi

  • Create a while loop and an event structure inside with a 20ms timeout
  • On timeout, add a Get Notifier Status and wire the error cluster to the while loop stop terminal
  • Unbundle stop notifier from the Child Actor object and wire the notifier into the Get Notifier Status vi
  • This monitors the notifier every 20ms and when it is released in Stop Core, it will stop Actor Core. This is one of many ways that can be used to stop the Actor.
  • Add an event for Panel Close?
  • From the Actor Framework functions palette, place the Read Self Enqueuer outside the while loop and the Stop Actor inside the Panel Close? event.
  • Wire the Child Actor object to the Read Seld Enqueuer and the Self Enqueuer to the Stop Actor.

LabVIEW Actor Framework Child Class Actor Core

The Read Self Enqueuer vi gets the queue for itself. So what is happening here is the Stop Actor vi is being run on the Actors own queue which will call Stop Core, release the notifier and then stop the entire Actor.

Next, create the Parent Actor using the same steps. Once complete, add the following modifications.

Parent Actor.lvclass:Actor Core.vi

The Parent Actor will be responsible for launching the Child Actor. To do this we need to:

  • Add the Launch Actor vi with the Read Self Enqueuer defining which queue to execute on.
  • Add a control of the Actor’s enqueuer to the Parent Actors private data and bundle it into the Parent Actor object.
  • Drag the Child Actor.lvclass from the project window onto the Parent Actor Core block diagram and wire it into the Launch Actor vi.

This will now launch the Child Actor before running the Parent Actor core. Make sure that if you want to show the front panel of the Actor being launched, you need to set the Open Actor Core front Panel? To TRUE as the default is false.

LabVIEW Actor Framework Parent Class Actor Core

Creating the Launcher to start the Parent Actor

  • Create a new vi in the Launcher folder and name it Launcher.vi
  • You first need to create a queue for the Actor Core to be launched on.
  • Then Launch the Actor by wiring in which class you want to launch. In this case we wire in the Parent Actor class
  • Then release the queue and close the front panel. You can make fancy launchers with splash screens, but this one is just a plain vi with an empty front panel

LabVIEW Actor Framework Launcher

You should now be able to run the launcher which will start the Parent Actor. The parent Actor will then start the Child Actor. When you close the two Actors, they should stop cleanly. If this works then we can carry on. If not, go back and make sure that you are releasing all the notifiers and queues.

LabVIEW Actor Framework Cores running

Communication between Actors

Add a Boolean control and indicator to the Parent and Child Actor Core. Setting the control in the one Actor will set the indicator in the other Actor. This will show the basics of sending messages between Actors.

Parent to Child Actor

You need to add references to both Actors for their respective indicators. We will use these references to get and update their state from other vi’s with the class. You also need to add a reference control to the Parent and Child class private data.

LabVIEW Actor Framework Parent Class Actor Core_2

LabVIEW Actor Framework Parent Class Actor Control

Make sure you add references to both the Parent and Child Classes.

We now need to create a method (vi) in the Child Class that is going to change the Child indicator when told to do so. Create a new VI from Static Dispatch Template in the Child Class. Save it with the name Get state from Parent.vi.

Add a Boolean control to the front panel and connect it to the connector pane. In the block diagram, unbundle the indicator reference, wire it into a property node and then write the Boolean state to the value property.

LabVIEW Actor Framework Child Class method

This vi is the method that does the work of changing the Child Actor front panel indicator. We now need a way to be able to run this vi from the Parent Actor. There are some tools that allow us to create these messages really easily.

From the project window, select Options and then Actor Framework Message Maker. This will open a window and allow you to create messages for methods that are in your project. Select the method that we just created and click Build Selected.

A Get state from Parent Msg.lvclass is created with two vi’s. Close the vi’s and move the class to the Messages folder within the Child Actor.

LabVIEW Actor Framework Project with Child Actor message

The Send Get state from Parent vi is used to add the data to a queue and the Do vi calls the method that we created a step back. I am not going to go into the details of these vi’s but feel free to open them and see what is going on.

Now that we have our Message and our method, we need to go back to the Parent Actor and to define when to execute this message.

In the Parent Actor Core, add an event case to handle a value change from the Boolean control. This is where we will send the state to the Child Actor message. Add the Set Get state from Parent vi to the event case. This will put the Boolean control state onto the queue of the Child Actor. The Do vi will then be called which will then run the method from within the Child Actor Class. This will then update the front panel indicator of the Child Actor.

LabVIEW Actor Framework Parent Class Actor Core_3

Save your project and run the Launcher vi. Notice that changing the control on the Parent Actor, changes the indicator of the Child Actor.

LabVIEW Actor Framework Cores running_2

Child to Parent Actor

Now repeat the process to send the state from the Child Actor up to the Parent Actor.

  • Add a method to the Parent Actor Class writing the state to the indicator reference
  • Create the messages using the Actor Framework Message Maker tool
  • Add an event case to the Child Actor to handle the state change
  • Wire the control into the Send Get state from Child vi
  • Wire in the queue. You now need to get the caller enqueuer and wire that queue in.
  • Save the project and it should now work

LabVIEW Actor Framework Cores running_3

The final project should like something like this.

Actor Framework Final Project

You are now able to send states both ways between the Parent and Child Actor.

I used these points to get a better understanding on how the Actor Framework works:

  • The main program of an Actor is the Actor Core that is overridden from the base class
  • Each Actor has its own queue
  • Use the Actor Framework Message Maker tool to create messages to communicate between Actors
  • Use the Read Self Enqueuer vi to get an Actors own queue
  • Use Read Callers Enqueuer vi to get the queue of the Actor that Launched it
  • Think of each Actor as its own process with a queue. To speak to a specific Actor, create a message and tell it which queue to execute on

It took me a week or so to get my head around what goes on. I still have a way to go but am getting there and the more I use it, the more confident I am getting. This is a very basic example but I feel it’s good to get going and to understand the framework without starting with a large project.

I have gone into detail with some of the above steps and breezed over others. I hope I have made the most important steps clear enough. If you are stuck with anything, please leave a comment and I will try help as much as I can. You can get a copy of the entire working project below. It has been written in LV2013 SP1.

Thanks for reading and I hope that I have been able to clear the fog over Actor Framework for some people.

Download Actor Framework LabVIEW code

Greg