在 CodeSys 中初始化多个电机的最佳变量结构

Best variable structure for initialization of several motors in CodeSys

问题

我有一个 PLC 通过 CanOpen 连接到几个电机(它们都是同一类型)。 PLC 使用带有“结构化文本”的 CodeSys 进行编程。为了激活电机,每个电机都必须 运行 通过初始化状态机,为此我必须按顺序发送一些命令(开机、激活等)。但据我所知,我必须为每个必须激活的布尔值明确分配一个变量(mot1_power_on、mot2_power_on、mot1_enable、mot2_enable 等)。

问题

如何使用 CodeSys 和结构化文本有效地初始化多个(同样)电机,其中每个电机都必须 运行 通过初始化状态机?我发现为每个电机和每个变量分配一个 bool,然后多次编写相同的代码是一种不好的做法。如何有效地处理这项任务?有没有办法将电机或某些结构传递给某些功能,然后为每个电机执行此任务?在 C++ 中,我会实例化一个 class 来执行此任务,但是在 CodeSys 中我必须为每个电机显式分配一个变量时如何完成此操作?

背景

我是 codesys 的新手,但我对 c/c++、matlab、python 和其他编码语言有一定的了解。

使用 C++ 编程后,我假设您熟悉面向对象的编程。 CODESYS 中的功能块非常类似于 OO 语言中的 classes。因此,继续使用您希望使用的任何成员变量和方法创建一个“motors”class。为每个电机实例化此 class(通过单个变量或数组),并确保以某种方式从主程序中调用 运行 所需的任何代码。

我希望感觉不自然的部分是关于 I/O 的部分,这就是你说“为每个布尔值分配一个变量”时所指的内容。因为在您的项目中,您需要读取和写入的(可能是 BIT 而不是 BOOL)值具有硬件地址(如 %I12.3、%Q3.2)。一旦你有了 classes/instances,你仍然需要告诉每个实例在哪里找到它自己的 I/O。您不想为此使用单独的全局变量,这可能会导致代码重复,对吗?

这是一种方法:

  • 为每个要寻址的 I/O 内存块创建一个结构。最简单的情况是所有输入变量都在 I/O 内存中,所有输出变量也在一起,所以这意味着要定义两个结构。这些结构必须与位的 I/O 内存布局位相匹配。

  • 注意 TRUE/FALSE I/O 通常暴露为 BIT 值。当您在结构中包含连续的 BIT 成员时,CODESYS 会将它们打包在字节内(而 BOOL 至少占用一个完整字节)。通常需要 BIT 成员来确保结构与 I/O 内存中值的真实布局相匹配。请注意,除 BIT 之外的所有类型都是字节对齐的;举个例子,BIT变量到BYTE变量之间一个孤独的BIT变量会占用一个完整的字节。

  • 在您的功能块中,使用您的结构作为类型声明变量,具有未定义的地址。

     inputs AT %I*: MY_INPUTS_STRUCTURE;
     outputs AT %Q*: MY_OUTPUTS_STRUCTURE;
    
  • 这些未定义的地址本质上是作为引用。您的功能块的每个实例都将收到其自己的独立引用。然而,为了使它起作用,您必须将那些未定义的地址“映射”到硬件地址。在 CODESYS 下,这可以通过几种方式完成:您可以转到项目中电机的映射页面并分别为每个变量执行此操作,或者您可以将 VAR_CONFIG 添加到您的项目中,这将允许每个结构都有一个映射(无需单独关联结构中的每个变量)。

  • 请注意,当映射整个结构而不是单个变量时,如果现场总线字节顺序,则在使用多字节类型时可能会有字节顺序(小端与大端)问题需要处理不同于 CPU 字节顺序。

一开始可能看起来有点重,但一旦你发现它真的不是,它允许你用 I/O 创建功能块,可以放在库中并在许多项目中重复使用.