【问题标题】:TwinCat3 how to efficiently setup the EventLogger in an OOP?TwinCat3 如何在 OOP 中有效地设置 EventLogger?
【发布时间】:2022-02-25 01:17:54
【问题描述】:

我对 OOP 和 TwinCat 还是很陌生,所以请多多包涵。我目前正在为一台小型机器开发软件,该软件将与 TF2000 HMI 结合使用。因为事件网格占用了大量工作,所以我想设置 TC3 EventLogger。我了解您如何创建警报等,我可以在 HMI 事件网格中显示它们。

它适用于单个事件,但现在我想更进一步并添加每个功能块的错误。比如FB_TemperatureController可以报告过热,FB_Motor可以报告停止错误等等。

如何设置事件记录器,以便从每个实例化的 FB 发送相同的错误?

我想创建一个 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);

有几件事我不喜欢这个:

  1. 事件源始终是 FB_FaultHandler 但我希望它显示相关的 FB
  2. 我不确定如何从不同的实例两次发出警报。例如:fbTemp1 和 fbTemp 2 都是 FB_TemperatureController 的实例。现在,如果我在 FB_FaultHandler 中创建一个“SetFault”方法,它会引发并确认一个警报,它会在我不知道来源的情况下引发两次相同的错误。
METHOD setError
VAR_INPUT
  nErrorId: INT;
  bErrorActive: BOOL;
END_VAR
  1. 如果数组设置为事件的 ID,我更愿意。因此“Error_Overtemp”的 id 为 96,FB_FaultHandler 会将其放入 aAlarms[96]

我还没有在任何地方找到任何关于此的真实样本。我观看了网络研讨会,但老实说,它的描述非常糟糕。如果有任何帮助、输入或优秀事件记录器的示例,我将不胜感激。

【问题讨论】:

    标签: oop twincat codesys


    【解决方案1】:

    在互联网的帮助下,我的脑海中浮现。手头没有编译系统。但是您可以执行以下代码。

    基本有一个用于记录的基类(您的 FB_FaultHandler)。从这里可以派生所有具有日志记录功能的类。它对实例路径使用反射。我从来没有在 twincat 中使用反射,因为我通常会稍微不同地解决这类问题。但我猜这是最通用的解决方案。
    最后一个类的示例是 FB_MyClassesWithLoggingFunctionality。

    MAIN 中还有一个用于初始化代码的小存根。您必须初始化并触发 Info Class FB_SourceInfo 的设置。它在 FB_SourceInfo 中设置实例信息。这是一个可以移交给 CreateEx 方法的类,并且应该提供实例信息的来源。

    在下面的 MAIN 示例中,源信息类似于 -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
    

    【讨论】:

    • 您好,感谢您的详细解答。我有点困惑你会在你的例子中发出警报。我只看到你用createEx(); 创建它。此外,我必须知道任何 logError(); 方法中的数组索引,对吗?
    • 你是对的。昨天是一个快速破解。 logError 是您用来引发错误的函数。我会用伪代码更新它。
    • 我仍然对您如何区分错误感到有些困惑。假设我有两个FB_Motor 实例。 FB_Motor 调用.InitInfo() 并在aAlarms[0] 中创建警报但现在我遇到的问题是两个实例都会在相同的数组位置上创建警报,即使它们可以在不同时间引发。我是否需要一个 for 循环,它基本上只是跳转到下一个数组索引?
    • 如果一个错误的原因相同,那就是同一个错误。您要区分的是 Motor1 或 Motor2 是否处于错误状态。该信息在 fbFaultInfo 错误源中。它告诉错误的来源。
    • 对不起,我的回答很晚,但与此同时我正忙于另一个项目。感谢您提供的解决方案。您介意快速解释一下您通常如何解决日志记录问题吗?扩展日志记录的基类似乎不是最佳选择,因为这不允许我扩展任何其他类。
    【解决方案2】:

    我建议查看属性“instance-path”的文档。这应该告诉您功能块的哪个实例是源(Motor1 或 Motor2)。你会在那里找到源代码示例。

    https://infosys.beckhoff.com/content/1033/tc3_plc_intro/3108100107.html?id=5092968876405062789

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-24
      • 1970-01-01
      • 1970-01-01
      • 2021-09-27
      • 2014-02-27
      • 2017-02-19
      • 2018-05-06
      相关资源
      最近更新 更多