Discussion:
respond to break/resume in OI by calling a teststand subsequence
(too old to reply)
Caren R
2008-07-30 15:40:17 UTC
Permalink
I have a teststand v3.5 sequence file comprised of a main sequence and various subsequences, many of which are based on calls to a DLL written in CVI   (LabWindows/CVI v8.0).    The user runs the sequence using a slightly modified version of the CVI full-featured operator interface (LabWindows/CVI v8.0).    I want to run a sub-sequence in the same sequence whenever the user presses the break/resume button during execution of the sequence.  When the resume button is pressed, I need to run another subsequence and return to the execution point active when break was pressed.  How can I implement this?
Dr. Doiron
2008-08-01 12:10:10 UTC
Permalink
Hello Caren,
 
This is a difficult issue in that we want to find a method that uses good practice (maintains modularity) so that we don't tie a resolution to your process model.
 
I am looking into this but let me ask you some questions first:
 
1. What is your overall application?
 
2. Why are you wanting to specifically use this method (break/resume)? What is your goal by adding this feature?
 
Also, I would highly recommend looking at the <a href="http://zone.ni.com/devzone/cda/tut/p/id/7560" target="_blank">Best Practices for NI TestStand User Interface Development Tutorial</a> from the NI TestStand Advanced Architecture Series, it is a great read for anyone doing UI work.
Caren R
2008-08-03 05:40:20 UTC
Permalink
Hi David,
&nbsp;
I'll try to concisely describe my application.&nbsp; I have a sequence file which in the setup opens a serial port and via that port communicates programmatically with&nbsp;a&nbsp;power supply.&nbsp; The power supply has output enabled throughout the various tests performed in the sequence.&nbsp; At the cleanup, the power supply is programmatically output disabled and the serial port closed.&nbsp; If the break button is pressed in the OI during the test execution, I would like&nbsp;to somehow call a&nbsp;subsequence within the original sequence which would disable power supply output but not close the port, and suspend the seuqence operation.&nbsp; If the resume button is pressed, I want to reenable the power supply output and resume the sequence operation from where it was suspended when the break button was pressed.
&nbsp;
Currently the only functionality of the break/resume is that provided by the 'default' OI which is to suspend/resume execution without any other special handing.&nbsp;&nbsp;The user using&nbsp;my application, might press break and not continue the sequence for a period of time.&nbsp; I would somehow like to define a callback in the sequence (such as a subsequence) which would be executed when pressing break/resume, so I can define how to handle the event.
&nbsp;
How can this be achieved?&nbsp; I appreciate your feedback.
&nbsp;
Regards,
Caren
Dr. Doiron
2008-08-03 18:10:09 UTC
Permalink
Hello Caren,
&nbsp;
Thank you very much for your more detailed explanation.
&nbsp;
My question now is why must the sequence stop? It seems like from your application you described that the most important thing is that the power supply is disabled and that you perform some other arbitrary action as well on pushing break.
&nbsp;
What if you had a button called "disable power supply" which would disable the power supply then call a subsequence that performs some action then waits for "enable power supply", another button.
&nbsp;
Is there a particular reason you must break (as is stop execution&nbsp;completely)&nbsp;or do you just want the functionality described in your post?
Caren R
2008-08-04 13:10:15 UTC
Permalink
Hi David,
In your post you asked why must the sequence stop?&nbsp; I'll try to explain that here.&nbsp; The programmable power supply supplies current to a device which the dll used by the TestStand sequence&nbsp;is periodically communicating with.&nbsp; The dll assumes that after setup, and if initialization succeeds&nbsp;(of both the power supply and the device) then the device is always available.&nbsp; Many of the various steps&nbsp;in the sequence contain tests which involve sending commands to the device and expecting a response or&nbsp;timeout.
&nbsp;However, if the power supply output is disabled but the sequence continues executing,&nbsp;&nbsp;the dll will continue to periodically attempt to communicate with the device and it obviously won't respond.&nbsp; Usually timeout means a test has failed.&nbsp; Why continue the test sequence if we have disabled the power supply&nbsp;output outside the sequence via the break button?
Communications with the device powered by the power supply is the main idea here and not the power supply itself.&nbsp; However,&nbsp; it sounds logical to me that a long test sequence might be suspended by the operator.&nbsp; Do you have any ideas such as how I could call a callback in the Teststand sequence?&nbsp; Do you have any other suggestions on how to implement the break/resume operations I have described?
Thank you for your feedback.
Regards,Caren
j_dodek
2008-08-04 15:10:13 UTC
Permalink
Hi Caren,
Just for understanding in a short way.
CVI-UI with a button Break!&nbsp;A Sequnce with&nbsp;serial&nbsp;comunication to a PS. If&nbsp;Break&nbsp;is pressed at any time PS should be turned off.over serial port communication.
Is that right ?
Greetings
juergen&nbsp;
Dr. Doiron
2008-08-04 21:40:10 UTC
Permalink
Hello Caren,
&nbsp;
It looks like you can use the Break/Resume button.&nbsp;&nbsp;You can utilize the fact that there is a UIMessage passed that represents a Break - if you put the code to pause the execution and power off the PSU in the UIMessage handler for the Break UIMessage, you can continue to utilize the Break/Resume button.
You will need to:

- Pause the original&nbsp;execution
- Create a new execution and call the Power Supply sequence
- Wait until that sequence is done and the resume button is pressed and then
- Restart the original execution

So basically you will be overwriting the break UIMessage (actually all 3) and implementing some extra code when that happens.
This should help you get started, I would highly recommend reading the link I posted earlier regarding Best Practices for UI Development, it's a great document with a lot of information.
Have a great Monday!
DRock
2008-08-12 21:10:16 UTC
Permalink
Caren, Implementation of the suggestions that David gave you winds up being a matter of adding two portions of code to the CVI Full-Featured Operator Interface (or a modified version thereof).&nbsp; The idea is to react to the already existing UIMessage that gets posted when the user presses the "Break" button.&nbsp; This UIMessage has the code "1", as is listed in the TestStand Help.In order to set up our OI to handle a custom UIMessage or add to / override an existing UIMessage, add the following code to your OI in the RegisterActiveXEventCallbacks function :errChk( TSUI__ApplicationMgrEventsRegOnUIMessageEvent
(gMainWindow.applicationMgr, ApplicationMgr_OnUserMessage, NULL, 1,
NULL));After that, add the code in the handle the UIMessage in a custom fashion.&nbsp; The code to handle the UIMessage would look something like this:HRESULT CVICALLBACK ApplicationMgr_OnUserMessage(CAObjHandle caServerObjHandle, void *caCallbackData, TSUIObj_UIMessage&nbsp; uiMsg, VBOOL *cancel){ &nbsp;&nbsp;&nbsp; TSUIObj_IEngine gotEngine;&nbsp;&nbsp;&nbsp; TSObj_SeqFile seqFile;&nbsp;&nbsp;&nbsp; CAObjHandle newExecution;&nbsp;&nbsp;&nbsp; VBOOL removed;&nbsp;&nbsp;&nbsp; char *sessionName;&nbsp;&nbsp;&nbsp; double sessionID;&nbsp;&nbsp;&nbsp; enum TSEnum_UIMessageCodes event;&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp;&nbsp; error = 0;&nbsp;&nbsp;&nbsp; //Get UIMessage event&nbsp;&nbsp;&nbsp; tsErrChk(TS_UIMessageGetEvent(uiMsg, &amp;errorInfo, &amp;event));&nbsp;&nbsp;&nbsp; switch (event) &nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; case 1:&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; MessagePopup ("", "UI Message Handled");&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tsErrChk(TSUI_ApplicationMgrGetEngine (gMainWindow.applicationMgr, NULL, &amp;gotEngine));&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tsErrChk(TS_EngineGetSeqFileEx (gotEngine, NULL, "C:\\test.seq", 11, TS_ConflictHandler_Error, &amp;seqFile));&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tsErrChk(TS_EngineNewExecution (gotEngine, NULL, seqFile, "MainSequence", 0, VFALSE, TS_ExecTypeMask_Normal, CA_DEFAULT_VAL, CA_DEFAULT_VAL, CA_DEFAULT_VAL, &amp;newExecution));&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tsErrChk(TS_EngineReleaseSeqFileEx (gotEngine, NULL, seqFile, 0, &amp;removed));&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; CA_DiscardObjHandle (seqFile);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; CA_DiscardObjHandle (newExecution);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;&nbsp;&nbsp;&nbsp; }Error:&nbsp;&nbsp;&nbsp; DisplayError(error);&nbsp;&nbsp;&nbsp; return error &lt; 0 ? E_FAIL : S_OK;} Adding the above two portions of code will allow you to launch the MainSequence sequence within the C:\test.seq sequence file.&nbsp; You can modify the code to allow it to point at a different sequence within a sequence file of your choice - but this should get you started.&nbsp; I hope this helps, Caren.&nbsp; Good luck with the rest of your development.
j_dodek
2008-08-13 05:40:28 UTC
Permalink
Hi Derrick
&nbsp;
Thanks (5!) for sharing this code snipped.
&nbsp;
Greetings
&nbsp;
Juergen
&nbsp;
&nbsp;

Loading...