NI TestStand

cancel
Showing results for 
Search instead for 
Did you mean: 

Station Globals access (what's wrong?)

I have this function that I created under TS 2.0 to write a boolean value to a TestStand StationGlobal. When I single-step through it there are no errors but the code has no effect (i.e. StationGlobal does NOT change). The function always returns a value of zero!
 
Here are some definitions used.
 
sgName = "StationGlobals.DiagnosticReport"
StationGlobals = "StationGlobals."
 
Can anyone tell me what's wrong?
=========================================================================
 
int Eng_StationGlobalSetValBoolean (char *sgName, int sgValue)
{
  VBOOL      propertyExists = VFALSE;
  VBOOL      bValue = sgValue ? VTRUE : VFALSE;
  int               error = 0;
  ERRORINFO  errorInfo;
  char          *pStr;
 
  // First check if we have a handle to the globals yet
  if (0 == sGlobals)
  {
    oleErrChkReportErrInfo (TS_EngineGetProperty (sTEEngineObj, &errorInfo,
                                                  TS_EngineGlobals, CAVT_OBJHANDLE,
                                                  &sGlobals));
  }
 
  // Next find 'StationGlobals.' in the variable name
  pStr = strstr (sgName, StationGlobals);
  if (NULL != pStr)
    pStr += strlen (StationGlobals);
  else
    pStr = sgName;
   
  // Then check to make sure the property exists
  oleErrChkReportErrInfo (TS_PropertyExists (sGlobals, &errorInfo, pStr, 0,
                                             &propertyExists));
  if (propertyExists)
  {
    oleErrChkReportErrInfo (TS_PropertySetValBoolean (sGlobals, &errorInfo,
                                                      pStr, 0, bValue));
  }
  else
    error = -1;
 
Error:
  return (error);
}
======================================================================
0 Kudos
Message 1 of 12
(4,402 Views)
Hi,
 
You only need to use "DiagnosticReport" and not "StationGlobals.DiagnosticReport" as the lookup string because you are using the StationGlobals as the reference.
 
Hope this helps you
Regards
Ray Farmer
Regards
Ray Farmer
0 Kudos
Message 2 of 12
(4,395 Views)

That is what is used in the final step, which returns without error, but without modifying the value.

Anyone else have a clue?

Hurst C.

0 Kudos
Message 3 of 12
(4,399 Views)
Hi,
 
where do you get the sTEEngineObj value from as you dont pass it as a parameter?
 
Regards
Ray Farmer
Regards
Ray Farmer
0 Kudos
Message 4 of 12
(4,386 Views)
Hi,
 
with TestStand 2.0 you would have used a function call such as:
 
void __declspec(dllexport) __stdcall Eng_StationGlobalSetValBoolean(CAObjHandle seqContextCVI,
        char reportText[1024], short *errorOccurred, long *errorCode, char errorMsg[1024])
{
    int error = 0;
    // ErrMsg errMsg = {'\0'};
    // ERRORINFO errorInfo;
    // char *lastUserName = NULL;   
    // INSERT YOUR SPECIFIC TEST CODE HERE
    // The following code shows how to access a property or variable via the TestStand ActiveX API
    // tsErrChk (TS_PropertyGetValString(seqContextCVI, &errorInfo,
    //                                   "StationGlobals.TS.LastUserName",
    //                                   0, &lastUserName));
Error: 
    // FREE RESOURCES
    // if (lastUserName != NULL)
    //     CA_FreeMemory(lastUserName);
    // 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);
        }
}
 
But with later TestStands you can now define your own parameters but you still have to pass either the SequenceContext reference or a specific reference such as the Engine reference to beable to make use of the TestStand API calls.
 
 
Regards
Ray Farmer
 
Regards
Ray Farmer
0 Kudos
Message 5 of 12
(4,382 Views)

There are a number of Get.../Set... functions in this file (I have not shown all) and they all share sTEEngineObj. The first one requiring it initializes it. As for the path string "StationGlobals. ...", it needs to be that way because it comes out of a .h file and is used elsewhere. I advanced the pointer to beyond the "StationGlobals." because of the sharing. I abhor multiple definitions for essentially the same thing.

Hurst C.

0 Kudos
Message 6 of 12
(4,378 Views)
Well I have egg all over my face! It does work, it's just my testing method. Here's what I did:
 
1) Bring up SeqEdit and view StationGlobals and note the state of the variable of interest. Exit SeqEdit.
2) Bring up my application and perform the action that writes to TestStand StationGlobals (first post above).
3) Bring up SeqEdit and view StationGlobals. Note at this point the variable has not changed. Exit SeqEdit.
4) ShutDown my application.
5) Bring up SeqEdit and view StationGlobals and lo and behold the variable has changed.
 
Why can't I see the change while my application is running?
 
Hurst C.
 
0 Kudos
Message 7 of 12
(4,377 Views)

Hi,

I assume, when you say "my application" that you are running some sort of operator interface as well as the SeqEditor.

Unfortunately, when you launch two TestStand Applications they both share the StationGlobals file as well as other resourses.

I'm surprised you didn't get some sort of warning that the StationGlobals file had changed, when you switched between one application and the other. Anyway you would have had to refresh it by loading the file again, (I think there's a method you can call to do this), before you can see the change.

Regards

Ray Farmer

Regards
Ray Farmer
0 Kudos
Message 8 of 12
(4,372 Views)
Yes, my application is an operator interface. If I have the SeqEdit open when I terminate my application then I do get the 'changed' message dialog and I have the option to load the new values. I thought the whole intent behind StationGlobals was that there was only one instance of a variable, but I believe that my test above disproves that, and that multiple instances can co-exist simultaneously. In my test above I made sure that the SeqEdit was terminated so that each time I invoked it SeqEdit would be forced to read the current values. Instead what actually happens is that SeqEdit reads the StationGlobals as they were prior to invoking my operator interface. In other words, the StationGlobals don't get written to the .ini file until the application exits.
 
Hurst C.
0 Kudos
Message 9 of 12
(4,369 Views)
Hi,
 
You can use the method Engine.CommitGlobalsToDisk() after you have changed the StationGlobals.
 
Regards
Ray Farmer
Regards
Ray Farmer
0 Kudos
Message 10 of 12
(4,334 Views)