从站诊断
每个从站提供独立的诊断属性和子对象,可查询端口错误、冗余、DC 同步等信息。
配合事件使用
建议通过 事件 驱动异常处理(如 on_slave_state_changed、on_slave_offline、on_dc_sync_lost),而非轮询。
功能概览
| 功能 | 访问路径 | 说明 |
|---|---|---|
| 通信诊断 | slave.diagnostics().read_port_errors() | ESC 端口错误计数器 |
| 冗余诊断 | slave.diagnostics().* | 冗余激活、断路检测 |
| DC 同步 | slave.diagnostics().dc().* | 同步状态、时间差 |
通信诊断
read_port_errors()
pub fn read_port_errors(&self) -> Option<EscPortErrors>
读取从站 ESC 端口错误计数器。
pub struct EscPortErrors {
pub rx_error: [u8; 4], // 各端口 RX 错误计数 [Port0-3]
pub invalid_frame: [u8; 4], // 各端口无效帧计数 [Port0-3]
pub lost_link: [u8; 4], // 各端口链路丢失计数 [Port0-3]
}
impl EscPortErrors {
pub fn has_errors(&self) -> bool // 是否存在任何错误
}
备注
read_port_errors() 需实时读取从站,不建议高频调用(建议 >=100ms 间隔)。
冗余和 DC 属性为"始终活跃",无需启用诊断模块。
示例:
for slave in master.slaves().into_iter() {
if let Some(errors) = slave.diagnostics().read_port_errors() {
if errors.has_errors() {
println!("从站 {}: RX错误={:?}, 无效帧={:?}, 链路丢失={:?}",
slave.index(), errors.rx_error,
errors.invalid_frame, errors.lost_link);
}
}
}
冗余诊断
通过 slave.diagnostics() 访问从站的冗余状态。仅在主站启用冗余时有意义。
| 方法 | 类型 | 说明 |
|---|---|---|
| redundancy_activated() | bool | 冗余被激活。从站未丢失,但网络中存在断线,冗余机制正在工作。CRC 故障不触发此标志 |
| primary_link_broken() | bool | 主线路断路。从主端口 (Port0) 到该从站的路径上存在断线。仅检测物理断线 |
| secondary_link_broken() | bool | 冗余线路断路。从副端口 (Port1) 反向到该从站的路径上存在断线。仅检测物理断线 |
示例:
for slave in master.slaves().into_iter() {
if !slave.diagnostics().redundancy_activated() { continue; }
print!("从站 {}: 冗余激活", slave.index());
if slave.diagnostics().primary_link_broken() {
print!(", 主线路断路");
}
if slave.diagnostics().secondary_link_broken() {
print!(", 冗余线路断路");
}
println!();
}
DC 同步
通过 slave.diagnostics().dc() 访问。
| 方法 | 类型 | 说明 |
|---|---|---|
| is_in_sync() | bool | 是否在同步窗口内 |
| sync_time_difference() | i32 | 当前与参考时钟的时间差(纳秒) |
示例:
for slave in master.slaves().into_iter() {
if !slave.has_dc() { continue; }
let dc = slave.diagnostics().dc();
println!("从站 {}: 时间差={}ns, 同步={}",
slave.index(), dc.sync_time_difference(), dc.is_in_sync());
}
从站错误计数器
通过 master.diagnostics_info().read_slave_error_counters() 访问。
pub fn read_slave_error_counters(&self, slave_index: i32) -> SlaveErrorCounters
pub struct SlaveErrorCounters {
pub slave_index: i32,
pub port0_crc_errors: u32,
pub port1_crc_errors: u32,
pub port2_crc_errors: u32,
pub port3_crc_errors: u32,
pub frame_errors: u32,
pub lost_frames: u32,
}
完整示例
for slave in master.slaves().into_iter() {
println!("--- 从站 {}: {} ---", slave.index(), slave.name());
// 端口错误
if let Some(errors) = slave.diagnostics().read_port_errors() {
if errors.has_errors() {
println!(" 端口错误: RX={:?}, 无效帧={:?}, 链路丢失={:?}",
errors.rx_error, errors.invalid_frame, errors.lost_link);
}
}
// 冗余
if slave.diagnostics().redundancy_activated() {
println!(" 冗余激活: 主线路断={}, 冗余线路断={}",
slave.diagnostics().primary_link_broken(),
slave.diagnostics().secondary_link_broken());
}
// DC 同步
if slave.has_dc() {
let dc = slave.diagnostics().dc();
println!(" DC: 时间差={}ns, 同步={}", dc.sync_time_difference(), dc.is_in_sync());
}
}