从站诊断
每个从站提供独立的诊断属性和子对象,可查询端口错误、冗余、DC 同步等信息。
从站基础属性
从站状态(State、ErrorCode、IsLost)等基础属性请参考 属性与方法。
配合事件使用
建议通过 事件 驱动异常处理(如 SlaveStateChanged、SlaveOffline、DCSyncLost),而非轮询。
直接读取从站诊断属性适用于 UI 显示等场景。
主站级诊断
全局通信统计、丢包率、PDO 丢帧汇总请参考 主站诊断。
功能概览
| 功能 | 访问路径 | 说明 |
|---|---|---|
| 通信诊断 | slave.Diagnostics.ReadPortErrors() | ESC 端口错误计数器 |
| 冗余诊断 | slave.Diagnostics.* | 冗余激活、主/冗余线路断路检测 |
| DC 同步 | slave.Diagnostics.DC.* | 同步状态、时间差 |
| 类别 | 属性 | 类型 | 访问 | 使能控制 | 说明 |
|---|---|---|---|---|---|
| 通信诊断 | ReadPortErrors() | EscPortErrors? | 只读 | 读取 ESC 端口错误计数器 (寄存器 0x0300-0x0313)。实时读取从站寄存器,失败返回 null | |
| 冗余诊断 | RedundancyActivated | bool | 只读 | 不可停 | 冗余被激活。从站未丢失,但网络中存在断线,冗余机制正在工作 |
PrimaryLinkBroken | bool | 只读 | 不可停 | 主线路断路。从主端口 (Port0) 到该从站的路径上存在断线 | |
SecondaryLinkBroken | bool | 只读 | 不可停 | 冗余线路断路。从副端口 (Port1) 反向到该从站的路径上存在断线 | |
| DC 同步 | DC.IsInSync | bool | 只读 | 不可停 | 是否在同步窗口内(阈值由 master.Diagnostics.SyncWindowThreshold 控制) |
DC.SyncTimeDifference | int | 只读 | 不可停 | 当前与参考时钟的时间差(纳秒) |
EscPortErrors 结构体
| 字段 | 类型 | 说明 |
|---|---|---|
| RxError | byte[4] | 各端口 RX 错误计数 [Port0-3] (0x0300-0x0307) |
| InvalidFrame | byte[4] | 各端口无效帧计数 [Port0-3] (0x0308-0x030B) |
| LostLink | byte[4] | 各端口链路丢失计数 [Port0-3] (0x0310-0x0313) |
| HasErrors | bool | 是否存在任何错误 |
备注
冗余和 DC 属性为"不可停"(始终活跃),无需启用 master.Diagnostics.Enabled。
ReadPortErrors() 需实时读取 ESC 寄存器,不建议高频调用。
通信诊断
ReadPortErrors()
public EscPortErrors? ReadPortErrors()
读取从站 ESC 端口错误计数器(ETG.1000 5.3, 寄存器 0x0300-0x0313),返回各端口的物理层错误统计。
返回值:
EscPortErrors?— 端口错误计数器,读取失败返回null
示例:
foreach (var slave in master.Slaves)
{
var errors = slave.Diagnostics.ReadPortErrors();
if (errors?.HasErrors == true)
{
var e = errors.Value;
Console.WriteLine($"从站 {slave.SlaveNum}: " +
$"RX错误=[{string.Join(",", e.RxError)}], " +
$"无效帧=[{string.Join(",", e.InvalidFrame)}], " +
$"链路丢失=[{string.Join(",", e.LostLink)}]");
}
}
冗余诊断
通过 slave.Diagnostics 访问从站的冗余状态。仅在主站启用冗余时有意义。
主站级监控
全局冗余状态和断线点请参考 主站诊断 - 冗余状态。
示例:
foreach (var slave in master.Slaves)
{
if (!slave.Diagnostics.RedundancyActivated) continue;
Console.Write($"从站 {slave.SlaveNum}: 冗余激活");
if (slave.Diagnostics.PrimaryLinkBroken)
Console.Write(", 主线路断路");
if (slave.Diagnostics.SecondaryLinkBroken)
Console.Write(", 冗余线路断路");
Console.WriteLine();
}
DC 同步
通过 slave.Diagnostics.DC 访问从站的 DC 同步状态。
主站级监控
全局阈值和事件请参考 主站诊断 - DC 同步。
示例:
foreach (var slave in master.Slaves)
{
if (!slave.HasDC) continue;
var dc = slave.Diagnostics.DC;
Console.WriteLine($"从站 {slave.SlaveNum}: " +
$"时间差={dc.SyncTimeDifference}ns, " +
$"同步={dc.IsInSync}");
}
完整示例
foreach (var slave in master.Slaves)
{
Console.WriteLine($"--- 从站 {slave.SlaveNum}: {slave.Name} ---");
// 端口错误
var errors = slave.Diagnostics.ReadPortErrors();
if (errors?.HasErrors == true)
{
var e = errors.Value;
Console.WriteLine($" 端口错误: RX=[{string.Join(",", e.RxError)}], " +
$"无效帧=[{string.Join(",", e.InvalidFrame)}], " +
$"链路丢失=[{string.Join(",", e.LostLink)}]");
}
// 冗余(仅冗余模式下有意义)
if (slave.Diagnostics.RedundancyActivated)
{
Console.WriteLine($" 冗余激活: 主线路断={slave.Diagnostics.PrimaryLinkBroken}, " +
$"冗余线路断={slave.Diagnostics.SecondaryLinkBroken}");
}
// DC 同步
if (slave.HasDC)
{
Console.WriteLine($" DC: 时间差={slave.Diagnostics.DC.SyncTimeDifference}ns, " +
$"同步={slave.Diagnostics.DC.IsInSync}");
}
}