首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Windows3:将"F_GetSystemTime“与本地TwinCAT时间同步?

Windows3:将"F_GetSystemTime“与本地TwinCAT时间同步?
EN

Stack Overflow用户
提问于 2019-09-21 06:05:29
回答 2查看 1.1K关注 0票数 0

我正在开发一个应用程序,在这个应用程序中,我使用"F_GetSystemTime“标记高精度数据。此函数返回自1601年1月1日以来的100 1st间隔数。

我还通过NTP服务器将本地Windows时间同步到全球网络时钟。这确保了日历系统时间不会长期漂移。

然而,我遇到了一个问题,"F_GetSystemTime“似乎与Windows时间不同步。在几周的时间里,我的"F_GetSystemTime“出现了明显的漂移。

有没有办法让"F_GetSystemTime“和我的视窗时间保持同步?

EN

回答 2

Stack Overflow用户

发布于 2019-09-21 20:32:57

你可以用你的任务周期的精度来构建一个内部计数器。假设你有一个10ms的plc周期,你可以用10ms的时间戳记录你的数据。如果您想要更精确,您可以使用主plc任务的周期时间下降,或者创建一个周期更快的单独任务。

另一种可能性是使用具有过采样的快速IOs,如el1262。

下面是如何定义内部计数器的原始示例:

声明部分:

代码语言:javascript
复制
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

实现部分:

代码语言:javascript
复制
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’

为您提供10ms精度的正确时间,无需进一步同步。

然后,您可以擦亮字符串,以清除不需要的字符,如DT#、T#或ms。

票数 0
EN

Stack Overflow用户

发布于 2019-09-26 15:47:28

按照Filippos answer中的说明使用FB_LocalSystemTime功能块。它以毫秒为单位提供当前时间,并每隔dwCycle秒同步到Windows时钟。通过这种方式,代码块在被调用时总是给出当前时间,并保持自身同步。我不认为你需要任何缓冲区计算等,只要在每个PLC周期运行这段代码就可以了。

如果你的周期是10ms,那么每次调用输出都会改变10ms。当然,这可能不是99%的准确,但应该可以做到这一点。当时间同步到Windows时间时,前一个值和当前值之间的增量当然会有一些变化。如果不确定,则将同步间隔增加到更小或更高的值。

输出是TIMESTRUCT,它包含日期和时间以及毫秒。只需使用SYSTEMTIME_TO_DT进行转换即可。请记住,毫秒在该转换中是四舍五入的,因此它可能会更改秒数。您可以在SYSTEMTIME_TO_DT之前将毫秒设置为0,以保持秒数不变。

代码语言:javascript
复制
//...

VAR
    LocalSystemTime     : FB_LocalSystemTime;
    FirstTimeUpdateOK   : BOOL; //True after the time was synced OK at least once
    EmptyDateAndTime    : TIMESTRUCT := (wYear := 1970, wMonth := 1, wDay := 1);
END_VAR
VAR_OUTPUT
    SyncedTime          : TIMESTRUCT;
END_VAR




//First, set current time to 1970 if not updated yet.
IF NOT FirstTimeUpdateOK THEN
    SyncedTime := EmptyDateAndTime;
END_IF


//Call the time sync block
LocalSystemTime(
    bEnable := TRUE,    //Keep as TRUE always
    dwCycle := 5        //Sync with windows clock every 5 seconds (change to smaller/higher value to prevent small changes every 5 seconds)
);


IF LocalSystemTime.bValid THEN
    //Everything OK, we have valid time
    FirstTimeUpdateOK:= TRUE;
    SyncedTime := LocalSystemTime.systemTime;


ELSIF FirstTimeUpdateOK THEN
    //We have once had the valid time, but not now. Show error?
    //...
END_IF
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58035625

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档