Discussion:
Programmatic creation of shared variables
(too old to reply)
Doug M
2006-08-16 22:10:07 UTC
Permalink
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.


Programmatic SV Creation.lvproj:
http://forums.ni.com/attachments/ni/170/201084/1/Programmatic SV Creation.lvproj


Programmatic SV Creation.vi:
http://forums.ni.com/attachments/ni/170/201084/2/Programmatic SV Creation.vi
Adnan Z
2007-02-27 16:10:08 UTC
Permalink
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
dliechti
2007-02-27 16:40:12 UTC
Permalink
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
MScap
2008-06-06 16:40:06 UTC
Permalink
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?
MScap
2008-06-06 16:40:06 UTC
Permalink
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 Enabledit 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
Eli_S
2008-06-09 20:10:06 UTC
Permalink
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?


GetVariableList.vi:
http://forums.ni.com/attachments/ni/170/330087/1/GetVariableList.vi
MScap
2008-06-10 07:10:07 UTC
Permalink
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! :smileyhappy:
MScap
2008-06-10 07:40:05 UTC
Permalink
oh wow!!! that was working very very fine!!I wanted something just like that!thank you so much!!:smileyhappy:
blackperl
2008-08-11 08:10:06 UTC
Permalink
Hi all,I have an application where i am using a set of cFP controllers and a pair of Servers. I am using Shared Variables for transferring data between cFP and Server by binding the cFP variable to Server Variable.I am using these servers for redundancy purpose. I made some logic to intimate cFP whichever is active.But is it possible to programmatically bind the cFP variables to the Active Server. i need to change the binding address whenever a server switching is happened.Waiting for a reply.Thanks and Regards,Blackperl
Loading...