跳到主要内容

DC 配置

什么是 DC?

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

DC 对设备的好处
  • 多轴同步运动 — 所有伺服驱动器在同一时刻更新位置指令,消除轴间抖动,轨迹插补更平滑
  • IO 同步采样 — 所有输入输出在同一时刻,主站读取时数据一致,适合高速控制和测量
  • 精确 I/O 时间戳 — 输入数据带有硬件时间戳,主站可精确知道采样发生的物理时刻
  • 确定性输出 — 输出在固定时刻生效,不受 EtherCAT 帧到达时间的抖动影响,降低系统延迟和不确定性

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

相关页面

属性

属性类型说明
has_dcbool网络中是否有支持 DC 的从站
master_dc_timeint最近一次 FRMW 取回的 64-bit DC 系统时间 (ns, 纪元 2000-01-01 UTC)
reference_clock_slave_indexint参考时钟从站索引 (1-based), 无 DC 从站时返回 0

master_dc_time

@property
def master_dc_time(self) -> int

最近一次 FRMW (Read-Multiple-Write) 取回的 64-bit DC 系统时间。

  • 单位: 纳秒
  • 纪元: 2000-01-01 00:00:00 UTC (EtherCAT DC 标准)
  • 返回 0 的情况: DC 未激活 / 尚未完成 DC 配置
每 PDO 周期更新一次

master_dc_time 由主站周期帧中的 FRMW 子帧自动刷新, 采样频率等于 loop_cycle

reference_clock_slave_index

@property
def reference_clock_slave_index(self) -> int

参考时钟从站索引 (1-based)。主站在配置 DC 时自动选择网络拓扑中第一个支持 DC 的从站作为参考时钟。

返回值:

  • int — 从站索引 (1-based)
  • 0 — 无 DC 从站

示例 — 查询 DC 时间与参考时钟:

t_ns = master.master_dc_time
ref = master.reference_clock_slave_index

if t_ns > 0:
seconds_since_2000 = t_ns / 1_000_000_000
print(f"DC 时间: {t_ns} ns ({seconds_since_2000:.6f} s since 2000-01-01)")
print(f"参考从站: #{ref}")
else:
print("DC 未激活")
转换为日期时间
from datetime import datetime, timezone, timedelta

dc_epoch = datetime(2000, 1, 1, tzinfo=timezone.utc)
t_ns = master.master_dc_time
if t_ns > 0:
dc_dt = dc_epoch + timedelta(microseconds=t_ns // 1000)
print(f"DC 对应 UTC 时间: {dc_dt.isoformat()}")

方法

configure_dc()

def configure_dc(self, sync0_ns: int, sync1_ns: int = 0) -> int

为所有 DC 从站配置 DC 同步。

默认自动完成:

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

参数:

  • sync0_ns (int) — SYNC0 周期(纳秒),0 表示禁用 DC
  • sync1_ns (int) — SYNC1 增量时间(纳秒),0 表示仅 SYNC0

返回值:

  • int — 成功配置的 DC 从站数量

示例:

master.configure_dc(1_000_000)                # SYNC0 = 1ms
master.configure_dc(1_000_000, 500_000) # SYNC0 = 1ms, SYNC1 = 500us
推荐配置

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

master.config.loop_cycle = 125_000    # PDO 交换周期 125us
master.configure_dc(125_000) # SYNC0 = 125us

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

master.config.loop_cycle = 1_000_000  # PDO 交换周期 1ms
master.configure_dc(1_000_000) # SYNC0 = 1ms
  • SYNC0 与 loop_cycle — 应保持一致或为其整数倍,数据未到达的同步没有意义
  • 偏移自动计算 — 主站通过 auto_calculate_dc_shift() 自动测量传播延迟并计算
  • 过采样例外 — Oversampling 设备中 SYNC0 < loop_cycle,需设备硬件和 PDO 映射专门支持
关于 SYNC1

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

与从站级配置的区别
  • master.configure_dc() — 一次性配置所有 DC 从站
  • DcConfig.configure() — 配置单个从站(参见 从站 DC 同步

enable_continuous_measurement()

def enable_continuous_measurement(self, enable: bool = True, interval_sec: int = 10) -> None

启用或禁用持续传播延迟测量(ETG.1500 5.13.2)。

示例:

master.enable_continuous_measurement(True, 60)  # 每 60 秒重新测量

同步窗口监控

# 阈值:默认 1000ns
master.diagnostics_info.sync_window_threshold = 500 # 设为 500ns

# 事件
def on_sync_lost(mi, si, diff_ns):
print(f"从站 {si} DC 同步丢失: 偏差 {diff_ns}ns")

master.set_dc_sync_lost_callback(on_sync_lost)

max_sync_difference

@property
def max_sync_difference(self) -> int

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

示例:

print(f"最大同步偏差: {master.max_sync_difference}ns")

all_slaves_in_sync

@property
def all_slaves_in_sync(self) -> bool

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

示例:

if not master.all_slaves_in_sync:
print("存在从站同步偏差过大")

reset_all_sync_window_stats()

def reset_all_sync_window_stats(self) -> None

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

示例:

master.reset_all_sync_window_stats()
单个从站

单个从站的同步窗口详细状态请使用 slave.get_sync_window_status(),包含 diff_ns、max_diff_ns、min_diff_ns、in_sync、out_of_sync_count。

DC 漂移补偿

enable_drift_compensation()

def enable_drift_compensation(self, enable: bool = True,
threshold_ns: int = 1000, gain: int = 1) -> None

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

参数:

  • enable (bool) — True 启用,False 禁用
  • threshold_ns (int) — 触发补偿的偏差阈值(纳秒),偏差低于此值时不做修正,默认 1000ns
  • gain (int) — 补偿增益,控制修正速率(值越大修正越快但可能引入振荡),默认 1

示例:

# 使用默认参数启用漂移补偿
master.enable_drift_compensation(True)

# 自定义参数:500ns 阈值,较低增益(更平滑的修正)
master.enable_drift_compensation(True, threshold_ns=500, gain=256)

# 禁用漂移补偿
master.enable_drift_compensation(False)
推荐

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

完整示例

125us 高性能(WDK 驱动)

with EtherCATMaster() as master:
master.set_eni(r"C:\config.deni")
master.set_network(r"\\Device\\NPF_{GUID}")

# 配置周期
master.config.loop_cycle = 125_000

# 切换到 SafeOp
master.set_state(EcState.SAFE_OP)

# 配置 DC
if master.has_dc:
master.configure_dc(125_000)

import time
time.sleep(1)

# 切换到 OP
master.set_state(EcState.OP)

# 监听 DC 同步丢失事件
def on_sync_lost(mi, si, diff_ns):
print(f"从站 {si} DC 同步丢失: 偏差 {diff_ns}ns")

master.set_dc_sync_lost_callback(on_sync_lost)

持续测量与同步监控

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

# 同步窗口监控
if not master.all_slaves_in_sync:
print(f"同步偏差过大: {master.max_sync_difference}ns")

# 重置统计
master.reset_all_sync_window_stats()
SM 同步类型配置

SM 同步类型通过从站级 slave.configure_dc(mode, ...) 方法自动配置,无需手动调用。详见 从站 DC 同步