NI TestStand

cancel
Showing results for 
Search instead for 
Did you mean: 

Problems with Custom Data Types when converting from TS 1.0 to 3.0.

I am currently involved in the process of converting a test environment from TestStand 1.0, LabVIEW 5.1, and Windows NT to TestStand 3.0, LabVIEW 7.0, and Windows XP. We use a custom Operator Interface developed in LV. Based on the entered Model and Serial number, the appropriate Test Sequence is called. We also use a custom Process Model. The steps in the Test Sequence are either LV code modules or DLLs created in C++. We have LV SubVIs and C++ API functions that allow the developers of the test steps to add data to various Custom Data Types. For example, a developer may set up a test to add a note (Step.Result.Notes[x].String) when the test fails. Step.Result.Notes is a container for an array of strings. The attempt to set a note first attempts to use SetDimensions to redimension the array, then SetValString to set the value. These notes are added to the report. On the old system, everything worked fine. A note could be added to any result. On the new system, if a note is added to say the 5th result, but results 1-4 do not have a note, the test sequence ends and the Operator Interface returns to waiting for data entry (as if no test ever happened). No report is generated. The LabVIEW libraries have been modified to solve this problem by calling SetDimensions to incrementally increase the array size by one, and populating the unused TestStand array elements with an empty array of LabVIEW strings using the SetValString call . In other words, based on the previous example, if the user wants to set a note for the 5th result, the notes for results 1-4 must first be sent an empty array of strings. The report will only display the note for Result 5 (as desired). In addition to this being cumbersome, attempting to implement the same workaround in the C++ API has been unsuccessful because even though the note arrays for unwanted notes (1-4) is initialized with nothing, it is still displayed as a note (empty) on the report. If anybody knows what is wrong and what the solution is, it will be appreciated.
0 Kudos
Message 1 of 10
(4,151 Views)
Hello,

I want to make sure that I fully understand to situation. If taken literally, results 1 through 5 should refer to 5 different steps (each step as a result, each result has an array called Notes, each element in Notes has a sub property called String). However, from the context of your message it sounds when you refer to "results" you really mean different elements in the Notes array in the results container of a given step. Is this later interpretation correct?

If so, then you are saying that after redimensioning the array Notes with the method, SetDimensions, you are still unable to add an element at index 5 without first adding elements at indices 1 through 4. SetDimensions allows you to determine the range of indices for an array. Therefore, if you wanted an array with a single element at index 5, you would set both the lower and upper bounds of the array to the value 5.

As a side note, there are two other things I would like to mention. The first is that you most likely want an array of types instead of an array of containers. If you declare an array of containers, each element in the array is not necessarily of the same type. Instead, create a custom type and create an array of that type so that all the elements are uniform. I would also suggest doing all of the debugging of your application in the sequence editor instead of in an Operator Interface (OI).

For your convenience, I have created a quick sample sequence that calls a VI which changes the dimensions of the array and adds an element at index 5. The report should only show that one item. Thank you for contacting National Instruments and take care!

Regards,

Aaron B.
National Instruments
0 Kudos
Message 2 of 10
(4,124 Views)
Aaron,
Thanks for your reply. I will attempt to clarify. I am working with a single step. The step calls a DLL. The DLL performs many 'checks' on the UUT (e.g. Model Number Check, Serial Number Check, Calibration Constants Check, etc.). Under the Type Palette - MyTypes.ini, we have a Step Type called TEST_DLL with a container in it called Results. In the Results container are a number of things, but I will only list the important ones:

Notes (Array of Type 'Notes'; Type 'Notes' is a Custom Data Type (container, Type Definition)containing an array of strings called 'String')
-Notes are generally set when on of the checks fails, otherwise no Note is set for the check.
Val (Array of Type 'Val'; Type 'Val' is Custom Data Type (container, Type Definition) containing a Boolean called 'Boolean')
-Val indicates whether the check passed of failed

Pseudocode example:
//Model Number Check
check# = 0;
resultBOOL = ModelNumberCheck();
SetDimensions("Step.Result.Val", 0, "[0]", check#);
SetValBoolean("Step.Result.Val[check#].Boolean", 0, resultBOOL);
if(resultBOOL == FAIL)
{
Note# = 0;
SetDimensions("Step.Result.Notes", 0, "[0]", check#);
SetDimensions(Step.Result.Notes[check#].String, 0, "[0]", Note#);
SetValString("Step.Result.Notes[check#].String[Note#]", 0, "Model Number Check failed");
Note# = 1;
SetDimensions(Step.Result.Notes[check#].String, 0, "[0]", Note#);
SetValString("Step.Result.Notes[check#].String[Note#]", 0, "Model Number = 1234");
}
//Serial Number Check
check# = 1;
resultBOOL = SerialNumberCheck();
SetDimensions("Step.Result.Val", 0, "[0]", check#);
SetValBoolean("Step.Result.Val[check#].Boolean", 0, resultBOOL);
if(resultBOOL == FAIL)
{
Note# = 0;
SetDimensions("Step.Result.Notes", 0, "[0]", check#);
SetDimensions(Step.Result.Notes[check#].String, 0, "[0]", Note#);
SetValString("Step.Result.Notes[check#].String[Note#]", 0, "Serial Number does not match expected");
}
More Checks
...

As you can see above, the "Step.Result.Val" array is redimensioned for every check. The "Step.Result.Notes" array is only redimensioned when a note needs to be added for a failing check. If the entire step executes and no check adds a note, the sequence is fine. If every check fails and therefore every check adds a note, the sequence is fine. However, if there are any gaps (e.g. check 0 adds a note, check 1 does not add a note, and check 2 tries to add a note), the sequence will stop. If I add blank notes for every check that would otherwise not have a note, the sequence completes, but the report shows the blank note.

Also, the exact code that is causing these problems runs fine on our old systems (TestStand 1.0). I hope that I clarified the problem and thanks again for the help.
0 Kudos
Message 3 of 10
(4,108 Views)
Tony,

SetDimension, the UpperBound parameter is a string therefore you must convert check# to "["+str(check#)+"]".

Regards
Ray Farmer
Regards
Ray Farmer
0 Kudos
Message 4 of 10
(4,093 Views)
Thanks for the suggestion Ray. However, this is not the actual code, just the basic idea of what is going on. In the actual code the fourth parameter is converted to a string prior to using the SetDimension. Again, thank you.
0 Kudos
Message 5 of 10
(4,082 Views)
Hello,

Thank you for the clarification. So the problem is not redimensioning an array, it is that you want to have an array with indices that are not continuous (ie: 1, 3, 4, 7). This is impossible. Array indices must exist in increasing increments of 1. But if you do that, then in your report, all of the array elements are shown, even the ones that you left blank. Is this correct?

My only suggestion to you, in that case, is to programmatically copy the data from the one array to another that is "compressed". For example, if you have the following array:

a[2] = "how"
a[3] = ""
a[4] = "are"
a[5] = ""
a[6] = ""
a[7] = "you"

I would copy it to a temp array, resize your array and then copy the values back so that the result is:

a[0] = "how"
a[1] = "are"
a[2] = "you"

If you need to maintain the specific index values for some reason, you could create a new array of a data type that contains a string and a numeric. The numeric could be the original index value. Good luck and take care!

Regards,

Aaron B.
National Instruments
Message 6 of 10
(4,066 Views)
Thank you Aaron. You have the problem correct. What is frustrating is that we were able to have the arrays with non-continuous indices in TS 1.0. We need to keep the indices because they are used for the report generation. All of the Step.Result.Parameters[x] are written to the report based on x (i.e. Step.Result.Val[1], Step.Result.Notes[1], Step.Result.Eval[1], etc. all go on the report under RESULT 1). We have also found a way to get around the problem on our new system (TS 3.0, LV 7.0) with our LabVIEW driver set. We just populate the empty TS array locations with an empty LabVIEW array of strings by using the "TestStand - Set Property Value (String Array).vi". The same fix will not work in our C++ driver set because declaring an array with zero elements causes a compiler error. Also, trying to set the empty TS array locations with:

SetValString( "Step.Result.Notes[x].String", 0, "");

causes the Note to show up on the report. I would guess that this is because the "" is actually treated as and empty string with '\0' appended to it. We could just change our report handling to remove empty notes, but that will add about two months onto the project as we would have to revalidate our Operator Interface. Therefore, I would really like the fix happen in the C++ driver as this is going to be revalidated anyway. One idea that I thought of, but have not attempted yet is to compile our LabVIEW solution into a DLL and then call the resulting function with the C++ driver. Thank you for your help.
0 Kudos
Message 7 of 10
(4,046 Views)
Hello,

I disagree that it should take months to modify the way that your report results are written. In fact, if everything has been programmed efficiently, you should not need to modify your OI in any way. All report generation should take place in a Process Model. So the programming that would need to be altered is just the sequence(s) that pertain to generating the report. And possibly, just the code modules called by steps in the process model would need to be changed. In fact, if I were you, I would look for the place in the code where the Notes data gets written to the report. Put that small piece of code in an conditional block such that it only gets executed if that Notes data is not empty.


Regards,

Aaron B.
National Instruments


P.S. The heuristic that I mentioned in an earlier message on this thread to remove elements in an array is NOT efficient. A much better way would be to use the "RemoveElements" function in "Expression Browser >> Operator/Functions >> Functions >> Array" to remove one or more element at a time. The array will automatically resize itself and adjust the indices so that they are continguous.
0 Kudos
Message 8 of 10
(4,013 Views)
Hello Aaron,
Thanks for the help. I was not saying that the change itself will take months. I understand that a change to the report generation would be a fairly minor change from a coding standpoint. However, I am working with code that has been operational for years and is currently used in many of our production locations. Therefore, I am limited by management as to what changes I can make. In addition to that, the company that I work for must follow certain federal rules so a relatively simple change to the code can still cause a two month delay because of all the paperwork and revalidation that must take place before the code can be released to the production environment. I guess what I originally wanted an answer to is: Our code worked with TS 1.0, are there additional or new methods that need to be called in TS 3.0 to make the same code work, or was the array handling fundamentally changed? If there is no way to do it, then I will need to make a change in the report generation, but that is not the ideal solution for my situation (although it is looking like the only one). I thank you for your time on this matter.
0 Kudos
Message 9 of 10
(4,006 Views)
Tony -
I am not sure what 1.0 did, but I can tell you your options for 2.0 and later. From what I understand of our internal code our arrays must be continuous. However, when you work with arrays of containers you can define a name for the item. For example. The Main step group is an array of container. Each step has its own name. You can access the list of steps using a numeric index or the name of the step. The sequences in a sequence file are the same thing also. The key is that this only applies to elements in an array of containers.

You can see what this looks like in the attached png graphic and what the report looks like. The report generator uses the name instead of the index to display the value in the report.. Hope this helps.
Scott Richardson
https://testeract.com
0 Kudos
Message 10 of 10
(3,984 Views)