我应该如何处理仅 49 天后的 Codesys SYS_TIME 溢出?

How should I handle Codesys SYS_TIME overflow after only 49 days?

SYS_TIME函数ABBPLC/codesys编程returns一个DWORD表示毫秒数因为 PLC 已打开。 (或者可能是硬重置/其他事件?找不到相关文档。)

Codesys 中 DWORD 的最大大小为 232-1 = 4,294,967,295。

这意味着 SYS_TIME 仅在 49.7 天后溢出!

任何人都可以在 49.7 天过去后确认 SYS_TIME 函数 returns 的确切内容吗?是不是整数溢出又​​从零开始计数了?

这对使用 SYS_TIME 的功能有重要的影响,例如警告自某个事件发生以来的时间。 (例如,通过 modbus 读取远程设备)。

假设它只是一个整数溢出并且 SYS_TIME 重置为零,那么程序员可以通过例如重置他们用来记录最后已知事件时间的变量:

(* Assuming now, last_event_time are suitably declared DWORDs *)
now := SYS_TIME(TRUE);
IF last_event_time > now THEN
    last_event_time := 0;
END_IF
(* continue, performing check of how long since last event occurred etc.... *)

我希望有一些我遗漏的东西可以提供替代方法。

但是 - 这是一个 GOTCHA,它可能会使没有想到这一点的 PLC 程序员绊倒,导致经过广泛测试的表面上功能齐全的 PLC 程序在现场使用 49 天后失败。

如果有 SYS_TIME 的替代方案,returns 一个 LWORD,适合 50 亿年的不间断服务,将会非常有帮助:-)

注意 - 我认为此功能可能特定于 ABB AC500 系列 PLC,而不是标准的 Codesys 功能,因此此问题主要针对 ABB 和 ABB PLC 程序员。

进一步研究,我确认了两件事:

  1. SYS_TIME 绝对是 ABB AC500 的特定功能,包含在库 SysInt_AC500_V10.lib.
  2. 引自 ABB AC500 在线帮助:"An overflow is reached after 49 days. After this, the counter restarts at 0."。这样就回答了关于函数行为的部分。

我的问题的第二部分(处理这个问题的最佳方法是什么?)仍然悬而未决...

选项很少,但我会使用以下任一选项

  1. 读取系统日期和时间并保持更新。使用 DT 时,您将获得 1 秒分辨率。当您首先将它们转换为 DWORD(纪元时间)时,很容易在 DT 之间进行比较。看我的。请注意,如果您计算类似 DT1-DT2 的内容,您将得到 TIME -> 相同的溢出问题的结果。这就是为什么 DT_TO_DWORD 是个好主意。

  2. 自己安排时间。您的 PLC 有一个周期时间,应该始终精确相同。用它来计算。

这是一个具有不同数据类型的简单示例。

请注意,如果需要,也可以使用某些 Codesys 库读取周期时间,但不确定是哪一个。例如参见 [​​=14=].

PROGRAM PRG_Time
VAR CONSTANT
    TASK_CYCLE_TIME_MS  : WORD := 10; //Update this!
END_VAR
VAR_OUTPUT
    Total               : LREAL;
    TotalMilliseconds   : LWORD;
    TotalSeconds        : DWORD;
    Milliseconds        : WORD;
END_VAR

Total := Total + TASK_CYCLE_TIME_MS / 1000.0;
TotalMilliseconds := TotalMilliseconds + TASK_CYCLE_TIME_MS;
Milliseconds := Milliseconds + TASK_CYCLE_TIME_MS;

//Calculate seconds
IF Milliseconds >= 1000 THEN
    TotalSeconds := TotalSeconds + 1;
    Milliseconds := Milliseconds - 1000;
END_IF

LREAL 精确到毫秒。所以基本上这里是一个 SYS_TIME 作为 LWORD (TotalMilliseconds)