KEJR Posted November 19, 2009 Posted November 19, 2009 Hello, When using the IDE we would like to not use any manually assigned variables, but rather use the global variables in "symbolic" form via the "global definitions.pmh" file (and the automatically generated header file when using C programs). Are there any cases where we would *not* be able to use the symbolic names in the "global definitions.pmh" file? I.e. I would prefer to never have to type P100 ever again, even in a #define statment. (BTW, being able to query symbolic names in the watch windows and terminal is very nice...) Also, when using C there is no type checking on the function calls (since they accept any unsigned int), so it is easy to use the wrong function call (see following): "global definitions.pmh" file: global TrigJog; csglobal SomeVar; "C" PLC contents: while(GetGlobalVar(SomeVar) == 1); //Whoops, just got the wrong val!! SetCSVar(TrigJog, 1); //Just set wrong Q var.... One nice thing about this is that if you pass a global variable to a function it can be passed as an unsigned int and issue the appropriate API calls to get and set the values. I also like how the vars are called the same thing in all script and C programs with only one definition. One possible "Best Practice" solution would be to define your vars like this: ptr pSomeIOBit, pSomeOtherIO Global gTrigJog, gJogIsBusy, gCrimpStationClearPoint CSGlobal csSomeVar, csSomeOtherVar at least then you can glance at your function call and have a chance of noticing a mistake: //Set wrong var, but it is more //visible to programmer with //naming convention. SetPtrVar(csSomeVar); It still would be nice in the future to have some kind of type checking in the C code, even if it is a warning with a custom preprocessor. I know you guys have alot on your plate, just putting this out there for suggestion.
bradp Posted November 19, 2009 Posted November 19, 2009 Unless we have missed something you can always use the symbolic names. Having the array access on the "P" name is nice for some stuff but it can all be done with symbolic names and IDE array functions. There are other functions to avoid this, but I do not think they are listed in the example program or in the API manual yet. //------------------------------------------------------------------ // Input: pinstr - Pmac Variable (Symbolic version is converted) or variable like 'v', 'p' or 'f' // Output: *pdata - Is strtod of returned data // Return: 0 == OK, - == error number //------------------------------------------------------------------ int GetPmacVar( char *pinstr, double *pdata); //------------------------------------------------------------------ // Input: pinstr - Pmac Variable (Symbolic version is converted) or variable like 'v', 'p' or 'f' // Input: pdata - Is strtod assigned to pinstr // Return: 0 == OK, - == error number //------------------------------------------------------------------ int SetPmacVar( char *pinstr, double data); And you do not have this problem. Since input is a string you can do "&1myvar" for the CS vars.
KEJR Posted November 19, 2009 Author Posted November 19, 2009 Thanks! I'll have to try this string method. It definitely seems safer. Are there any performance penalties of doing this, or is it insignificant? Keep in mind we might have 8-16 tasks making these calls every millisecond. This function call must be interfacing to a command interpreter I would assume?
bradp Posted November 19, 2009 Posted November 19, 2009 In comparison to other methods there is an efficiency penalty. Here is the table. The time is based on an average from 1000 queries. Access Time pSHM->Motor[1].Servo.Kp 0.025 usec GetResponse("Motor[1].Servo.Kp") 10.867 usec GetIVar(130) 0.257 usec GetPmacVar("Motor[1].Servo.Kp") 13.335 usec At the moment GetPmacVar is the slowest and this is because it is essentially the same as GetResponse() with some added overhead. In the future it will change to a method similar to GetIVar() and with the same added overhead I expect responses at around 10 to 15 usec
Recommended Posts