NI TestStand

cancel
Showing results for 
Search instead for 
Did you mean: 

How To Abort A Step And Jump to New StepIndex

Solved!
Go to solution

Hello,

 

I am in the process of evaluating NI TestStand to determine if it meets the needs for a custom application.  The application will consist of a basic repetitive sequence of activating outputs and verifying the response of the system (inputs).  This portion seems to be a good fit for NI TestStand.  However, while these basic IO operations are executing, the system needs to be capable of asynchronous monitoring.  These asynchronous monitors need to occur over multiple basic IO steps and also need to be handled immediately in the case of failure.  For example, monitor the supply voltage over 10 steps and immediately abort the test if the supply voltage is insufficient.

 

 

I will use the supply voltage as the example for the rest of this discussion, but the final solution will need to implement multiple "monitors".  The "failure" condition of the supply voltage is when it drops below a certain limit and the test results are no longer valid.

 

 

I have been able to handle terminating execution of the MainSequence using a (monitor) SubSequence that reads the supply voltage and calls the Execution.TerminateAll() method when the supply voltage is below limits.

 

 

I am now trying to abort the current step, and jump to a new StepIndex (in the MainSequence) upon a supply voltage failure (detected by a SubSequence in a parallel Execution).  The new StepIndex can contain user-defined code that will either handle the error or jump to a location that no longer needs the supply voltage ON.  I have hit a roadblock with the implementation.

 

 

I cannot find any information on how to abort a step and proceed to the next step or a user-defined step.

The only thread I found was here, but does not contain information on how to do this as the Application Engineer elected to have a private conversation

 

 

Anyone have some advice?

CLA, CTA
0 Kudos
Message 1 of 13
(6,084 Views)

Have you thought about using the SequenceFilePreStep to do you monitoring and aborting your Step. This is called everytime a Step is executed but you could use a counter to determine every 10 step to actual perform any checking.

 

here is a link to an example using SequenceFilePostStep, which is after the step code has executed.

 

Regards

Ray Farmer

 

 

 

Regards
Ray Farmer
0 Kudos
Message 2 of 13
(6,071 Views)

Ray, thank you for the response.  I will describe the operation of the test in further detail to clarify what I am trying to accomplish.

 

The application will consist of a basic repetitive sequence of activating outputs and verifying the response of the system (inputs):

1. Write Outputs

2. Wait

3. Read Inputs

 

It is important to note that the wait time could be anywhere from 1 seconds to a few minutes.

 

 

I currently see two methods of handling a failure:

 

1. Checking the status before/after each step (as you suggested)

This method will not occur immediately after a monitor failure, but after the current step is completed.

 

2.  Using an abort command for the current step

This method will occur immediately after a monitor failure.

 

 

Method 1 is not desired, because it could take a few minutes before the monitor failure is handled.

 

 

Looking forward to discussing this further.  Thanks!

CLA, CTA
0 Kudos
Message 3 of 13
(6,063 Views)

Create a subsequence that does the monitoring. Call it using a sequence call set to new thread. If you are looping in the monitoring subsequence you should probably shut off result collection for that subsequence to avoid wasting memory logging info you probably don't need anyway. You can disable result collection for a sequence in the sequence properties dialog box. The monitoring sequence can then be checking for the conditions you are concerned about in a polling loop and if the condition occurs it can call RunState.Execution.Terminate(), or notify your step in the main sequence in someway that it should abort.

 

That said, there are many ways to do this. Let me know if you have some specific requirement that makes this way impractical.

 

Hope this helps,

-Doug

Message Edited by dug9000 on 05-14-2010 09:43 AM
0 Kudos
Message 4 of 13
(6,054 Views)

Thanks for the response Doug.  I have already implemented the method you discussed above.  This method will terminate the execution of the entire Sequence.  I am not looking to terminate execution, but abort just the current step and jump to an "Error Handler" that will process the failure and then jump to another location in the seqeunce.

 


LVB wrote:

I have been able to handle terminating execution of the MainSequence using a (monitor) SubSequence that reads the supply voltage and calls the Execution.TerminateAll() method when the supply voltage is below limits.

 

 

I am now trying to abort the current step, and jump to a new StepIndex (in the MainSequence) upon a supply voltage failure (detected by a SubSequence in a parallel Execution).  The new StepIndex can contain user-defined code that will either handle the error or jump to a location that no longer needs the supply voltage ON.  I have hit a roadblock with the implementation.


 

My roadblock currently is determining how to abort the current step (but not the sequence), and jump to a new StepIndex.  A good use case would be at 30 seconds through a 2 minute wait step, I detect a supply voltage failure.  I do not want the full 2 minutes before handling the error.

 

Thanks

CLA, CTA
0 Kudos
Message 5 of 13
(6,048 Views)

In that case, rather than calling Execution.Terminate(), you can do the following:

 

1) Create a boolean variable, Locals.SupplyVoltageLow or something like that.

2) Pass that as a parameter by reference to your monitoring sequence (i.e. create a parameter with a similar name in your monitoring sequence and pass the local with the sequence call step)

3) instead of calling Execution.Terminate(), your monitoring sequence should set the state of that variable to its appropriate value

4) Write a Wait subsequence (also disable result collection for it as well), that takes SupplyVoltageLow (by reference) and a wait interval as parameters and does a polling loop with a short wait interval (100ms) in the loop to avoid wasting CPU cycles. Use the Seconds() expression function to determine the start time and whether the total time has elapsed for your loop.  In the loop it should also check SupplyVoltageLow and if it's low then it should exit the loop and cause a failure or error using a step after the loop. The error or failure will propagate to the caller.

5) In your mainsequence instead of using a wait step, use a regular sequence call to your new wait subsequence. To jump to a step based on the status of the wait sequence call, use the post action settings on the step. For example, if you return failure from your wait subsequence you can use the On fail action of the sequence call that calls it to go to a specific step in that sequence on failure. Or, perhaps a better design would be, rather than having your sequence call set execution to a different step, use preconditions on the step after your sequence call step to decide which steps should run after that one. I think the precondition idea makes the sequence more readable as jumping around to various places in a sequence or in any programming language for that matter generally makes the code harder to follow.

 

Hope this helps,

-Doug

0 Kudos
Message 6 of 13
(6,045 Views)

Doug,

 

Thank you for the response.  For the wait function use case, the solution you provided is reasonable.  However, I do not see this solution as scalable.

 

Another use case would be 30 arbitrary monitors that would be started and stopped at various points during the sequence.  Each would have their own respective "error handler".  Based upon the monitor type, the error handler of the monitor may simply skip over a few steps, or may perform some logging, and retry the current step for "n" times before aborting the test.  The important point of this use case would be the active monitors can change as the sequence executes.  For example, monitor power supply voltage over steps 1-10, monitor RS-232 communications link valid over steps 5-15, ...

 

 

  • The main goal of this thread is to determine if it is possible to abort a step, but continue to execute the sequence.  Is this possible within TestStand?
  • I am interested to hear how the use case above would be implemented by some veteran TestStand users

 

 

Thanks.

CLA, CTA
0 Kudos
Message 7 of 13
(5,996 Views)
Solution
Accepted by topic author LVB

There are probably a few different ways you can implement the behavior you are looking for. I think with the information you have provided, continuing to use Execution.Terminate() and taking one step further to implement a Termination Monitor in your steps might be the most suitable option.

 

The Termination Monitor is generally used in a code module that is performing multiple iterations in a loop. It checks to see if the user initiated a termination from outside the code module. If your code module has been correctly designed, upon learning from the termination monitor that a termination has been initiated, the loop will be terminated and the remaining unnecessary code will be skipped (I say unnecessary because there might be some cleanup code in your code module that you want to run before exiting the code module). In your case, if you aren't performing any loops, you can check for a termination at multiple points in your code module. (Note that the default TestStand Wait step type implements a Termination Monitor and will honor a termination)

 

Once the code module exits, you can check whether or not a termination was initiated in a Post-Step engine callback and define the behavior you want to occur if it has. (For example, you can cancel the termination and specify what you want to happen next, whether it be calling a sequence or performing certain test steps).

 

If you choose to take this approach, you will need to ensure that a Termination Monitor is implemented in your code modules at the proper, strategic points. You will also need to be aware that by overriding the Post-Step engine callback, there will be some overhead added and you will encounter a slight performance hit as it will fire for every single step that executes.

 

Does this sound like a viable solution? Hope this helps.

Manooch H.
National Instruments
Message 8 of 13
(5,989 Views)

I think we are both just making this more complicated than it needs to be. Would something like the following work for you? It would be a lot simpler:

 

Can you just have your basic IO steps check themselves to see if there is an undervoltage or whatever similar issues that particular step requires rather than have an external monitor? These IO steps could do the waiting themselves rather than having a separate wait step and just check and return an error or failure if the voltage got too low. If you want to run multiple IO steps at the same time you could run them in separate threads using asynchronus sequence calls.

 

There are multiple advantages to this approach:

1) you can use something like a SequenceFilePostStepRuntimeError or SequenceFilePostStepFailure callback to handle that error case (or even just use a postaction if you prefer), and makes it easier for your to do things like retry the step (see the example sequence under TestStandPublic\Examples\Callbacks\ErrorHandlerExample.seq for details on how to do retry).

2) The IO operation itself is combined with the thing it needs to monitor which makes your code easier to understand. Separating out the monitoring from the thing that depends on the monitoring makes the code less straightforward and hard to follow.

 

You could potentially use Execution.Terminate() and Execution.CancelTermination() or sequence calls also have an option to ignore termination on their run options settings, but I think all of this is unnecessary if you just combine the monitoring of the hardware with the code modules actually doing the tests.

 

Hope this helps,

-Doug

Message 9 of 13
(5,985 Views)

Doug and Manooch, thank you for your responses.  I appreciate your time and effort.

The main goals I am trying to achieve are:
1.    Constantly monitoring a signal (not just at the start or end of a step), may be a TestStand sequence or a custom VI
2.    Immediately handling a failure (aborting the current step, but not the sequence)
3.    Jumping to a new location in the sequence (handling the error) and running error handling code, and possibly jumping back to another test step

Doug:
My example above was poor (monitor power supply voltage over steps 1-10, monitor RS-232 communications link valid over steps 5-15, ...).  There will not always a correlation between steps and monitors that would allow the basic IO steps to check themselves or be combined with the monitors.
Another example would be monitor output signal is ON for 60 seconds.  This could be launched in a new thread during step 5, but the remaining steps are not correlated to the status of the monitor.  However, if the monitor fails (step 5 would be a failure and the current step “n” is terminated/aborted), the sequence should immediately run the error handling routine that will either handle the error or jump to a new location in the sequence.
I am trying to keep the use cases simple, but I can further define some use cases that would require this operation if desired.

Manooch:
It sounds like the Termination Monitor may handle goal #2 from above.
My understanding of your post is as follows: the TestStand Wait step will immediately stop and the Post-Step callback will occur, (allowing the canceling of the termination so the current sequence is not aborted).  If the termination is cancelled, the next StepIndex will run.
If this is correct, it sounds like a viable solution.  I would be interested in discussing the risks of this approach.  From the TestStand API documentation, it mentioned that deadlocks could occur if the method was called incorrectly.  Since there could be multiple monitors (all starting on different steps), I would like to make sure the all threads are handled properly.

 

Thanks

CLA, CTA
0 Kudos
Message 10 of 13
(5,935 Views)