Pass a cicode global variable argument into a function that is called by a super genie graphic window

 I am having trouble passing a global cicode variable to the BlockedTrnSetPen function, which is called by the trend pop up page (super genie).

//**************************** GLOBAL VARIABLES *****************************
GLOBAL STRING TrendPen1;
GLOBAL STRING TrendPen2;
GLOBAL STRING TrendPen3;
GLOBAL STRING TrendPen4;

Super genie cicode function call by event on 'On page shown'

BlockedTrnSetPen(86,1,( TrendPen1) )

INT
FUNCTION
BlockedTrnSetPen(INT hAN, INT nPen, STRING sTrend)
INT timeout = 5000
INT sleepTime = 10
INT error = -1
INT elapsed = 0
INT currentTime
STRING sPenName
error = TrnSetPen(hAN, nPen, sTrend)
IF error = 0 THEN
error = -1
currentTime = SysTime()
WHILE error <> 0 AND elapsed < timeout DO
sPenName = TrnGetPen(hAN, nPen)
IF sPenName = sTrend THEN
error = 0
ELSE
SleepMS(sleepTime)
elapsed = elapsed + SysTimeDelta(currentTime)
END
END
END
RETURN error
END

In debug first two arguments are passed ok but global variable argument debug shows bad  and value of 0.00 for global variable string argument.

Any thoughts?

Thanks

Daryl

  •  Hi  
    Have those global variables been initialized before they are used? They should be initialized with the default trend tag names in the startup Cicode function in your project.

    ~jacky

  • Hello Jacky and thanks for your reply.

    I have used Citect for quite a few years now but only ever hacked around in Cicode.

    I'm not sure quite what you mean by initialized.

    Our startup Cicode is quite simple, not much functionality.

    Do I have to initialize in this section?

    // DESC: This is the routine that gets called on startup of Citect.
    // FUNCTIONS: BB_Startup()
    // ServerActive()
    //
    //**************************** GLOBAL VARIABLES *****************************

    //**************************** GLOBAL CONSTANTS *****************************
    //**************************** MODULE VARIABLES *****************************
    MODULE INT mhSQL_TestConnection=-1; //SQL Handle of test connection to database
    //**************************** MODULE CONSTANTS *****************************

    Again thanks for your help.

    Kindest regards

    Daryl

  • It is the good practice to assign the default values to those Module or Global Cicode variables. You can assign the values in Declaration Statements. For example,

    //**************************** GLOBAL VARIABLES *****************************
    GLOBAL STRING TrendPen1 = "MyTrendTag1";
    GLOBAL STRING TrendPen2 = "MyTrendTag2";

    These default trend tags should be already defined in the system model in your project.

    I suppose that these global variables are assigned with new values dynamically at runtime depending on which trends you are interested in. 

    Also, in your original post, you stated

    BlockedTrnSetPen(86,1,( TrendPen1) )

    Should it read 

    BlockedTrnSetPen(86,1, TrendPen1 )

    No need to use brackets around a global variable  

  • Hello again Jacky and thanks again for your reply.

    I will try defining default values.

    The global variables are being assigned with new values dynamically at runtime. I know this is working as I can see the correct value in the cicode global variable debug window. If I hard code the example trend tag I'm using into the super genie function call, everything works fine.

    The problem is when I try and pass the dynamically assigned global variable arguments into the function, I get a bad value in the debug stack window.

    As for brackets around variable, I have tried no brackets, quotes and myriad of other combinations from scouring cicode forums etc.

    Thanks again for your help.

    Regards

    Daryl

  • If I understand correctly, you try to use a global CICODE variable in a function call on a graphics page.
    That will not work. Cicode variables are only valid in cicode, not on pages, in events, or anywhere else in the system.

    To achieve what you want, you have to use Local Variables. These are tags, declared in the Studio (or Project Editor for older versions), NOT in cicode.

    To understand the difference between the different kinds of tags and variables, you could take a look at KB article 000025797, but unfortunately the scope is not explained very well. I'll list a full reference here:

    Variable type Declared in Scope in Cicode functions Scope in Citect processes Machine scope
    Local cicode variable Cicode (function) Local (within single function) Local (cicode only) Local
    Module cicode variable Cicode (file header) Module (across functions within same cicode file) Local (cicode only) Local
    Global cicode variable Cicode (file header) Global (across all cicode functions) Local (cicode only) Local
    Local Variable Studio Global (across all cicode functions) Local (all purposes) Local
    Variable Tag Studio Global (across all cicode functions) Global (across all processes) Global (across all nodes in network)

    Hope this helps,

    Best regards,

    Patrick

  • Hello Patrick,

    Firstly, thank you very much for your help.

    Yes you did understand correctly.

    The documentation wasn’t crystal clear, saying a cicode global variable couldn’t be used on a graphic page, but I wasn’t sure if that included being passed as an argument to a cicode function that was called from a graphic page.

    Your solution of using a local variable worked perfectly.

    I can’t thank you enough as the problem this function is fixing has plagued the plant for many years.

    Many attempts to fix have been done before but none successful. Hopefully you have been part of a solution to a very long-standing problem.

     

    Kindest regards

     

    Daryl

  • You're welcome, glad I could help.

    I agree that documentation could be improved on this point.

  • You should have gotten compile warnings letting you know they weren't valid tag names to use on pages.

    I know some projects have hundreds of compile warnings that are always ignored, which makes it easy to miss problems like this.

    Another option to access Cicode variables from graphics or other places is to provide Get and Set functions:

    STRING FUNCTION GetTrendPen1()
      RETURN TrendPen1;
    END

    FUNCTION SetTrendPen1(string sPen)
      TrendPen1 = sPen;
    END

    From the graphics, you could then use a command like:

    BlockedTrnSetPen(86,1,GetTrendPen1());

    Also, it's a good idea to prefix Cicode variable names with g for global, m for module, s for string, etc. For example, gsTrendPen1. That helps you avoid getting them mixed up with variable tags and using them in places they aren't allowed.

  • Patrick's post was especially helpful! The easiest way to do what you want is to define the variables as Local Variables. If it is data you want to export out of Citect to other processes or programs via I/O (MODBUS, for example) make them Variable Tags and define their I/O addresses.

  •   nice suggestion to improve the article! Thanks!