NI TestStand

cancel
Showing results for 
Search instead for 
Did you mean: 

Problems with Multiple Numeric Limit Test

Hi,

I'm trying to use the MultipleNumeric Limit test and I have problems with it

1) Since I use TestStand 3.1, is it recommended to uses the new type template rather than the legacy one?
2) When you let TestStand create the test code for you it gives you the following:

// The following code shows how to access a property or variable via the TestStand ActiveX API
// To use this code you must add a parameter "struct IDispatch *seqContextDisp" to this function
// and pass a sequence context to it.
// tsErrChk(TS_PropertyGetValNumber(seqContextCVI, &errorInfo,
// "Step.Result.Measurement[0].Limits.Low", 0, &lowLimit0));


I would appreciate if anybody can show me an example using that. I just don't understand it!!
Can't I just pass the sequence context parameter as follow: 'CAObjHandle seqContextCVI' ?

Is the purpose of the line indicating in this example to get the low limit value of test 0 ?

3) This is what I did and got an error

void __declspec(dllexport) __stdcall OpticalParameterTest(CAObjHandle seqContextCVI,double measurements[],
char reportText[1024], short *errorOccurred, long *errorCode, char errorMsg[1024])

{
int error = 0;
ErrMsg errMsg = {'\0'};
ERRORINFO errorInfo;

const int NUM_MEASUREMENTS = 3;
char *StepTitle = NULL, NextErrMsg[BUFFER_LEN] = {'\0'}, buf[BUFFER_LEN] = {'\0'};
double PortNo = 0, offset = 0;
int i;


//=====================================
StepTitle = "Initialization";
//=====================================
gContext = seqContextCVI; //save context

//=====================================
StepTitle = "Power test";
//=====================================

******I get an error for the following line*****
tsErrChk (TS_PropertyGetValNumber (gContext, &errorInfo, "FileGlobals.PwrMeterOpticalLoss", 0, &offset));

ErrNoZ(GPIB_PwrMtr_cmd (gContext, 3, buf, NextErrMsg)); //read power

****** Is this the correct way to pass the result back to TestStand? ****
measurements[0] =atof(buf) + offset;

Thanks
Rafi
0 Kudos
Message 1 of 8
(3,845 Views)
Hi,

You need to use the CVI Active X Automation Handle type so that you pass a CAObjHandle as your seqContextCVI parameter.

As shown below;

void __declspec(dllexport) MyTest(CAObjHandle seqContextCVI, double measurements[], char reportText[1024], short *errorOccurred, long *errorCode, char errorMsg[1024])
{
int error = 0;
ErrMsg errMsg = {'\0'};
ERRORINFO errorInfo;

//// REPLACE THE FOLLOWING WITH YOUR SPECIFIC TEST CODE
double lowLimit0;
const int NUM_MEASUREMENTS = 3; // Replace with the number of measurements you define in the MultipleNumericLimitTest step.
int i;
for (i = 0; i < NUM_MEASUREMENTS; i++)
measurements[i] = 5.0; // Replace with the actual measurement values

// The following code shows how to access a property or variable via the TestStand ActiveX API



// To use this code you must add a parameter "struct IDispatch *seqContextDisp" to this function
// and pass a sequence context to it.
tsErrChk(TS_PropertyGetValNumber(seqContextCVI, &errorInfo,
"Step.Result.Measurement[0].Limits.Low", 0, &lowLimit0));

// Note: This template requires that you do not select the Specify a Data Source for Each Measurement step option.
// If you select this option, the MultipleNumericLimitTest step does not necessarily use the contents of Step.NumericArray.
// You typically do not call a code module when you set this step option.

Error:
//// FREE RESOURCES HERE

// If an error occurred, set the error flag to cause a run-time error in TestStand.
if (error < 0)
{
*errorOccurred = TRUE;

// OPTIONALLY SET THE ERROR CODE AND STRING
*errorCode = error;
strcpy(errorMsg, errMsg);
}
}


Regards
Ray Farmer
Regards
Ray Farmer
0 Kudos
Message 2 of 8
(3,838 Views)
Hi Ray and thanks for answering,

If you look again in the code I inserted into my question you will see that it is exactly the same code you are posting. Basically it is the standard template NI is providing for Multiple Numeric Limit Test with the addition of the parameter CAObjHandle seqContextCVI.

However, using this template I encounter an error and therefore I posted few question. I'll post them again and hopefully you will be able to help me:

1) Is it better to use the new template rather than the legacy one?
2) I'd like some clarification for the following (from NI template):

// To use this code you must add a parameter "struct IDispatch *seqContextDisp" to this function
// and pass a sequence context to it.
// tsErrChk(TS_PropertyGetValNumber(seqContextCVI, &errorInfo,
// "Step.Result.Measurement[0].Limits.Low", 0, &lowLimit0));

What exactly is this 'struct IDispatch *seqContextDisp' ? Can you please post an example of how to use it in my application?

3) Why do I get an error in the following line?

tsErrChk (TS_PropertyGetValNumber (seqContextCVI, &errorInfo, "FileGlobals.PwrMeterOpticalLoss", 0, &offset));

error = -2147024890
errMsg = "Unknown Error"

Thanks
Rafi
0 Kudos
Message 3 of 8
(3,818 Views)
Hi Rafi,

1) Yes it is easier to use the new template than the legacy.

2) Instead of using a struct IDispatch, I'd recommend using a CAObjHandle to access ActiveX objects. Essentially what you need to do is send CVI a handle to the ActiveX object for This Context. From there you can access the relevant lookup string to set or get the data you want. The IDispatch structure is another way for you to pass a reference to CVI but using the ActiveX method is far easier. Here is a the default path to an example using the multiple numeric limit test using the CAObjHandle. This example shows how the Object handle is passed to CVI and then used to access the " Step.NumericArray[0]" lookup string.

C:\Program Files\National Instruments\TestStand 3.1\Examples\MultipleNumericLimitTest\UsingCVIStandardPrototype

In TestStand the data type 'tTestData' is the object handle. TestData is used to point to the ObjectHandle which references seqContextCVI. i.e. it allows you to access the lookup string which in this case is the array: Step.NumericArray[].

3) The handle, seqContextCVI, is invalid. This could be for any number of reasons, have a look at the example to see how it is addressed there.
0 Kudos
Message 4 of 8
(3,792 Views)
Hi John

Thanks for the clarification.

I know how to work with the seqContextCVI. I got confused to see that NI insert automatically the text regarding
IDispatch structure. Is there any circumstance that requires to use it rather than the seqContextCVI?

Thanks
Rafi
0 Kudos
Message 5 of 8
(3,787 Views)
Hi,

It usually used in VC++, but there are some routine to convert the IDispatch structure to CAObjHandle, namely CA_CreateObjHandleFromInterface()if you wanted to use IDispatch structure in your CVI code.

Dont know why the comment is in the template, it's probably just a cut & paste error, well that's my guess.

Regards
Ray Farmer
Regards
Ray Farmer
0 Kudos
Message 6 of 8
(3,784 Views)
Ray, you are absolutely correct, it's primarily used in C++. It's possible to use it in XVI but it's far more involved then using the method described above. I think it has been left in the auto code because it's possible to do but realistically it's not worth the effort.
0 Kudos
Message 7 of 8
(3,771 Views)
Hi John,

Yeah, that routine did look abit involved and didn't seem worth all the effort. There was another function, CA_CreateObjHandleFromIDispatch () which seemed to be a lot easier to use, but it was listed as being obsolete and had been superceded by CA_CreateObjHandleFromInterface().


Regards
Ray Farmer
Regards
Ray Farmer
0 Kudos
Message 8 of 8
(3,764 Views)