Dynamic function call

RikeR
2006-05-16
2007-06-29
  • RikeR - 2006-05-16

    Hey guys,

    Let's say I have some logic which will return a value. Based on the outcome I would like to run a certain program/function block. The values of this logic can vary from say 0 to 100. For example value = 50, run Program 50.

    I've searched the manual and found the ADRINST function, which in my case can come in pretty handy. But the documentation on this function is limited:

    ADRINST

    Adress function, not prescribed by the standard IEC61131-3.

    ADRINST within a function block instance returns the address of the instance in a DWORD. This

    address then can be sent to functions and be treated there as a pointer or it can be assigned to a

    pointer within the project.

    Is there a beter way to handle the problem discribed above, or is there a way to use the pointer returned by the ADRINST function and call a function?

    Greeting,

    RikeR

     
  • RolandWagner

    RolandWagner - 2006-06-27

    The direct call of function blocks e.g. via a string variable with the name of the FB can be realised by the means of some detours.

    What you need in order to do so is the CAA_Callback.lib. This is an external library that provides the function CB_CallFunctionByIndex .

    The call could e.g. look like this:

    dwValue := CB_CallFunctionByIndex(INDEXOF(CallbackFBI1), dwParam1, dwParam2, dwParam3);
    

    Please find the sepcification of the CAA_Callback.lib attached (unfortunately German only).
    It is important that this function can only call another function that fulfils the following requests:

    A possible prototype thus looks like this:

    FUNCTION CallbackFBI1: DWORD
    VAR_INPUT
       Param1: DWORD;
       Param2: DWORD;
       Param3: DWORD;
    END_VAR
    

    Please find a CoDeSys project with the name FB-Pointer-Liste.pro attached. There the following approach is considered:
    If the CAA_Callback.lib is not available you could probably write your own c library. It should have something like this:

    unsigned long CB_CallFunctionByIndex(
                                  short sPOUIndex,
                                  unsigned long ulParam1,
                                  unsigned long ulParam2,
                                  unsigned long ulParam3)
    {
       void* pPlcFunctions;
       unsigned long ulValue = 0;
       if(sPOUIndex != -1)
       {
          pPlcFunctions = RtsGetIecFctPointer(sPOUIndex);
          if (RtsProgramLoaded() && pPlcFunctions != 0)
          {
             ulValue = SysCallWith3Param(
                         (PFCALLBACK)pPlcFunctions,
                         ulParam1,
                         ulParam2,
                         ulParam3
                      );
          }
       }
       return(ulValue);
    }
    

    CAA_Callback.pdf [45.66 KiB]

    CAA_Callback.zip [3.92 KiB]

    FB Pointer Liste.zip [5.4 KiB]

     
  • Avgur - 2007-06-26

    hi!

    I have the similar question. I try to use System event EXCPT_WATCHDOG in Task configuration as follows:

    1) watchdog in main program PLC_PRG is enabled and set to 30 sec;

    2) main program represents endless loop

    WHILE TRUE DO
    ;
    END_WHILE
    

    3) System event EXCPT_WATCHDOG is set, called POU have only one operator ```

    SysResetPlcProgram(0);

    ``` from PLC control system library SysLibPlcCtrl.lib (I want to reset my program when watchdog triggered)

    It seems to be right but doesn't work! Software watchdog of IEC-task never triggers and I can't reset my program at the same time hardware watchdog of ThinkIO always triggers and indicating PLC hang-up.

    Please explain me how I should reset program or completely PLC?

     
  • ljean - 2007-06-29

    Your callback must return 0. Just have a look to the attached program which is working for me with PlcWinNt

    testwd.pro [25.96 KiB]

     

Log in to post a comment.