Slave API
通过 master.getSlave(n) 访问(1-based 索引)或 master.Slaves() 获取列表。
快速开始
索引访问
Slave slave = master.getSlave(1); // 第1个从站(1-based)
List<Slave> all = master.Slaves(); // 从站列表
int count = master.SlaveCount(); // 从站总数
组访问
// 设置从站分组和分频器
master.getSlave(2).Group((byte) 1);
master.Divider((byte) 1, (byte) 4);
int activeGroups = master.ActiveGroupCount();
提示
组相关属性详见 从站分组。
地址访问
// 物理配置地址(自动分配)
short addr = slave.ConfigAddr();
// 别名地址(EEPROM 中配置,可选)
short alias = slave.AliasAddress();
// 按地址查找
Slave target = master.Slaves().stream()
.filter(s -> s.ConfigAddr() == 0x1001)
.findFirst().orElse(null);
标识访问
String name = slave.Name(); // 设备名称
String driveName = slave.DriveName(); // 驱动名称(SDO 0x1008)
int vendorId = slave.VendorId(); // 厂商 ID
int productId = slave.ProductId(); // 产品 ID
int revision = slave.RevId(); // 修订号
int serial = slave.SerialNumber(); // 序列号
// 按名称查找
Slave target = master.Slaves().stream()
.filter(s -> "EL2008".equals(s.Name()))
.findFirst().orElse(null);
协议访问
| 类别 | 协议 | 方法 | 类型 | 读写 | 说明 |
|---|---|---|---|---|---|
| 过程数据 | PDO | slave.PDO() | PDO | 只读 | 过程数据对象,实时 IO 数据读写 |
| 邮箱协议 | CoE | slave.CoE() | CoE | 只读 | CANopen over EtherCAT,SDO 对象字典访问 |
| 驱动配置 | CiA 402 | slave.CiA402() | CiA402 | 只读 | 伺服驱动器协议,状态机管理与使能控制 |
| CiA 401 | slave.CiA401() | CiA401 | 只读 | 通用 I/O 模块协议,数字/模拟输入输出 | |
| MDP | slave.MDP() | MDP | 只读 | 模块化设备协议,模块检测与自动配置 | |
| 邮箱协议 | SoE | slave.SoE() | SoE | 只读 | Servo over EtherCAT,伺服驱动器参数 |
| FoE | slave.FoE() | FoE | 只读 | File over EtherCAT,文件传输 | |
| EoE | slave.EoE() | EoE | 只读 | Ethernet over EtherCAT,以太网隧道 | |
| AoE | slave.AoE() | AoE | 只读 | ADS over EtherCAT,Beckhoff ADS 协议 | |
| VoE | slave.VoE() | VoE | 只读 | Vendor over EtherCAT,厂商特定协议 | |
| FSoE | slave.FSoE() | FSoE | 只读 | Functional Safety over EtherCAT,功能安全协议 |
PDO 数据读写
详细的 PDO 读写方式请参见 PDO 输入输出。
进 OP 后把 packed Structure 映射到过程映像,多线程直接改字段:
@FieldOrder({"statusWord", "actualPosition"})
public static class InPdo extends Structure {
public short statusWord;
public int actualPosition;
public InPdo() { super(ALIGN_NONE); }
}
@FieldOrder({"controlWord", "targetPosition"})
public static class OutPdo extends Structure {
public short controlWord;
public int targetPosition;
public OutPdo() { super(ALIGN_NONE); }
}
PDO pdo = slave.PDO();
InPdo inputs = pdo.inputsMapping(InPdo.class);
OutPdo outputs = pdo.outputsMapping(OutPdo.class);
outputs.controlWord = 0x000F;
outputs.write();
System.out.println("当前位置: " + inputs.actualPosition);
EMCY 紧急消息
EtherCAT 从站在检测到异常时会发送 EMCY(Emergency)紧急消息。通过 slave.CoE() 访问,详见 CoE — EMCY 紧急消息。
// 获取紧急消息历史
List<CoE.EmergencyMessage> history = slave.CoE().GetEmergencyHistory();
for (CoE.EmergencyMessage msg : history) {
System.out.printf("错误码: 0x%04X, 寄存器: 0x%02X%n",
msg.ErrorCode, msg.ErrorRegister);
}
// 清除紧急消息历史
slave.CoE().ClearEmergencyHistory();
拓扑查询
通过 master.TopologyChildren / master.TopologyRoots 获取拓扑关系,实现拓扑树的遍历。
master.SlaveTopology().Count() 返回根节点数(入口端口类型为 MII,或 ParentStation()==0 直连主站)。EBUS 模块挂在耦合器下不算根。不是 master.SlaveCount()(全网从站数)。从站级 slave.Topology().Count() 无主站列表,返回 0。
// 重建拓扑(通常在进入 OP 后调用一次)
master.rebuildTopology();
int roots = master.SlaveTopology().Count();
// 遍历拓扑树
void printTree(int slaveIdx, int depth) {
String indent = " ".repeat(depth * 2);
Slave slave = master.getSlave(slaveIdx);
System.out.printf("%s[%d] %s%n", indent, slaveIdx, slave.Name());
for (int child : master.TopologyChildren(slaveIdx)) {
printTree(child, depth + 1);
}
}
for (int root : master.TopologyRoots()) {
printTree(root, 0);
}