DC 配置
什么是 DC?
DC(分布式时钟)是 EtherCAT 的硬件级时间同步机制。它让网络中所有从站共享同一个时间基准,使各从站能在完全相同的时刻执行动作。
- 多轴同步运动 — 所有伺服驱动器在同一时刻更新位置指令,消除轴间抖动,轨迹插补更平滑
- IO 同步采样 — 所有输入输出在同一时刻,主站读取时数据一致,适合高速控制和测量
- 精确 I/O 时间戳 — 输入数据带有硬件时间戳,主站可精确知道采样发生的物理时刻
- 确定性输出 — 输出在固定时刻生效,不受 EtherCAT 帧到达时间的抖动影响,降低系统延迟和不确定性
主站级 DC 配置。通过 master 直接调用。
- 单个从站的 DC 配置请参见 从站 DC 同步
- 周期属性请参考 配置 - 周期配置
- DC 同步监控请参考 主站诊断 - DC 同步
属性
| 属性 | 类型 | 说明 |
|---|---|---|
| has_dc | bool | 网络中是否有支持 DC 的从站 |
| master_dc_time | int | 最近一次 FRMW 取回的 64-bit DC 系统时间 (ns, 纪元 2000-01-01 UTC) |
| reference_clock_slave_index | int | 参考时钟从站索引 (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 配置
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 同步。
默认自动完成:
- 传播延迟测量 — 读取各端口接收时间并计算延迟
- 偏移计算 — 基于传播延迟自动计算每个从站的相位偏移
- DC 应用 — 写入 SYNC0/SYNC1 周期和起始时间到各从站
参数:
sync0_ns(int) — SYNC0 周期(纳秒),0 表示禁用 DCsync1_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 是相对于 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) — 触发补偿的偏差阈值(纳秒),偏差低于此值时不做修正,默认 1000nsgain(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 同步类型通过从站级 slave.configure_dc(mode, ...) 方法自动配置,无需手动调用。详见 从站 DC 同步。