Search code examples
ooptwincatcodesys

TwinCat3 how to efficiently setup the EventLogger in an OOP?


I'm still very new to OOP and TwinCat so please bear with me. I'm currently developing the software for a small machine that will be used combined with the TF2000 HMI. Because the Event Grid takes away a lot of work I want to set up the TC3 EventLogger. I understand how you create alarms etc. and I can display them in the HMI Event Grid.

It works great with single events, but now I want to take it further and add the errors of every function block. For example FB_TemperatureController can report overheat, FB_Motor can report a stop error and so on.

How do I setup the event logger so I can send the same error from every instantiated FB?

I thought of creating a FB_FaultHandler:

FUNCTION_BLOCK FB_FaultHandler
VAR
    fbEventLogger       : FB_TcEventLogger;
    aMessages           : ARRAY [0..100] OF Fb_TcMessage;
    aAlarms             : ARRAY [0..100] OF Fb_TcAlarm;
END_VAR

METHOD init
VAR_INPUT
END_VAR

aAlarms[0].CreateEx(Tc_Events.AlarmEvents.Error_Overtemp, TRUE, 0);
aAlarms[1].CreateEx(Error2, TRUE, 0);
aAlarms[2].CreateEx(Error3, TRUE, 0);
aAlarms[3].CreateEx(Error4, TRUE, 0);
aAlarms[4].CreateEx(, TRUE, 0);
aAlarms[5].CreateEx(, TRUE, 0);
aAlarms[6].CreateEx(, TRUE, 0);

There's a few things I don't like about this tho:

  1. The source of the event would always be FB_FaultHandler but I want it to display the concerning FB
  2. I'm not sure how to raise an alarm from different instances twice. For example: fbTemp1 and fbTemp 2 are both instances of FB_TemperatureController. Now if I create a "SetFault" Method in the FB_FaultHandler, which raises and confirms an alarm it would raise the same error twice without me knowing the source.
METHOD setError
VAR_INPUT
  nErrorId: INT;
  bErrorActive: BOOL;
END_VAR
  1. I'd prefer if the array would be set up with the id of an event. So "Error_Overtemp" has id 96 and the FB_FaultHandler will put it in aAlarms[96]

I haven't really found any real samples about this anywhere. I watched the Webinar but it honestly is described very poorly. I'd be thankful for any help, input or examples of a good event logger.


Solution

  • Off the top of my head with some help of the internet. Don't have a system for compiling at hand. But you could do something like this code below.

    Essential there is a baseclass for logging (your FB_FaultHandler). From this all classes with logging functionality can be derived from. It uses reflection for the instance path. I never used reflection in twincat as I usually solve this kind of problem a little different. But it is the most generic solution I guess.
    An example for the final class is FB_MyClassesWithLoggingFunctionality.

    There is also a small stub for the initialization code in MAIN. You have to initialize and trigger the setting of Info Class FB_SourceInfo. It sets the instance information in the FB_SourceInfo. That is a class that you can handover to the CreateEx Method and should provide the source of the instance information.

    In the below example of MAIN the source info would be like -project-.MAIN.fbClass

    // -------------- Base class for all classes with logging
    {attribute 'reflection'}
    FUNCTION_BLOCK FB_FaultHandler
    VAR
        {attribute 'instance-path'}
        {attribute 'noinit'}
        sErrorSource : STRING; // make sure that this variable is large enough to hold the path
    
        fbFaultInfo : FB_SourceInfo;
    
        fbEventLogger       : FB_TcEventLogger;
        aMessages           : ARRAY [0..100] OF Fb_TcMessage;
        aAlarms             : ARRAY [0..100] OF Fb_TcAlarm;
    END_VAR
    
    
    METHOD InitInfo
    fbFaultInfo.InitInfo(sErrorSource);
    // example: use faultInfo
    aAlarms[0].CreateEx(Tc_Events.AlarmEvents.Error_Overtemp, TRUE, fbFaultInfo);
    END_METHOD
    
    METHOD logError
    VAR_INPUT
        errorId : INT;
    END_VAR
    END_METHOD
       // Raise error
    END_FUNCTION_BLOCK
    
    
    // ------------ FB for source Info
    FUNCTION_BLOCK FB_SourceInfo IMPLEMENTS I_TcSourceInfo 
    VAR
        sSourceInfo : STRING
    METHOD InitInfo
    VAR_INPUT
        source : STRING
    END_VAR
    sSourceInfo := source;
    
    END_METHOD
    
    
    END_FUNCTION_BLOCK
    
    // ------------------  Final class that has logging functions
    FUNCTION_BLOCK FB_MyClassesWithLoggingFunctionality EXTENDS FB_FaultHandler
    
    METHOD DoSomething
    VAR_INPUT
    
    END_VAR
    
    IF bError then
        logError(id);
    END_IF
    END_METHOD
    
    
    // Usage
    PROGRAM MAIN
    VAR
        fbClass : FB_MyClassesWithLoggingFunctionality;
        bInit : BOOL;
    END_VAR
    IF NOT bInit THEN
        fbClass.InitInfo();
        bInit := FALSE;
    END_IF
    
    END_PROGRAM