跳到主要内容

从站诊断

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

配合事件使用

建议通过 事件 驱动异常处理(如 on_slave_state_changedon_slave_offlineon_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());
}
}