NTP-Provider einsetzen

Auf dem CX70xx ist ein NTP-Provider ab Image-Version 140501 oder höher vorhanden.

Der NTP-Provider kann auf verschiedenen CX70xx Embedded-PCs eingesetzt werden, um eine annähernd gleiche Zeit bereitzustellen. Zwischen zwei CX70xx verbleibt typischerweise eine Abweichung von ± 5 ms.

Weitere Informationen dazu, wie der NTP-Provider als TcCOM-Modul in TwinCAT eingefügt und in Betrieb genommen wird, finden Sie hier: https://infosys.beckhoff.com/content/1031/tc3_grundlagen/6326712203.html?id=2077149792280564536

Beispielprogramm für die Verwendung des NTP-Providers

CX7000_NTP_Provider.zip

Variablendeklaration im ST-Editor

PROGRAM TimeSync
VAR
(*
Time format:
FileTime64        8 Byte len        begin 1.1.1601    Bit/100ns
DCTime64          8 Byte len        begin 1.1.2000    Bit/100ns
*)
    Test_FileTime64:T_FILETIME64;    (* not used only to see where
                                      this time begin to see the different *)
    Test_DCTime64:T_DCTIME64;        (* not used only to see where
                                      this time begin to see the different *)


    nLocalTime            : T_FILETIME64;       // Filetime 64 - Local RTOS Time
    nPLC_DC_TASKTime      : T_FILETIME64;       (* Filetime 64 - Local DC Time | Local DC Time =
                                                 System Time see DiffSysTimeToPLCDCTime *)
    nSysTime AT %I*        : T_FILETIME64;      // Filetime 64 - Sytem Time        
    nExtTime AT %I*        : T_FILETIME64;      // Filetime 64 - TCNet Ext NTP Time
    nSysToExtTimeOffset     AT %I*    :LINT;    // Offset this is the offset from ExtTime to SysTime
    nSysToExtTimeDeviation  AT %I*    :LINT;    (* Only for Info: Diff from NTP to the NPT Filter
                                                 time is it < 1ms then is bIsSynchronized = TRUE *)
    
    bIsConnected AT %I*:BOOL;            // Connection to the NTP Server
    bIsSynchronized AT %I*:BOOL;         // see nSysToExtTimeDeviation

    FB_LocalSystemTime: FB_LocalSystemTime;        // Functionblock for read the local RTOS Time
    
    dt_LocalTime: DT;            // Time & data - local RTOS Time
    dt_PLC_DC_TASKTime: DT;      (* Time & data - This is the time from the TaskInfo Array, this
                                  is the same time as the Sytem Time from the NTP Object *)
    dt_nSysTime: DT;             // Time & data - Sytem Time from the NTP Object
    dt_nExtTime: DT;             // Time & data - NTP Object Ext NTP Time
        
    PlcTaskSystemInfo                : PlcTaskSystemInfo;    // Task Info


    DiffSysTimeToPLCDCTime: LINT;            // Local DC Time = System Time
    DiffLocalTimeToExtTime: LINT;            (* local Time - ExtTime = same time like
                                              the nSysToExtTimeOffset Time *)
    FB_EcDcTimeCtrl64_1:FB_EcDcTimeCtrl64;   // FB to get Sec/min/Hour... from a DCTime64
    nExtTime64: ULINT;                       // Format DCTime64 from nExtTime
    sec_1: WORD;                             // nExtTime Sec
    Min_1: WORD;                             // nExtTime Min
    msec_1: WORD;                            // nExtTime mSec

    nLocalTimeDC64: ULINT;                   // DCtime64 - from local filetime64
    MaxPLCTime: UDINT;


    lrTimeoffset: LREAL;              // Offest Time in LREAL [ms]
    lrTimeDeviation: LREAL;           (* Deviation Time [ms] this time show you the diff to the
                                       NTP filter time, if its <1ms the is bIsSynchronized = TRUE *)
    
    FB_CX7000_LED_WD: FB_CX7000_LED_WD;    // NPT Status via WD LED from CX7000


END_VAR

Programm im ST-Editor

PlcTaskSystemInfo:=_TaskInfo[1];      (* Get Task Info Data we need it to read the
                                       PlcTaskSystemInfo.DcTaskTime *)

dt_PLC_DC_TASKTime:=Systemtime_TO_DT(DCTime64_TO_SYSTEMTIME(LINT_TO_ULINT(PlcTaskSystemInfo.DcTaskTime)));         // Get Local DC Time to DT
nPLC_DC_TASKTime:=DCTIME64_TO_FILETIME64(LINT_TO_ULINT(PlcTaskSystemInfo.DcTaskTime));                            // Get Local DC Time to FileTime64

MaxPLCTime:=MAX(PlcTaskSystemInfo.LastExecTime,MaxPLCTime);


lrTimeoffset:=LINT_TO_LREAL(nSysToExtTimeOffset)/1000/10; // Read NTP Offset Time and convert it to Real in [ms]
lrTimeDeviation:=LINT_TO_LREAL(nSysToExtTimeDeviation)/1000/10; // Read NTP Offset Time and convert it to Real in [ms]


// Read the local time from RTOS
FB_LocalSystemTime(
    sNetID:= ,
    bEnable:=TRUE ,
    dwCycle:= ,
    dwOpt:= ,
    tTimeout:= ,
    bValid=> ,
    systemTime=> ,
    tzID=> );

dt_LocalTime:=SystemTime_TO_DT(FB_LocalSystemTime.systemTime);
nLocalTime:=SystemTime_TO_Filetime64(FB_LocalSystemTime.systemTime);

dt_nSysTime:=Filetime64_TO_DT(nSysTime);    // Convert nSysTime to date & time
dt_nExtTime:=Filetime64_TO_DT(nExtTime);    // Convert nExtTime to date & time

DiffSysTimeToPLCDCTime:=ULINT_TO_LINT(nPLC_DC_TASKTime-nSysTime);        // Must be 0 because SysTime = Local DC Time
DiffLocalTimeToExtTime:=ULINT_TO_LINT(nExtTime-nPLC_DC_TASKTime);        // Same diff like nSysToExtTimeOffset

// Ext NTP object as trigger for Outputs
nExtTime64:=FILETIME64_TO_DCTIME64(nExtTime);
FB_EcDcTimeCtrl64_1.A_GetMilli (in:=nExtTime64,get=>msec_1);
FB_EcDcTimeCtrl64_1.A_GetSecond (in:=nExtTime64,get=>sec_1);
FB_EcDcTimeCtrl64_1.A_GetMinute (in:=nExtTime64,get=>Min_1);

// Toggle Outpt every Sec
IF (sec_1 MOD 2) =0 THEN
    gvl.bCX7028_Out_4:=TRUE;
ELSE
    gvl.bCX7028_Out_4:=FALSE;
END_IF


// Set DO NTP Status
gvl.bCX7028_Out_1:=bIsConnected;
gvl.bCX7028_Out_2:=bIsSynchronized;

// WD LED from CX7000
// Red - no connection
// Green flashing - it is connected to NTP Server but it is not sync (that means that the filter is active and the synchonsation to the NTP Server is running - not with TC!)
// Green on - connection and synchonsation is running
FB_CX7000_LED_WD(
    bEnable:=TRUE ,
    eLED:= ,
    tFlashingTimeP1:= ,
    tFlashingTimeP2:= ,
    bError=> ,
    nErrorID=> );
IF bIsConnected AND NOT bIsSynchronized THEN
    FB_CX7000_LED_WD.eLED :=Tc2_SystemCX.E_CX7000_LED.LED_flashing_GREEN_OFF;
ELSIF bIsConnected AND bIsSynchronized THEN
    FB_CX7000_LED_WD.eLED :=Tc2_SystemCX.E_CX7000_LED.LED_GREEN ;
ELSE
    FB_CX7000_LED_WD.eLED :=Tc2_SystemCX.E_CX7000_LED.LED_RED ;
END_IF