NI TestStand

cancel
Showing results for 
Search instead for 
Did you mean: 

Pass parameters to teststand using LV

Ok I have been beating my brains out trying to figure out how to do this. What I have is a user interface built in LV. On the user interface I have the serial # and tests to run. I am trying to pass this information to teststand so that teststand can set locals based on the information. The way I am currently doing it (not wotking) is writing to a global variable inside my UI. Then in teststand I created a VI that reads the global and wires them straight thru to an indicator. Then test stand takes care of the rest.
 
Does anyone out there have a good way to do this. It seams like it should be so easy to do yet I cannot figure it out. I did get it to work correctly when I made the VI that was built in teststand to be reentrant but I have not gotten it to work a second time. (weird)
 
I need help in a bad way and not just with teststand (It's 9:00 PM here and I am still working)



Joe.
"NOTHING IS EVER EASY"
Message 1 of 21
(7,472 Views)

Joe,

The simplest way would be to write it to a StationGlobals variable then let your sequences pick up the information when required.

When you say global variable, you are referring to a aLabVIEW right?

This serial number you enter on your OI, I am assuming this is to replace the dialogbox that pops up when you Press 'Test UUTs'?

Regards

Ray

Regards
Ray Farmer
0 Kudos
Message 2 of 21
(7,469 Views)
Joe,
I had this same frustration with my OI.  In my implementation I was trying to replace/incorporate the parallel model dialog into the OI.  I found that it was relatively simple to get data into an OI with the UI messages and event but to get data from a user through the OI to the sequence was not as easy.
 
My solution was to use the synchronization manager of teststand.  I don't know if you have used any yet but there are synchronization steps in teststand that uses queues and notifications etc.  There is also a teststand synchronization manager that you can call from from labview to gain access to those synchronization steps.  What I did was to generate a new named notification in a teststand sequence with an optional data return value of a two element cluster, a string and a boolean for the serial number an the continue testing boolean.  Then in the sequence using a UI message that I defined I passed the name of the notification into the OI.  The next step in the sequence was to wait for the notification (wich will be comming from the OI).
 
Now, in the OI, I generated a new labview event when the UI event occured (using a similar method as the quit event is handled) so I can manage the serial number string in the existing event case in the top level of the OI.  When the user types in a serial number on the OI a LV event fires one of the event cases and in that event case I pass the serial number and the continue testing boolean to the notification using the synchronization manager (see link below).  The teststand sequence that was waiting for the notification continues on with the data...
 
I did gloss over a few issues,  I had to manage the testsocket socket indexes and I think I named my notifier based on the index (each socket had its own).  I also did some enabling and disabling of the controls based on events (for example don't enable the serial number control until the UI message).
 
This link has a picture that shows my subvi in the LV event case that accessed the notifier and passed the data.
 
I hope this helps and doesn't confuse things too much.  The basic idea I wanted to get across that you can use the synchronization manager to help sync up your OI to your sequence and get data to the sequence.
 
I did get LV 8.2 installed on this machine so I should be able to get you a copy of the OI I mentioned, but not till tomorrow - I don't have the code with me...
 
Paul
0 Kudos
Message 3 of 21
(7,459 Views)

The people that I work with would rather stay away from station globals. I guess if I could get it to actually pass parameters it would be OK but I cannot even get it to pass anything.

What I have is a user interface built in LV 8.5. On this user interface I have an array of 15 clusters that contain a string and a boolean. These represent serial # and slot active. I also have an array of 50 booleans that represent the tests to perform. The sequence is already setup for this. My flow goes as follows.

 

I initiate all the teststand controls and load three sequence files and show them on the listbar. The user is allowed to choose the sequence and based on the sequence I enable or disable tests and controls. They can enter in the serial # and slot active at any time before hitting the testUUT button. Upon hitting the button I would like to send all the parameters to teststand (trouble area) and let it test with no user interaction. I have not gotten anything to work. 

Thanks Ray and Paul for all of the help. What do you all think is the most robust way of doing this.

It just seams as if this should be so simple but yet it is so hard to get working.

I wish that they had a control that did this for you like they do for everything else.

 

Paul please send me that code if you would please. this souns very interesting.




Joe.
"NOTHING IS EVER EASY"
0 Kudos
Message 4 of 21
(7,460 Views)
Why can you not create a vi in teststand that reads from a global variable and use the set property value.vi to set the properties.



Joe.
"NOTHING IS EVER EASY"
0 Kudos
Message 5 of 21
(7,453 Views)
I had a simliar question when I was developing my OI.  I found that I could write back to TestStand from LV if called a UIMEssage from my sequence.  A user event that was called would then query the value of the control in my LV interface.  You could have a separate thread that was periodicaly generating the usermessage to get the status of the controls from LV.  Attached is the screen shot of the diagrams.  I can post the example but its 1.5 MB.  If you aren't able to get it to work from my screen shot then I will post it if neccesary.
0 Kudos
Message 6 of 21
(7,441 Views)

Hi Joe,

Make sure your lookup string matches up with what your referenced to.

eg

If your reference is StationGlobals then the lookup string to a variable will be "my_variable"

if your reference is the SequenceContext the the lookup string will be "StationGlobals.my_variable"

But these days you dont need to use the set property nodes as you can pass it directly from and too teststand via the VI connector pane.

 

Paul's idea seems like a good one. I'll have a look at that if I get some free time.

Regards

Ray

Regards
Ray Farmer
0 Kudos
Message 7 of 21
(7,435 Views)
Hey Joe,

I wanted to chime in here to mention that what Taylor suggested and Paul implemented as well is probably going to be the most robust way to communicate between TestStand and your LabVIEW UI/OI.  A UIMessage is a valuable mechanism to employ when trying to get information from the UI or to display information on the UI.

Global variables probably are not going to be as robust.  Using synchronization steps for information that is more "event-based" (in the sense that it would need to be otherwise constantly "polled") would be good as Paul implemented, but it is not a trivial task.

Ther are several resources that discuss UIMessages, but here's a basic explanation:
UIMessages allow you to send a UIMessage from your sequence or from your process model.  The Engine would at that time fire a callback in your LabVIEW UI that would respond to the UIMessage by setting some values or displaying some information.  The Thread method PostUIMessageEx is called from within a TestStand sequence and allows you to specify asynchronous or synchronous (mostly this determination would be whether you are sending information to the UI or waiting on information from the callback). 

The basis of understanding with UIMessages is the realization that the common "thread" or common task between your UI and the currently executing sequence in TestStand is the Engine.  Using that pipeline of communication, in the sequence we can tell the Engine (with the ActiveX API) to "Post" a UIMessage.  The Engine then signals the callback VI specified in your UI and passes it information.  With this information, the Thread object contains the sequence context, which you can use in your application to set a variable in TestStand.  The sequence context in TestStand is a reference that contains all of the properties/variables that during runtime.  With this sequence context, you can use the TestStand API to set and get values.

This introduction is not exhaustive by any means, but you can find some additional information in several places, the best of which are:
TestStand Reference Manual (in the Start menu)
Basic introduction: http://zone.ni.com/devzone/cda/tut/p/id/4532
Example: http://zone.ni.com/devzone/cda/epd/p/id/3879

Once you get up to speed on UIMessages on how they work, you might find that the best way to employ them in your application is by sending a UIMessage from your process model (perhaps from PreUUT - gathering each serial number - or PreUUTLoop - gathering all test information at once).  Note that you might want to pass either the control reference or the array of clusters in as the "User Parameter" in the register event callbacks node.  Then in your event handler, you can write the data in your array of clusters out to variables in TestStand.

Message Edited by AndrewMc on 08-23-2007 01:08 PM

Thanks,

Andy McRorie
NI R&D
0 Kudos
Message 8 of 21
(7,418 Views)

So the sequence would be something like this.

  1. In the sequence I would post a message that says "hey I'm ready for the test information" (Does the execution stop and wait for me to handle the event or do I need to put in a wait?)
  2. In my main UI I create a callback that handles the message. The callback would consist of.
  • A way of reading the parameters from the UI.
  • A case structure that handles the specific message.
  • A way to get to the context sequence. Which I understand to be local to the currently running sequence.
  • The set property VI.  How do I get to the specific value that I need to set if I need to input an array of clusters?  Would it be something like this that I put into the lookup

    Locals.SlotNumArray[0].SerNum one element cluster and the other would be Locals.SlotNumArray[0].TestActive. Or can I just pass in the whole array.

Thanks for all of the help I really do appreciate it. Learning something new sure does make you feel stupid sometimes........

                       

 




Joe.
"NOTHING IS EVER EASY"
0 Kudos
Message 9 of 21
(7,405 Views)
Joe,

You are right on with understanding UIMessages.

To verify/answer what you suggested:
  1. You do not need a wait.  The asynchronous parameter to the PostUIMessageEx method that I mentioned allows you to specify whether to wait for the callback to finish executing or not.
  2. Here you go:
  • The way of reading the parameters from the UI would be to pass in the control references (or the value itself, if it does not change during execution) into the register event callback as the "User Parameter".
  • Exactly, and the case structure would be based on the numeric "code" from the UIMessage (must be >= 10000).
  • Use a property node with the "Thread" parameter and access the sequence context parameter.  This is shown in the example.  What might help you make sense of the sequence context and what it is, add a breakpoint to a sequence in the Sequence Editor, execute the sequence, and when paused click on the "Variables" tab ("Context" tab if in 3.x).  All of these properties/variables make up the "sequence context".
  • That is exactly the type of lookup string that you can use.  You would need to set individual elements since the data is in a cluster.
Thanks,

Andy McRorie
NI R&D
0 Kudos
Message 10 of 21
(7,393 Views)