跳到主要内容

从站诊断

每个从站提供独立的诊断属性和子对象,可查询端口错误、冗余、DC 同步等信息。

从站基础属性

从站状态(State()ErrorCode()IsLost())等基础属性请参考 属性与方法

配合事件使用

建议通过 事件 驱动异常处理(如 addSlaveStateChangedListeneraddSlaveOfflineListeneraddDCSyncLostListener),而非轮询。 直接读取从站诊断属性适用于 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 结构:

字段类型说明
RxErrorbyte[4]各端口 RX 错误计数 [Port0-3]
InvalidFramebyte[4]各端口无效帧计数 [Port0-3]
LostLinkbyte[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 结构:

字段类型说明
DiffNsint当前时间差(纳秒)
MaxDiffNsint最大时间差(纳秒)
MinDiffNsint最小时间差(纳秒)
InSyncboolean是否在同步窗口内
OutOfSyncCountint超出同步窗口次数

示例:

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);
}
}
}