From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

NI TestStand

cancel
Showing results for 
Search instead for 
Did you mean: 

Handler demon / Stationglobals

Hi All.

I have a problem with "hanging" a new demon onto the ActiveX server, but first some basic information.

I have build an OI where I launch a exe file that contains a handler control, that controls my inline testrack. Both OI and the handler control is build in labview, and the way that I am sending data between them, is 2 stationglobals. If I run the system directly in labview, then it works. But after I have build both files into exe files, then it seems that they not share the same stationglobals anymore...
I have tried also to start up the TS Editor, and try to follow the stationglobals.. but there are not changed... Then I tried to set "Shared" and "Shared At Runtime" in the variables... but nothing changed..

The way I "control" the engine, is that in the OI (first caller) I call ApplicationMgr.Start, so it launch the ActiveX server, in the Handler control I just call ApplicationMgr.GetEngine... then I have the references to the engine, and then I can get to stationglobals, simple, and it worked in labview editor, but not after I have build the files.

Any ideas ???
0 Kudos
Message 1 of 8
(3,832 Views)
The TestStand engine is unique per process. What you were seeing before was two references to the same engine (the one created by the process LabVIEW.exe). Both of your VIs existed in the same process, and therefore, any engine you created was the same. However, once you create two executables, they are running as seperate processes, and therefore, you have two different engines.

Once Station Globals are loaded, you will have to explicitly reload them. Similarly, you will have to save the globals to disk if you expect any other process to be able to read the most updated values. You can do this with the following methods:
Engine.ReloadGlobals() will reload the globals from disk.
Engine.CommitGlobalsToDisk() will save the globals to disk.

Hope this helps!

Allen P.
NI
Message 2 of 8
(3,826 Views)
I have tried to save the values to disk.. and then as you say then it works, but this is not a good solution. It must take a lot of time compared to memory writing, and if you save the stationglobals, then the editor is saying that stationglobals has changed. Maybe I haven't explained deeply enough, but the handlercontroller, will transfer data to the seq/oi every 500ms

I maybe have to give you some more information about our setup, this "handler controller", has to run always, this is the only way we can load/unload out boards into our testracks. So also when we are in the editor then this "handler controller" has to run.

So what I need is to find a solution where I can transfer values between and OI, my handler controller and then the editor.
What the editor/oi is doing is that it fires up a sequence that runs until you close the OI/editor, this seq is the link between the handler controller and OI/Editor, so maybe the is a way where I can transfer sequence.context to my handlercontroller, but right now I cant see how to do that.....

What I don't understand is why you say it starts a new engine, how can I then write to stationglobals, I am not logged in, in the "handler controller", and if you are not logged in, then you normal cant write to variables...

Kind regards Bojer
0 Kudos
Message 3 of 8
(3,814 Views)
I would expect the method of using station globals to be slow, as it is all done through writing an INI file.

There are two methods I would suggest, and depending on your architecture, one may be superior to the other.

The simplest way (although I do not know if it will work with your system), is to create one instance of the engine in a process, and pass it to the other code modules or processes.

The second method, is to use the synchronization server with teststand to pass data between processes. For example, you can use a TestStand Queue to pass data between processes. Be sure to name all of your synchronization objects with a * prefix, so they can be shared between processes. In TestStand 3.1, this feature has its own section of documentation.
Instead of storing information in station globals, you can use the queue to pass any data back and forth.

Allen P.
NI
0 Kudos
Message 4 of 8
(3,807 Views)
Hi Allan.

Bottom up...

I don't think I can use the queue method as the handler controller is a pure Labview application.

But the other solution is actual what I was thinking of in the first place.. so the solution must be to store the sequnce.context or engine reference in a stationglobal, then fire up my "handler controller", and start with reading the object, and the rest is a piece of cake...

The only problem I see is that I still will have 2 instances of the engine = equal a lot of memory.... So is there not any information anywhere how to get into the same instance of the engine, my "demon" will newer start any seq. is only has to be a link between the testrack and TS.

Actual... if there was a way to start up a VI in TS (Action step) without waiting for it to finish, then this would be the best solution... then there are no problems with variables and so on... So maybe you have an idea here ???

Kind regards Bojer
0 Kudos
Message 5 of 8
(3,804 Views)
A couple of ideas.

First, you can stil use the queues even in a pure LabVIEW application (as long as you have TestStand installed). The Synchronization Server is an ActiveX server and has an API that you can call directly from your application. You can access it by using ActiveX with the NI TestStand Synchronization Server. You will have to create a SyncManager object and you can create/obtain queues.

If you want to pass an engine, I would recommend a method other than creating a new instance of the engine. I don't know if this is possible for how you have it designed.

Also, if you want to start a VI and not worry about having it finish, there are a couple of ways of doing this. One is the Call VI Asynchronously Step Type (LabVIEW Utility Steps). Another method is to call a VI that uses VI Server to spawn off a new VI and does not wait on it to finish.

Let me know if you need more details on each implimentation.
0 Kudos
Message 6 of 8
(3,796 Views)
Also, you can run a vi asynchronously by placing it in a subsequence and then configuring the step that calls the subsequence to run in a new thread or a new execution. This is effectively the same as what the Run VI Asynchronously step type does, except that you now have the option of including more in your asynchronous subsequence than a single vi call.
0 Kudos
Message 7 of 8
(3,792 Views)
Hi Allan

Why haven't I seen "Call VI Asynchronously"... this is exactly what I was looking for... So I changed to this step type, and is transferring sequence.context into the vi..... wwuuuupiii..

No I just have to solve a memory leak problem.. then we should up and running...

Kind regards Thomas
0 Kudos
Message 8 of 8
(3,768 Views)