DC 同步
从站级 DC(分布式时钟)配置。DC 属性直接通过 slave.* 访问,DC 配置方法通过 DcConfig 类操作。
大多数场景建议使用 master.configure_dc() 一次性配置所有 DC 从站。
从站级方法适用于需要对个别从站设置不同参数的场景。
只读属性
| 类别 | 属性 | 类型 | 说明 |
|---|---|---|---|
| DC 状态 | has_dc | bool | 是否支持 DC (ESC 硬件 bit) |
| has_esi_dc_sync | bool | ESI 是否声明此从站使用 DC 同步 (启用 DC 前应同时为真) | |
| dc_active | int | DC 激活状态(0=禁用, 非0=已激活) | |
| DC 时间 | dc_cycle0 | int | 当前 SYNC0 周期(纳秒) |
| dc_cycle1 | int | 当前 SYNC1 周期(纳秒) | |
| dc_shift | int | 当前相位偏移(纳秒) | |
| propagation_delay | int | 帧从主站到达此从站的传播延迟(纳秒) | |
| DC 拓扑 | dc_next / dc_previous | int | DC 链中下一个/上一个从站索引 |
| dc_parent_port | int | DC 父端口号 | |
| dc_receive_time_a/b/c/d | int | 各端口接收时间(纳秒) |
has_esi_dc_sync
@property
def has_esi_dc_sync(self) -> bool
ESI 文件是否声明此从站使用 DC 同步. has_dc 仅反映 ESC 硬件 bit, 不代表应用层启用 DC. 启用 DC 前应同时检查 has_dc and has_esi_dc_sync, 用于过滤 ESC 报 capable 但 ESI 未声明 DC OpMode 的从站 (如 GCAN-8200), 避免强写 DCCUC 导致从站卡死.
ESI 未加载时保守 fallback 到 has_dc.
示例:
slave = master[1]
if slave.has_dc and slave.has_esi_dc_sync:
master.configure_dc(1_000_000)
else:
print(f"从站 {slave.slave_num} 跳过 DC 配置")
配置方法
DcConfig.configure()
from ethercat import DcConfig
dc = DcConfig(dll, master_index, slave_index)
dc.configure(sync0_cycle_ns: int, sync1_cycle_ns: int = 0,
shift_ns: Optional[int] = None) -> bool
配置从站 DC 同步。所有参数单位:纳秒(ns)。
参数:
sync0_cycle_ns(int) — SYNC0 周期(纳秒),0 表示禁用sync1_cycle_ns(int) — SYNC1 增量时间(纳秒),0 表示仅 SYNC0shift_ns(Optional[int]) — 相位偏移(纳秒):None=自动(0),其他值=手动偏移
返回值:
bool— 配置是否成功
示例:
# 通过 slave.dc_config 公共访问器获取
dc = master[1].dc_config
dc.configure(1_000_000) # SYNC0 = 1ms
dc.configure(1_000_000, 500_000) # SYNC0 = 1ms, SYNC1 = 500us
DcConfig.configure_mode()
dc.configure_mode(mode: DcSyncMode, sync0_cycle_ns: int = 0,
sync1_cycle_ns: int = 0, shift_ns: Optional[int] = None) -> bool
按同步模式配置 DC。
参数:
mode(DcSyncMode) — DC 同步模式sync0_cycle_ns(int) — SYNC0 周期(纳秒)sync1_cycle_ns(int) — SYNC1 周期(纳秒)shift_ns(Optional[int]) — 相位偏移(纳秒)
相关结构 (唯一定义来源: slave/dc.py):
class DcSyncMode(IntEnum):
FreeRun = 0 # 自由运行 (不使用 DC 同步)
SmSynchron = 1 # SM 事件同步
DcSynchron = 2 # DC 同步, 仅 SYNC0 信号
DcSynchron01 = 3 # DC 同步, SYNC0 + SYNC1 信号
ethercat.data.types 也导出 DcSyncMode (大写下划线名 FREE_RUN / SM_SYNCHRON / DC_SYNCHRON, 含义对齐), 推荐统一使用 slave.dc 来源, 避免命名风格混用。
示例:
dc.configure_mode(DcSyncMode.DcSynchron, 1_000_000) # SYNC0 = 1ms
dc.configure_mode(DcSyncMode.DcSynchron01, 1_000_000, 500_000) # SYNC0 + SYNC1
dc.configure_mode(DcSyncMode.FreeRun) # 禁用 DC
DcConfig.disable()
dc.disable() -> bool
禁用此从站的 DC 同步。
同步窗口诊断
slave.sync_window_status
@property
def sync_window_status(self) -> Optional[dict]
获取从站 DC 同步窗口的详细状态。不支持 DC 或读取失败时返回 None。
返回值:
Optional[dict]— 同步窗口状态字典
{
'diff_ns': int, # 当前时间差(纳秒)
'max_diff_ns': int, # 最大时间差(纳秒)
'min_diff_ns': int, # 最小时间差(纳秒)
'in_sync': bool, # 是否在同步窗口内
'out_of_sync_count': int, # 超出同步窗口次数
}
如果只需要 in_sync 或 sync_time_difference,可通过 slave.diagnostics.dc 访问,详见 从站诊断。
DcConfig.get_sync_window_status()
dc.get_sync_window_status() -> Optional[SyncWindowStatus]
通过 DcConfig 获取同步窗口状态,返回 SyncWindowStatus 对象。
SyncWindowStatus 的标准定义在 slave/slave_stats.py (dataclass), 详见 从站诊断。
slave/dc.py 内部存在同名类用于 DcConfig 内部回包, 字段一致, 文档统一以 slave_stats 来源为准。
slave.reset_sync_stats()
def reset_sync_stats(self) -> None
重置此从站的同步窗口统计(最大/最小时间差、超出同步次数等)。
完整示例
slave = master[1] # 1-based 索引
if slave.has_dc:
dc = slave.dc_config # 公共访问器
dc.configure(1_000_000) # SYNC0 = 1ms
print(f"DCActive={slave.dc_active}, DCCycle0={slave.dc_cycle0}ns, DCShift={slave.dc_shift}ns")
# 同步窗口详细状态
status = slave.sync_window_status
if status is not None:
print(f"同步差={status['diff_ns']}ns, 同步={status['in_sync']}")
dc.disable()