跳到主要内容

冗余 (Redundancy)

EtherCAT 冗余通过双网卡 + 环形拓扑实现链路级容错: 主网口走 primary 帧, 副网口走 secondary 帧, 任一段断线时 SDK 自动从两侧 WKC 合并完成的从站状态, 整个网络仍正常运行.

通过 master 直接调用启用 / 强制故障转移, 通过 master.Diagnostics() 查看冗余诊断.

相关页面

启用与状态

方法返回类型说明
enableRedundancy(boolean)boolean启用 / 禁用冗余 (需在 Start() 之前调用)
forceRedundancyFailover()boolean强制冗余故障切换 (调试 / 维护用)
checkRedundancyHealth()boolean检查冗余健康状态
RingMode()int环拓扑冗余运行模式原始值 (0=Inactive, 1=Dual, 2=Degraded),可用 EtherCATTypes.RingMode.fromValue(...) 转为枚举
SecondaryLinkStatus()boolean副网口链路是否正常
setRedProcessdata(int mode)void设置冗余处理模式
RedProcessdata()int获取当前冗余处理模式

enableRedundancy(boolean)

public boolean enableRedundancy(boolean enable)

启用 / 禁用冗余. 必须在 Start() 之前调用, 且构造主站时已经通过 SetNetwork(primary, secondary) 指定副网卡.

forceRedundancyFailover()

public boolean forceRedundancyFailover()

强制把当前发送路径切到副网口, 调试或预防性维护时使用.

checkRedundancyHealth()

public boolean checkRedundancyHealth()

检查冗余健康状态.

RingMode()

public int RingMode()

获取环拓扑冗余运行模式原始值。返回 int0 / 1 / 2),可用 EtherCATTypes.RingMode 枚举转换为强类型:

int raw = master.RingMode();
EtherCATTypes.RingMode mode = EtherCATTypes.RingMode.fromValue(raw); // INACTIVE / DUAL / DEGRADED

EtherCATTypes.RingMode 枚举:

public enum RingMode {
INACTIVE(0), // 未激活: 冗余监控未初始化
DUAL(1), // 双向冗余: 两端发送 LRW
DEGRADED(2); // 降级模式: 仅 primary 工作
}

SecondaryLinkStatus()

public boolean SecondaryLinkStatus()

副网口链路是否正常.

setRedProcessdata(int mode) / RedProcessdata()

public void setRedProcessdata(int mode)
public int RedProcessdata()

设置 / 获取冗余处理模式.

冗余 WKC 读取 (合并 WKC)

合并 WKC 是权威值, 别拿主口单口 WKC 判故障

环形冗余下, 主帧 (primary) 从 P0 入网走 ring + branch, 副帧 (secondary) 从 P1 入网仅走 ring。某段断开时一侧帧只能看到断点之前的从站, 另一侧从反方向补齐 —— SDK 把两侧 WKC 合并, 得到本周期真正完成 PDO 交换的从站数。

铁律: 合并 WKC == 期望 WKC, 即网络完好; 此时单口 WKC 可以 < 期望, 不是故障。

Java SDK 暴露的是合并后的 WKC —— master.WKC() 已是主+副合并的权威实测值, 直接用它对比 master.ExpectedWKC() 即可判整体健康, 无需 (也无单独的高级方法) 去读主/副单口 WKC。

类别方法返回类型读写说明
合并 WKC (权威)WKC()short只读主+副合并后本周期真正完成交换的从站数
期望 WKCExpectedWKC()short只读拓扑固定真值, 永不下调迁就劣化总线
冗余激活Diagnostics().isRedundancyActive()boolean只读双端口均有流量 (即存在被补偿的断点)

判健康的正确写法 — 以合并 WKC 为准:

// ✅ 正确: 合并 WKC == 期望 WKC, 网络完好 (即使有断点被冗余补偿)
boolean linkHealthy = master.WKC() == master.ExpectedWKC();

if (linkHealthy && master.Diagnostics().isRedundancyActive()) {
System.out.println("有断点, 但冗余已补齐, 网络仍完整 (合并 WKC=" + master.WKC() + ")");
} else if (!linkHealthy) {
System.out.printf("真有从站掉了: 合并 WKC=%d < 期望=%d%n",
master.WKC(), master.ExpectedWKC());
}

完整示例

启用冗余 + 健康监控

try (EtherCATMaster master = EtherCATMaster.create()) {
master.SetNetwork("\\Device\\NPF_{primary-guid}", "\\Device\\NPF_{secondary-guid}");

// 启用冗余 (Start 前调用)
master.enableRedundancy(true);

// 订阅冗余模式变化
master.Events().addRedundancyModeChangedListener((mi, oldMode, newMode) -> {
System.out.printf("冗余模式: %s -> %s%n", oldMode, newMode);
});

master.setState(EcState.OP);
master.Start();

// 周期性健康检查
while (true) {
boolean healthy = master.checkRedundancyHealth();
int mode = master.RingMode();
boolean secOk = master.SecondaryLinkStatus();
System.out.printf("冗余: healthy=%b ring_mode=%d secondary_link=%b%n",
healthy, mode, secOk);
Thread.sleep(1000);
}
}

故障转移演练

// 模拟主网口故障, 强制切到副网口
master.forceRedundancyFailover();
Thread.sleep(500);

// 检查副链路是否承载主路
assert master.SecondaryLinkStatus();
assert master.State() == EcState.OP;
参考
  • ETG.1500 §5.7 Cable Redundancy
  • 其他语言 SDK 对齐: C# EnableRedundancy / Python enable_redundancy / C++ EnableRedundancy / Rust enable_redundancy