跳到主要内容

热连接 (HotConnect)

Hot-Connect 把「扫描时可能不在场」的从站登记成一组。组表是扫描期登记:必须在 set_network / 扫描前调用 add_group。扫描按 Alias 匹配,把组标成 present / absent。不调用 add_group 时所有从站仍是 mandatory(缺失即 AL_ERROR)。扫描时某组缺席不再算错,其余从站可以继续进 OP。

运行中插回不会自动进 OP。 主站可报 Offline/Online;应用层要自己处理状态机。不要指望插回去就自动进 OP;断电重连、换同型号也不会由主站自动拉回 OP。

典型场景:

  • 工艺工位可换装的子工装 (扫描时可不在场的 IO 模块)
  • 需要按产线节拍选用的附加轴
  • 移动 / 可选诊断设备

每个热连接组在配置时声明 预期 (alias_address, vendor_id, product_code)。SDK 在扫描阶段按 Alias 匹配,不在场时不算错。在场也不会在运行中自动加入 OP。

通过 HotConnect::new(master.index()) 构造管理器。​

扫描前登记
  • add_group 必须在 set_network / 扫描前调用
  • 不要用 from_json_file 一步启动后再登记组表(内部已经跑过 set_network)
  • 运行中插回不会自动进 OP;主站可报 Offline/Online,应用层自己处理状态机
Alias 必须先烧录
  • Alias Address (ESC 0x0012) 必须预先烧录到从站 EEPROM, 非 0 且组内唯一
  • Alias=0 的从站不支持 Hot-Connect (ETG.1020 §8.3)

数据结构​

HotConnectGroup​

pub struct HotConnectGroup {
pub group_id: u16, // 用户分配的组 ID, 1..65535
pub alias_address: u16, // 期望 Alias 地址 (ESC 0x0012)
pub vendor_id: u32, // 期望 VendorID, 0 = 不校验
pub product_code: u32, // 期望 ProductCode, 0 = 不校验
pub is_present: bool, // 是否在当前扫描中探测到
pub detected_slave_index: u16, // 匹配到的从站索引 (1-based), 0 = 未匹配
}

HotConnectStatus​

pub enum HotConnectStatus {
Unknown = -1, // 组未注册或底层查询失败
Absent = 0, // 组在当前扫描中未探测到
Present = 1, // 组在当前扫描中探测到
}

HotPlugIdentityMismatch​

pub struct HotPlugIdentityMismatch {
pub master_index: u16,
pub slave_index: u16,
pub expected_vendor: u32,
pub expected_product: u32,
pub expected_revision: u32,
pub actual_vendor: u32,
pub actual_product: u32,
pub actual_revision: u32,
}

常量​

pub const MAX_GROUPS: usize = 32;

每个主站最多支持的 Hot-Connect 组数。

方法​

HotConnect::new()​

pub fn new(master_index: u16) -> Self

构造 Hot-Connect 管理器。

参数:

  • master_index (u16) — 主站编号

add_group()​

pub fn add_group(&self, group_id: u16, alias: u16,
vendor_id: u32, product_code: u32) -> bool

向扫描期组表登记一个 Hot-Connect 组。 须在 set_network / 扫描前调用。 运行中插回不会因本组登记而自动进 OP.

参数:

  • group_id (u16) — 组 ID (1..65535, 同一主站内唯一)
  • alias (u16) — 期望 Alias 地址 (必须非 0)
  • vendor_id (u32) — 期望 VendorID, 0 = 不校验
  • product_code (u32) — 期望 ProductCode, 0 = 不校验

返回值:

  • bool — true = 已写入组表; false = 未登记

示例:

use darra_ethercat::HotConnect;

let hc = HotConnect::new(master.index());
let ok = hc.add_group(1, 0x1001, 0x0000_0002, 0x044C_2C52);

remove_group()​

pub fn remove_group(&self, group_id: u16) -> bool

删除指定 Hot-Connect 组。

group_status()​

pub fn group_status(&self, group_id: u16) -> HotConnectStatus

查询某个组的当前 Present / Absent 状态。

clear_all()​

pub fn clear_all(&self)

清空当前主站所有 Hot-Connect 组定义。

group_count()​

pub fn group_count(&self) -> i32

当前已注册组数。

enumerate()​

pub fn enumerate(&self) -> Vec<HotConnectGroup>

枚举所有已注册的 Hot-Connect 组及其当前状态。

示例:

for g in hc.enumerate() {
println!("组 {} alias=0x{:04X} present={} slave_idx={}",
g.group_id, g.alias_address, g.is_present, g.detected_slave_index);
}

HotPlug 自修复事件​

运行中插回不会自动进 OP。身份不符事件: 同一从站被换成其他设备 / 旧版本固件时触发, 操作员检查 / 更换设备后调用 master.acknowledge_slave_replacement()。应用层要自己处理状态机。

on_hotplug()​

pub fn on_hotplug<F>(callback: F)
where F: Fn(HotPlugIdentityMismatch) + Send + 'static

注册 HotPlug 自修复事件回调。 多次调用可累加多个订阅者。

示例:

use darra_ethercat::master::hot_connect::on_hotplug;

on_hotplug(|ev| {
println!("从站 {} 身份不符: 期望 V=0x{:08X} P=0x{:08X}, 实际 V=0x{:08X} P=0x{:08X}",
ev.slave_index,
ev.expected_vendor, ev.expected_product,
ev.actual_vendor, ev.actual_product);
});

clear_hotplug_listeners()​

pub fn clear_hotplug_listeners()

清空 HotPlug 订阅。

完整示例​

use darra_ethercat::{EtherCATMaster, HotConnect};
use darra_ethercat::master::hot_connect::{on_hotplug, HotPlugIdentityMismatch};

// 手动配置模式:AddGroup → set_network。不要用 from_json_file 一步启动后再登记
let mut master = EtherCATMaster::new()?;
let hc = HotConnect::new(master.index());

// 1. 扫描前登记组表(必须在 set_network / 扫描前)
hc.add_group(1, 0x1001, 0x0000_0002, 0x044C_2C52);
hc.add_group(2, 0x2001, 0x0000_006A, 0x0000_1389);

// 2. 订阅身份不符事件(插回不会自动进 OP,应用层自己处理状态机)
on_hotplug(|ev: HotPlugIdentityMismatch| {
println!("[HotPlug] 从站 {} 身份不符", ev.slave_index);
});

// 3. set_network 扫描按 Alias 匹配,缺席组标 absent
master.set_network(r"\Device\NPF_{YOUR-GUID}", "")?;
master.start();

// 4. Present/Absent 是扫描结果,不是自动进 OP
println!("已注册 {} 个组", hc.group_count());
for g in hc.enumerate() {
println!("组 {} alias=0x{:04X} present={}", g.group_id, g.alias_address, g.is_present);
}

// 5. 切换工艺前清空(通常在重新 set_network 前)
hc.clear_all();
限制
  • DC 主站参考时钟从站不可放进热连接组
  • 同一组内 Alias 必须唯一 (alias=0 不支持 Hot-Connect)
参考
  • ETG.1020 §8 Hot Connect 与 Alias Address
  • ETG.1500 §6.3 Hot Connect Groups