twincat - TwinCAT 3:将“F_GetSystemTime”与本地 Windows 时间同步?
问题描述
我正在开发一个应用程序,在该应用程序中我使用“F_GetSystemTime”对高精度数据进行时间戳记。此函数返回自 1601 年 1 月 1 日以来的 100ns 间隔数。
我还通过 NTP 服务器将本地 Windows 时间同步到全球网络时钟。这可确保日历系统时间不会长期漂移。
但是,我遇到了一个问题,“F_GetSystemTime”似乎与 Windows 时间不同步。在几周的时间里,我的“F_GetSystemTime”出现了明显的偏差。
有没有办法让“F_GetSystemTime”与我的 Windows 时间同步?
解决方案
您可以构建一个具有任务周期精度的内部计数器。假设您有一个 10 毫秒的 PLC 周期,您可以使用 10 毫秒的时间戳记录您的数据。如果您想更精确,您可以减少主要 plc 任务的周期时间,或者创建一个具有更快周期的单独任务。
另一种可能性是使用带有过采样的快速 IO,例如 el1262。
这是一个如何定义内部计数器的原始示例:
声明部分:
PROGRAM MAIN
VAR
bInit : BOOL;
nTime : UINT;
tBufferTime : TIME;
dtBufferDT : DT;
nCalcBuffer : UDINT;
sMs : STRING;
sLogTime : STRING;
sLogTimeWithMs : STRING;
stSystemTime : TIMESTRUCT;
fbLocalTime : FB_LocalSystemTime;
END_VAR
实现部分:
fbLocalTime(bEnable := TRUE);
IF NOT bInit
THEN
dtBufferDT := SYSTEMTIME_TO_DT(fbLocalTime.systemTime);
IF fbLocalTime.bValid
THEN
bInit := TRUE;
END_IF
ELSE
nTime := nTime + 1;
tBufferTime := UINT_TO_TIME(nTime*10);
IF tBufferTime = T#1S
THEN
//Add a second to your system time
ntime := 0;
nCalcBuffer := DT_TO_UDINT(dtBufferDT)+1;
dtBufferDT := UDINT_TO_DT(nCalcBuffer);
sLogTime := DT_TO_STRING(dtBufferDT);
sLogTimeWithMs := sLogTime;
ELSE
//Add ms string time-stamp
sMs := TIME_TO_STRING(tBufferTime);
sLogTimeWithMs := CONCAT(sLogTime,sMs);
END_IF
END_IF
sLogTimeWithMs 将显示如下内容:
'DT#2019-09-21-14:30:28T#530ms'
为您提供 10 毫秒精度的正确时间,无需进一步同步。
然后,您可以对字符串进行润色,以便将其从不需要的字符(如 DT#、T# 或 ms)中清除。
推荐阅读
- google-cloud-platform - Google PubSub Pull 与 Streaming Pull 的区别
- sql - 根据不同列中的值从 Oracle 中的不同组中提取多条记录
- elasticsearch - 如何在二手车网站中通过类似 Google 的搜索查询找到最佳文档(汽车)?
- django - 使用自定义用户模型在管理员中添加员工用户权限
- angular - 为多组件 Angular 应用程序生成 i18n 翻译文件
- excel - 对于重复的 VBA 输入表单(例如,100 个复选框,填充 100 个单元格)有没有办法自动生成代码?
- java - 如何限制整数输入值?
- javascript - agGrid 添加新的动态构造的行
- mysql - 如何使用一个查询在多列中查找所有相同的值
- swift - WKWebview 没有从远程 URL 显示正确的字体