LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Programmatic creation of shared variables

Hi,

I am trying to run the following example that shows how to programmatically create shared variables:

http://sine.ni.com/apps/utf8/niepd_web_display.display_epd4?p_guid=0E1C97CBB42D51A2E0440003BA7CCD71

However, I am getting the following error (-1950678978) at the output of the "Library" invoke node:

"LabVIEW: (Hex 0x8BBB003E) A shared variable may only be added to a project library."

I unzipped the files to a folder, and opened the .lvproj file which made it the current project. And I supplied the correct path to the .lvlib file (which is part of the project) in the Create Shared Variable.vi. I get the above error on running this VI.

I just started using the Project environment and must be missing something basic. Would appreciate any pointers.

Am using LV 8.20.

Thank you in advance!

-Khalid
0 Kudos
Message 1 of 22
(10,361 Views)
Khalid, thanks for noticing this, I'll get the example updated.

The API for programmatic creation of libraries and shared variables has changed a bit from 8.0 in 8.2, but should hopefully be simpler.  If you have LabVIEW DSC 8.2, there is a good example called Library Generation that ships with the module that shows the new API as well as includes some good subVIs for setting all the DSC parameters of shared variables.  There are four VIs that can be used for programmatic library and shared variable creation that ship with LabVIEW regardless of the DSC module, but these VIs did not make it onto the VIs palette. They are located at C:\Program Files\National Instruments\LabVIEW 8.2\vi.lib\Utility\Variable.

Attached is a simplified example that shows creation of a shared variable and library regardless of whether DSC is installed.
Doug M
Applications Engineer
National Instruments
For those unfamiliar with NBC's The Office, my icon is NOT a picture of me 🙂
Download All
Message 2 of 22
(10,328 Views)
I would like to create Shared Variables programmatically in an executable. Is that possible somehow?

My Executable loads and runs other VIs dynamically, which communicate with a real-time system. The loaded VIs could hold Shared Variables which didn't exist when the executable was built- so I would like to either add the according variable library to the project or create the variables programmatically. As I found out most of the library properties and methods aren't available in the LV runtime engine.

thanks for any help
Dave
0 Kudos
Message 3 of 22
(9,988 Views)
Hi Dave,

The only way to programmatically create a shared variable in LabVIEW is to use an add-on module called the LabVIEW DSC Module (Datalogging and Supervisory Control). This module greatly enhances LabVIEW's ability to dynamically operate on network-published data. It includes functionality for creating shared variables dynamically, deploying them, as well as binding them to any number of I/O servers such as FieldPoint devices and OPC Servers. Without the LabVIEW DSC Module, you must statically create shared variables as you edit your VI. And, when you create an executable, you can choose the 'Enhanced DSC Support Option'.

That being said, however, there are lots of good options that you have simply using LabVIEW if you don't necessarily want network-published data.

The first implementation I would recommend would be to use a single-element Queue. A Queue is a software FIFO (First In First Out) buffer that stores data. There are four basic queue operations:

1. Obtain Queue: get a reference to a new or existing queue. Specify the name and datatype of the queue.
2. Enqueue Element: write a value to the queue.
3. Dequeue Element: take the oldest element out of the queue and output its data.
4. Release Queue: destroys the queue and releases the storage in memory.

The idea here would be to use a single-element queue. If you are not interested in buffering your data, but rather just having globally shared data that you can create dynamically, then you only need one element in the queue. You can access your data two ways: by passing around an existing queue reference to dequeue or enqueue elements as needed, or by calling ... Obtain Queue from anywhere in your program and specifying the name of the queue to get a new reference to it. Refer to the example attached below and the tutorial for more information on this option. You can also search for the term queue in the Example Finder (from LabVIEW: Help >> Find Examples) for general use cases.

The next idea I would mention is to use a functional global to store your data. A functional global is actually a VI like any other, but it uses uninitialized shift registers on a while loop to store data. Generally a functional global has a while loop set to run only once (so that we can take advantage of the shift registers) and multiple cases that can execute inside the loop. You could, for instance, have a Read case and a Write case for accessing your data. You could also have any other number of cases. The reason these are called functional globals is that you can have other cases that not only return your stored data, but operate on it as well. You could, for example, have a Return RMS case that averages the data before returning it.

Generally, functional global VIs are set to be non-reentrant, meaning that you access the same instance of the VI no matter how many times it appears on the block diagram. In your case, this wouldn't help, because you want to programmatically instantiate global storage. This can be done by dynamically calling the VI using VI Server multiple times and passing those separate references around. You can then run these separate instances to get or set data using the Call By Reference Node. Again, refer to the tutorial linked below for more information and an example of this.

These ideas should get you going. If you want general advice on how to proceed, I would recommend the queue method. If all you want to do is store data and not operate on it as well, then the functional global method will add unneeded overhead and complexity. In general, however, functional globals are fantastic means of storing global data.

Here is the link to the tutorial I've been talking about. Specifically, refer to the section called Methods for Large Data Storage.
http://zone.ni.com/devzone/conceptd.nsf/webmain/6a56c174eaba7bbd86256e58005d9712

Please let me know if you have any questions whatsoever about any of these topics, or if you would like to discuss the LabVIEW DSC Module in further detail. Thanks and have a nice day!
Adnan Zafar
Certified LabVIEW Architect
Coleman Technologies
Message 4 of 22
(9,966 Views)

Hi Adnan!

Thanks a lot for your detailed answer!

I would be very interested in the DSC Module. I really have to interchange data between a host-PC and a realtime target (PXI). Beside that I have to communicate between an executable and dynamically called VIs (which aren't part of the executable).So the queues, functional globals and so on won't work - I need Shared Variables, Data Socket or TCP/IP communication.

I was thinking about creating a sort of data module. It would be a functional global where I store my data in shared variables instead of shift registers. For example to manage double values I would have two Shared Variables: A 1D string array and a 1D double array. One holds all the variable names and the other holds all the values. With array-operations I could create and delete variables at runtime. The same would work for other data types and even for arrays. To manage 1D Arrays I just need a 2D array and so on.

I once implemented something similar but there with normal functional globals and not with Shared Variables.

 

Actually the only thing I would like to do is to add a library of Shared Variables to the running executable. When programming the dynamic VIs which communicate with the PXI-System I have to define the Shared Variables anyway. So they exist somewhere. It's just when I want to run the VI dynamically I get an error which says that the VI isn't executable (because the Shared Variables are not known...).

 

Cheers, Dave

0 Kudos
Message 5 of 22
(9,955 Views)

Hi Dave,

I am glad you are interested. More information about the LabVIEW DSC Module can be found at the following links:
LabVIEW Datalogging and Supervisory Control Module 
LabVIEW Datalogging and Supervisory Control Module 8.2 Help

And you can always find more information on our Forums, Developer Zone and Knowledge Base.

 
Adnan Zafar
Certified LabVIEW Architect
Coleman Technologies
0 Kudos
Message 6 of 22
(9,936 Views)
hi


i need some help with regard to creating shared libraries and variables programatically.

i am making use of the vis 'create or add library to project' and 'create or add variable' vis to create libraries and variables programatically.

i create around 10 libraries and around 5-6 variables under each library in a single run of the vi.

the vi runs fine when all the library names and variable names are different.

as is obvious, i get an error 1051 when i enter an existing library/variable name, in my second run.

my libraries and variables will not be deployed as i write/run the code. so, if i try to use 'get process list' and 'get variable list' vis, i cannot get the details of the library names and variable names created in the previous iteration of the FOR loop.

i hope you got my point.

is there a method to find if the library name/variable name is already used?

i wish to use this vi scalably. i mean, if i might required to create 100 libraries, i just need to change the FOR loop iteration count.

ALSO, if i try to use 'get process list' or 'get variable list' vis, i will get lirbaries and variables present in other projects as well.
using this list as a chekc will not allow me to create a library/variable in an other project with exisitng names.

is there a solution to this?

how do i find out if there is already a library/variable in the given project with the same name - as i run it?
0 Kudos
Message 7 of 22
(7,111 Views)
hi

compeltely unrelated to my earlier post in this thread, i have another question.

i used property nodes to set the scaling properties of a shared variable.

when i configured the values in the order:

Scaling Enabled, Scaling Type, RUMax, RUMin,EUMax,EUMin

i got the error '(-1950678978) at the output of the "Library" invoke node:

"LabVIEW: (Hex 0x8BBB003E) A shared variable may only be added to a project library."'

when i changed the order to:

Scaling type, RUMax, RUMin,EUMax,EUMin,Scaling Enabled

it ran perfectly.

Qus: Why did that happen?

Property nodes follow top-down procedure. How can i configure sclaing paramters before enabling Scaling?
Should it not Enable scaling first and then configure the parameters?


Thanks

0 Kudos
Message 8 of 22
(7,106 Views)
MScap,

You can get a list of the variables and libraries in a specific project using VI server and you can then use these names to check if a specific name already exists. Furthermore, using the VI server method, you do not need to deploy the libaries for them to be found. Please take a look at the attached example. I posted it in LabVIEW 8.5.1 if you need another version please let me know.

As far as your second post, can you please show a screenshot of how you are setting the property nodes?


Eli S.
National Instruments
Applications Engineer
0 Kudos
Message 9 of 22
(7,061 Views)
hello!

Thank you for the reply.
I shall try the vi and update you.

coming to my second post, i got to know that there is a specific order of configuring the Shared variable using a property node.

I followed the order and solved my issue.

thank you! Smiley Happy
0 Kudos
Message 10 of 22
(7,051 Views)