从站诊断
每个从站提供独立的诊断属性和子对象,可查询端口错误、冗余、DC 同步等信息。
从站基础属性
从站状态(State()、ErrorCode()、IsLost())等基础属性请参考 属性与方法。
配合事件使用
建议通过 事件 驱动异常处理(如 addSlaveStateChangedListener、addSlaveOfflineListener、addDCSyncLostListener),而非轮询。
直接读取从站诊断属性适用于 UI 显示等场景。
主站级诊断
全局通信统计、丢包率、PDO 丢帧汇总请参考 主站诊断。
功能概览
| 功能 | 访问路径 | 说明 |
|---|---|---|
| 通信诊断 | slave.Diagnostics().ReadPortErrors() | ESC 端口错误计数器 |
| 冗余诊断 | slave.RedundancyActivated() 等 | 冗余激活、主/冗余线路断路检测 |
| DC 同步 | slave.DC().GetSyncWindowStatus() | 同步状态、时间差 |
属性
| 类别 | 方法 | 类型 | 说明 |
|---|---|---|---|
| 通信诊断 | ReadPortErrors() | EscPortErrors | 读取 ESC 端口错误计数器 |
| ResetPortErrors() | boolean | 重置端口错误计数器 | |
| LinkQuality() | short | 获取链路质量(0-100%) | |
| 冗余诊断 | RedundancyActivated() | boolean | 冗余被激活。从站未丢失但网络中存在断线,冗余机制正在工作 |
| PrimaryLinkBroken() | boolean | 主线路断路。从主端口 (Port0) 到该从站的路径上存在断线 | |
| SecondaryLinkBroken() | boolean | 冗余线路断路。从副端口 (Port1) 反向到该从站的路径上存在断线 | |
| DC 同步 | DC().GetSyncWindowStatus() | SyncWindowStatus | 同步窗口状态(时间差、是否同步等) |
EscPortErrors 结构:
| 字段 | 类型 | 说明 |
|---|---|---|
| RxError | byte[4] | 各端口 RX 错误计数 [Port0-3] |
| InvalidFrame | byte[4] | 各端口无效帧计数 [Port0-3] |
| LostLink | byte[4] | 各端口链路丢失计数 [Port0-3] |
| HasErrors() | boolean | 是否存在任何错误 |
备注
冗余和 DC 属性始终活跃,无需启用 master.Diagnostics().setEnabled(true)。
ReadPortErrors() 需实时读取从站,不建议高频调用。
通信诊断
ReadPortErrors()
public EscPortErrors ReadPortErrors()
读取从站 ESC 端口错误计数器,返回各端口的物理层错误统计。
返回值:
EscPortErrors-- 端口错误计数器,读取失败返回null
示例:
for (Slave slave : master.Slaves()) {
EscPortErrors errors = slave.Diagnostics().ReadPortErrors();
if (errors != null && errors.HasErrors()) {
System.out.printf("从站 %d: RX错误=%s, 无效帧=%s, 链路丢失=%s%n",
slave.SlaveNum,
Arrays.toString(errors.RxError),
Arrays.toString(errors.InvalidFrame),
Arrays.toString(errors.LostLink));
}
}
拓扑信息
通过 slave.Topology() 访问 SlaveTopology 拓扑信息。
| 方法 | 返回类型 | 说明 |
|---|---|---|
| EntryPort() | byte | 入口端口 |
| ParentPort() | byte | 父端口号 |
| ParentStation() | short | 父站地址 |
| PhysicalType() | byte | 物理类型 |
| TopologyByte() | byte | 拓扑字节 |
| ActivePorts() | byte | 活动端口 |
| ConsumedPorts() | byte | 已使用端口数 |
冗余诊断
直接通过 Slave 属性访问从站的冗余状态。仅在主站启用冗余时有意义。
主站级监控
全局冗余状态和断线点请参考 主站诊断 - 冗余状态。
示例:
for (Slave slave : master.Slaves()) {
if (!slave.RedundancyActivated()) continue;
System.out.print("从站 " + slave.SlaveNum + ": 冗余激活");
if (slave.PrimaryLinkBroken()) System.out.print(", 主线路断路");
if (slave.SecondaryLinkBroken()) System.out.print(", 冗余线路断路");
System.out.println();
}
DC 同步
通过 slave.DC().GetSyncWindowStatus() 访问从站的 DC 同步状态。
主站级监控
全局阈值和事件请参考 主站诊断 - DC 同步。
SyncWindowStatus 结构:
| 字段 | 类型 | 说明 |
|---|---|---|
| DiffNs | int | 当前时间差(纳秒) |
| MaxDiffNs | int | 最大时间差(纳秒) |
| MinDiffNs | int | 最小时间差(纳秒) |
| InSync | boolean | 是否在同步窗口内 |
| OutOfSyncCount | int | 超出同步窗口次数 |
示例:
for (Slave slave : master.Slaves()) {
if (!slave.HasDC()) continue;
DC.SyncWindowStatus status = slave.DC().GetSyncWindowStatus();
if (status != null) {
System.out.printf("从站 %d: 时间差=%dns, 同步=%b%n",
slave.SlaveNum, status.DiffNs, status.InSync);
}
}
完整示例
for (Slave slave : master.Slaves()) {
System.out.println("--- 从站 " + slave.SlaveNum + ": " + slave.Name() + " ---");
// 端口错误
EscPortErrors errors = slave.Diagnostics().ReadPortErrors();
if (errors != null && errors.HasErrors()) {
System.out.printf(" 端口错误: RX=%s, 无效帧=%s, 链路丢失=%s%n",
Arrays.toString(errors.RxError),
Arrays.toString(errors.InvalidFrame),
Arrays.toString(errors.LostLink));
}
// 冗余(仅冗余模式下有意义)
if (slave.RedundancyActivated()) {
System.out.printf(" 冗余激活: 主线路断=%b, 冗余线路断=%b%n",
slave.PrimaryLinkBroken(), slave.SecondaryLinkBroken());
}
// DC 同步
if (slave.HasDC()) {
DC.SyncWindowStatus status = slave.DC().GetSyncWindowStatus();
if (status != null) {
System.out.printf(" DC: 时间差=%dns, 同步=%b%n",
status.DiffNs, status.InSync);
}
}
}