将 FB1 传递给具有 FB2 的程序,这些程序想要使用 FB1 正在实现的接口

passing FB1 to programs with FB2s that want to use the interface that FB1 is implementing

这是我第一次 post 堆栈溢出,所以这里 ^^。

我正在尝试从“传统”类型的 PLC 编程过渡到 OOP(仍然很新)。我的新项目将有 3 个不同的程序,它们将 运行 一次 运行,所有的都是 运行 在一个主循环中,代码不是太大,因为有一个具有大部分配置且仅通过 ADS 协议将数据传递给 PLC 的独立系统。

我的问题是,在这 3 个程序中,我有许多功能块实例会触发持久数据保存 (FB_WritePersistentData)。我只想要一个 FB_WritePersistent 实例 - 不需要更多实例,更多实例可能只会导致同时写入,我想避免这种情况。

每个程序都有多个功能块,使用接口写入持久数据。

将实现该接口的单个​​ FB 定义传递到我想要使用该接口的所有功能块的正确方法是什么?我的第一次尝试如下:

我如何避免这种情况是通过简单地将持久 FB 传递给实现接口的 FB,如下所示: fb1 : FB_1(main.fbSavePersistent) 但这不是我想要的,因为感觉,嗯,错了:)

我应该改用 REFERENCE_TO 吗?提前感谢您的帮助。

说明

我认为您在这里感到困惑的是接口的相对应用。在结构化文本接口中,接口被作为 REFERENCES 处理,这意味着它们不需要通过 VAR_IN_OUT 进行专门处理,但只要您在尝试调用之前执行适当的检查,就可以将其视为标准 VAR_INPUT他们。

(正如 Uwe 所说,在设计界面时,您还需要考虑到它们可以从多个来源使用,因此我建议使用一种方法将要处理的数据排入队列记录器)

如果你想做一些事情,比如用辅助记录器替换持久数据记录器,或者将记录器更改为发布者,只要你实现接口,以这种方式实现接口会让生活变得更简单正确地在你的新 FB 中,你可以直接用新的记录器替换旧的记录器,一切仍然正常


例子

我将如何处理这种情况的一个非常基本的示例实现(无逻辑):

PROGRAM MAIN
VAR
    Logger1         : fb_PersistentDataLog; // Single data logger
    Source1         : fb_DataSource
                        :=( Logger  := Logger1 ); // Data source
    Source2         : fb_DataSource
                        :=( Logger  := Logger1 ); // Data source
END_VAR

Source1();
Source2();
Interface i_Logger
METHOD EnqueueData : UDINT // Interface method prototype
FUNCTION_BLOCK fb_PersistentDataLog IMPLEMENTS i_Logger
METHOD EnqueueData : UDINT
    // Run code here to enqueue data to logger
FUNCTION_BLOCK fb_DataSource
VAR_INPUT
    Logger          : i_Logger; // Definition of the interface as an input
END_VAR

IF Logger <> 0 THEN // Check interface reference is valid
    Logger.EnqueueData(); // Call interface method
END_IF