Set Action after using input dialog

  • tehthoams

    tehthoams - 2020-07-14


    I feel this may be an easy answer for someone, but i have exhausted myself trying to find it via search.

    With a visualization input (like numberpad) I need to create an event that calls a function when the value is updated.
    When I use the ST code and input event together, only one or the other functions, not both.

    Is there an easy way to accomplish this?

    Another way of stating the need:
    The structured text code can know when the user updates a specific value via the number pad in order to run some code.

  • tehthoams

    tehthoams - 2020-07-16

    To add to this conversation a bit, here is what I've found:

    This link explains how to use methods to capture user events. It builds a bit on the codesys store example for visualization events.

    While this explanation and the store example might be used to accomplish an automatic action with a user variable change.. it seems to have some very cumbersome requirements. For example, in order to discover which variable was changed by the event, the code has a long series of if statements which compare the pointer address of the changed variable to each and every pointer address you might be interested in. If it matches, then you could decide to do some action in that moment.

    I suppose a function could be written to create a list of pointers that are of interest, and build a bit more functionality to it with a structured data type...

    IF pbVarPointer <> 0 THEN
        IF pbVarPointer = ADR(PLC_PRG.xVar) THEN
        GetVariableName := 'PLC_PRG.xVar';
    ELSIF pbVarPointer = ADR(PLC_PRG.xVar1) THEN
        GetVariableName := 'PLC_PRG.xVar1';
    ELSIF pbVarPointer = ADR(PLC_PRG.xVar2) THEN
        GetVariableName := 'PLC_PRG.xVar2';
    ELSIF pbVarPointer = ADR(PLC_PRG.iVar) THEN
        GetVariableName := 'PLC_PRG.iVar';
    ELSIF pbVarPointer = ADR(PLC_PRG.iVar1) THEN
        GetVariableName := 'PLC_PRG.iVar1';
    ELSIF pbVarPointer = ADR(PLC_PRG.iVar2) THEN
        GetVariableName := 'PLC_PRG.iVar2';
    END_IF ///ETC... keep listing until you got them all
        plInt := pbOldValue;
        sOut := CONCAT('LInt variable ', sVarName);
        sOut := CONCAT(sOut, ' changed from: ');
        sOut := CONCAT(sOut, LINT_TO_STRING(plInt^));
        plInt := pbNewValue;
        sOut := CONCAT(sOut, ' to: ');
        sOut := CONCAT(sOut, LINT_TO_STRING(plInt^));
        VisuElems.Visu_Output(sOut, VisuElems.LogClass.LOG_INFO);

    It then sets up a pointer to the value that changed (need one for each type of value that changes).

    A question:
    If i have a data structure with several elements, and the user changes one of the elements (perhaps an integer).. would this function return the pointer of the data structure or of the individual element that was changed?

  • tehthoams

    tehthoams - 2020-07-16

    Here is the normal 'write a variable' entry. The standard numberpad returns a string of "OK" with the close dialog action.

    Is there any way to call a function with a pointer to the variable being changed with this close dialog option? I see no obvious reference to the variable...

    Instead of write Variable, can use execute ST-Code which opens the dialog, and then continues on to do some other ST code after the dialog is closed?

    I found a very cool possibility that uses custom implicit checks which seems as though they can be used to call functions based on things like variable changes and knowledge if the variable was read or written [Machine Control Studio].

    One example project I found which was part of a customized codesys application set up to automatically call functions to read/write to variables to external components when used normally in code when they had special tags

    {attribute 'get_access' := 'callafunctiontoReadData()'}
    {attribute 'write_access' := fbToSendNetworkMessage()'}
    myVariable: DINT;

    Around their variable declarations. I did not fully understand the mechanism making this happen but found it to be awesomely useful. Variables without these attributes weren't affected by the code...

    I thought using those tags around visualization variables could call an action similarly when written to as a possible solution.

    I hope to start a bit of a discussion about this where:

    if variable <> lastVariable then
    lastVariable := variable;

    isn't sufficient for the situation.

  • tehthoams

    tehthoams - 2020-07-16


    I think your suggestion to use OnDialogClosed makes a lot of sense, and I did a quick test and it does seem to work. The only real issue is that the dialog closes with the escape/cancel or ok. So this code would execute in either case i believe.

    Maybe combining OnDialogClosed with a check of previous value to current value..

  • Morberis

    Morberis - 2020-07-16

    How about using the OnDialogClosed feature from the Input Configuration. Viewable if you put the properties tab into expert/advanced mode. You can have structured text that toggles a variable then you can have logic somewhere that do something and reset that variable. Or have the ST do something else.

    You could also just monitor that variable for any changes and then do something if it does change. In ladder logic I would use the EQ or NE function block possibly followed by R_Trig or F_Trig.

    An example of that would be having a whole page with settings and then a DONE button. When you push the Done button it taps a variable that then write the name of a different visualization to the current visualization variable changing the screen to something else or allowing something to happen.

    Edit: You definitely seem more capable than me so I'm not sure if what I said is helpful.


    Last edit: Morberis 2020-07-16

Log in to post a comment.