跳到主要内容

DC 配置

什么是 DC?

DC(分布式时钟)是 EtherCAT 的硬件级时间同步机制。它让网络中所有从站共享同一个时间基准,使各从站能在完全相同的时刻执行动作。

DC 对设备的好处
  • 多轴同步运动 -- 所有伺服驱动器在同一时刻更新位置指令,消除轴间抖动
  • IO 同步采样 -- 所有输入输出在同一时刻,主站读取时数据一致
  • 精确 I/O 时间戳 -- 输入数据带有硬件时间戳,主站可精确知道采样发生的物理时刻
  • 确定性输出 -- 输出在固定时刻生效,不受 EtherCAT 帧到达时间的抖动影响

主站级 DC 配置。通过 master 直接调用。

相关页面

方法

configureDCAll

public int configureDCAll(int sync0Ns, int sync1Ns)

为所有 DC 从站配置 DC 同步。所有参数单位:纳秒(ns)。默认自动完成:

  1. 传播延迟测量 -- 读取各端口接收时间并计算延迟
  2. 偏移计算 -- 基于传播延迟自动计算每个从站的相位偏移
  3. DC 应用 -- 写入 SYNC0/SYNC1 周期和起始时间到各从站

参数:

  • sync0Ns (int) -- SYNC0 周期(纳秒),0 表示禁用 DC
  • sync1Ns (int) -- SYNC1 增量时间(纳秒),0 表示仅 SYNC0

返回值:

  • int -- 0 表示成功

示例:

master.configureDCAll(1_000_000, 0);           // SYNC0 = 1ms
master.configureDCAll(1_000_000, 500_000); // SYNC0 = 1ms, SYNC1 = 500us
推荐配置

125us 高性能配置(WDK 驱动推荐):

master.Config().LoopCycle(125_000);    // PDO 交换周期 125us
master.configureDCAll(125_000, 0); // SYNC0 = 125us

1ms 常规配置(通用场景):

master.Config().LoopCycle(1_000_000);  // PDO 交换周期 1ms
master.configureDCAll(1_000_000, 0); // SYNC0 = 1ms
  • SYNC0 与 LoopCycle -- 应保持一致或为其整数倍
  • 自动偏移(推荐) -- 主站自动测量传播延迟并计算
关于 SYNC1

SYNC1 是相对于 SYNC0 的增量时间。例如 SYNC0=1,000,000ns, SYNC1=500,000ns 表示 SYNC1 在每个 SYNC0 后 500us 触发。

setMasterDCCycleTime

public void setMasterDCCycleTime(int timeNs)

设置主站 DC 循环时间(纳秒)。

参数:

  • timeNs (int) -- DC 循环时间(纳秒)

autoCalculateDCShift

public int autoCalculateDCShift()

自动计算 DC 偏移。基于传播延迟自动计算每个从站的相位偏移值。

返回值:

  • int -- 计算结果

enableDriftCompensation

public void enableDriftCompensation(boolean enable, int thresholdNs, int gain)

启用或禁用 DC 漂移补偿。漂移补偿在主站侧持续修正系统时钟与 DC 参考时钟之间的偏差,防止长时间运行后同步精度下降。

参数:

  • enable (boolean) -- true 启用,false 禁用
  • thresholdNs (int) -- 触发补偿的偏差阈值(纳秒),偏差低于此值时不做修正
  • gain (int) -- 补偿增益,控制修正速率(值越大修正越快但可能引入振荡)

示例:

// 使用推荐参数启用漂移补偿
master.enableDriftCompensation(true, 1000, 512);

// 自定义参数:500ns 阈值,较低增益(更平滑的修正)
master.enableDriftCompensation(true, 500, 256);

// 禁用漂移补偿
master.enableDriftCompensation(false, 0, 0);
推荐

对于长时间运行的系统(>24小时),建议启用漂移补偿。默认参数适合大多数场景,仅在需要更精细控制时调整阈值和增益。

enableContinuousMeasurement

public void enableContinuousMeasurement(boolean enable, int intervalSec)

启用或禁用持续传播延迟测量(ETG.1500 5.13.2)。启用后主站定期重新测量传播延迟,适用于温度漂移等导致延迟变化的场景。

参数:

  • enable (boolean) -- true 启用,false 禁用
  • intervalSec (int) -- 测量间隔(秒),0 表示使用默认间隔

示例:

master.enableContinuousMeasurement(true, 60);  // 每 60 秒重新测量
master.enableContinuousMeasurement(false, 0); // 禁用
备注

默认情况下 DC 偏移在 configureDCAll() 时一次性计算。仅在长时间运行且环境温度变化较大时启用此功能。

同步窗口监控

主站每秒自动检查各 DC 从站的时间偏差。当从站偏差超出 SyncWindowThreshold 阈值时触发 DCSyncLost 事件。

// 阈值:默认 1000ns,可调整
master.Diagnostics().setSyncWindowThreshold(500); // 设为 500ns

// 事件:从站从"同步"变为"失同步"时触发一次
master.Events().addDCSyncLostListener((masterIdx, slaveIdx, diffNs) ->
System.out.println("从站 " + slaveIdx + " DC 同步丢失: 偏差 " + diffNs + "ns"));

MaxSyncDifference

public int MaxSyncDifference()

获取所有 DC 从站中的最大时间偏差(纳秒)。

返回值:

  • int -- 最大时间偏差(纳秒),失败返回 -1

示例:

int maxDiff = master.MaxSyncDifference();
System.out.println("最大同步偏差: " + maxDiff + "ns");

isAllSlavesInSync

public boolean isAllSlavesInSync()

检查所有 DC 从站是否都在同步窗口内(偏差 <= SyncWindowThreshold)。

返回值:

  • boolean -- 所有从站同步返回 true

示例:

if (!master.isAllSlavesInSync()) {
System.out.println("存在从站同步偏差过大");
}

resetAllSyncWindowStats

public void resetAllSyncWindowStats()

重置所有从站的同步窗口统计(最大/最小时间差、超出同步次数等)。

单个从站

单个从站的同步窗口详细状态请参见 从站 DC 同步

MaxPropagationDelay

public int MaxPropagationDelay()

获取最大传播延迟(纳秒)。

DC 时间查询

用于读取总线当前的 DC 系统时间和参考时钟从站索引。主站每次 PDO 周期通过 FRMW 从参考时钟从站读回 DC 时间,本 API 返回最近一次的缓存值。

getMasterDCTime

public long getMasterDCTime()

获取主站最近一次 PDO 周期取回的 64 位 DC 系统时间。单位纳秒,以 2000-01-01 00:00:00 UTC 为纪元(ETG 规范定义)。

返回值:

  • long — DC 时间(纳秒)。0 表示 DC 未激活或无 DC 从站

示例:

long dcNs = master.getMasterDCTime();
if (dcNs == 0) {
System.out.println("DC 未激活");
} else {
// 2000-01-01 到 1970-01-01 = 946_684_800 秒
long epochMs = dcNs / 1_000_000L + 946_684_800_000L;
System.out.println("DC 时间: " + new java.util.Date(epochMs));
}

getReferenceClockSlaveIndex

public int getReferenceClockSlaveIndex()

获取当前参考时钟从站索引(1-based)。参考时钟是 DC 网络中第一个支持 DC 的从站,所有其他 DC 从站的时间相对它同步。

返回值:

  • int — 参考时钟从站索引(1-based);0 表示总线上无 DC 能力从站

示例:

int refIdx = master.getReferenceClockSlaveIndex();
if (refIdx > 0) {
System.out.printf("参考时钟从站: Slave[%d]%n", refIdx);
} else {
System.out.println("总线上没有 DC 能力从站");
}
与 C# 的对齐

Java 的 getMasterDCTime() / getReferenceClockSlaveIndex() 对应 C# 的 DC.MasterDCTimeNs / DC.ReferenceClockSlaveIndex 属性,语义一致,仅 Java 以 getter 方法形式暴露。

DC 自动偏移

master.setDCAutoShiftEnabled(true);
boolean enabled = master.getDCAutoShiftEnabled();

启用后,主站在 DC 配置时自动计算最优偏移值。

完整示例

125us 高性能(WDK 驱动)

try (EtherCATMaster master = EtherCATMaster.create()) {
master.SetNetwork("\\Device\\NPF_{...}");

// 1. 配置周期 -- 125us(WDK 驱动推荐值)
master.Config().LoopCycle(125_000);

// 2. 切换到 SafeOp
master.setState(EcState.SAFE_OP);

// 3. 配置 DC(自动偏移)-- SYNC0 与 LoopCycle 保持一致
master.configureDCAll(125_000, 0);

Thread.sleep(1000);

// 4. 切换到 Op
master.setState(EcState.OP);
master.Start();

// 监听 DC 同步丢失事件
master.Events().addDCSyncLostListener((masterIdx, slaveIdx, diffNs) ->
System.out.println("从站 " + slaveIdx + " DC 同步丢失: 偏差 " + diffNs + "ns"));
}

持续测量与同步监控

// 长时间运行:启用持续传播延迟测量(温度漂移补偿)
master.enableContinuousMeasurement(true, 60);

// 漂移补偿
master.enableDriftCompensation(true, 500, 256);

// 同步窗口监控
if (!master.isAllSlavesInSync()) {
int maxDiff = master.MaxSyncDifference();
System.out.println("同步偏差过大: " + maxDiff + "ns");
}

// 重置统计
master.resetAllSyncWindowStats();