跳到主要内容

CiA 402 — 伺服驱动器辅助

CiA 402 (IEC 61800-7-204) 是基于 CoE 的伺服驱动器设备协议。CiA402Instance 封装了驱动器状态机管理、操作模式切换和运动参数访问功能。

CiA 402 运行在 CoE (SDO) 之上。CiA402Instance 需要独立构造,不是通过 slave.coe() 链式访问。

两种使用方式: slave.cia402_* vs CiA402Instance

SDK 提供两套 CiA 402 接口, 按场景选择:

slave.cia402_* — 轻量直调 (SDO-only)

挂在 Slave 上的快捷方法, 不依赖 PDO 映射, 全程走 SDO. 适合单次操作 / 调试 / 非周期场景

可用方法:

  • slave.cia402_state()CiA402State — 读当前驱动器状态
  • slave.cia402_enable()Result<()> — 一键使能 (SDO 推进状态机)
  • slave.cia402_set_mode(mode: i8)Result<()> / slave.cia402_mode()i8 — 操作模式读写 (0x6060 / 0x6061)
  • slave.cia402_status_word()u16 — 读 0x6041
  • slave.cia402_write_control_word(cw: u16)Result<()> — 写 0x6040
  • slave.cia402_fault_reset()Result<()> — 复位 0x6040 Bit 7

示例:

let slave = master.slave(1);

// 调试: 上电检查驱动器是否处于 OperationEnabled
println!("当前状态: {:?}", slave.cia402_state());

// 一次性使能 + 读状态
slave.cia402_enable()?;
println!("使能后状态字: 0x{:04X}", slave.cia402_status_word());

CiA402Instance — 高性能完整接口 (PDO + SDO)

需要先通过 Cia402PdoMap::scan() 扫描 PDO 映射, 然后构造完整实例. 0x1C12 / 0x1C13 中已映射的对象走 PDO 零拷贝, 未映射的对象自动回退 SDO. 适合周期运动控制 / 高频读写

典型场景:

  • PDO 周期内频繁读取 ActualPosition / ActualVelocity / StatusWord
  • 周期内写入 TargetPosition / ControlWord, 走 PDO 不阻塞
  • 需要 enable() / quick_stop() / fault_reset() 等高级状态机封装

选择对比

  • 调试 / 离线诊断 / 一次性操作 → 用 slave.cia402_*, 不需要扫描 PDO 映射, 接口简单
  • 周期运动控制 / 实时数据流 → 用 CiA402Instance, 享受 PDO 零拷贝性能
  • 混合: 启动时用 slave.cia402_enable() 一键使能, 进入 OP 后切换为 CiA402Instance 做周期控制 (两者可在同一从站上共存)

构造方式

CiA 402 实例需要先扫描 PDO 映射表,然后独立构造:

use ethercat::{Cia402PdoMap, CiA402Instance};

// 1. 扫描 PDO 映射 (读取 0x1C12/0x1C13)
let pdo_map = Cia402PdoMap::scan(master.index(), 1)?;

// 2. 创建 CiA 402 实例
let drv = CiA402Instance::new(master.index(), 1, pdo_map);

PDO 映射扫描

Cia402PdoMap::scan()

pub fn scan(master_index: u16, slave_index: u16) -> Result<Self>

扫描从站 PDO 映射,读取 0x1C12/0x1C13 系列对象的映射参数,以及从站 IOmap 的 IO 指针,建立完整映射缓存。

映射建立后,CiA402Instance 的读写会优先通过 PDO(零拷贝),不在映射中的对象自动回退到 SDO。

示例:

let pdo_map = Cia402PdoMap::scan(master.index(), 1)?;

// 查看映射信息
for entry in pdo_map.output_entries() {
println!("RxPDO: 0x{:04X}:{:02X} {}bit @offset {}",
entry.od_index, entry.sub_index, entry.bit_length, entry.byte_offset);
}
for entry in pdo_map.input_entries() {
println!("TxPDO: 0x{:04X}:{:02X} {}bit @offset {}",
entry.od_index, entry.sub_index, entry.bit_length, entry.byte_offset);
}

状态控制

enable() 一次性推进到 OperationEnabled (内部完成完整状态链 + Fault 复位 + QuickStop 恢复 + 0x605A 选项码判断); disable / disable_operation / quick_stop / fault_reset 仅写一次 Controlword 后立即返回, 通过 state_drive() 检查结果。

enable(max_retries) / enable_default()

pub fn enable(&self, max_retries: i32) -> bool
pub fn enable_default(&self) -> bool // 等价于 enable(10)

使能驱动器: 内部按 CiA 402-2 完成 SwitchOnDisabled → ReadyToSwitchOn → SwitchedOn → OperationEnabled 全套时序、Fault 复位、QuickStop 恢复。

参数:

  • max_retries — 最大重试次数

返回值:

  • booltrue = 已使能到 OperationEnabled, false = 失败/超时

示例:

// 一次性使能 (内部完成完整状态机)
if drv.enable_default() {
drv.set_target_position(next_position);
} else {
println!("使能失败, 当前状态: {:?}", drv.state_drive());
}

disable()

pub fn disable(&self)

禁用伺服 (-> SwitchOnDisabled),完全断电。

disable_operation()

pub fn disable_operation(&self)

禁用运行 (OperationEnabled -> SwitchedOn)。

quick_stop()

pub fn quick_stop(&self)

快速停止。

fault_reset()

pub fn fault_reset(&self)

清除故障。

状态读取

state_drive()

pub fn state_drive(&self) -> StateCiA402

从 StatusWord 解析当前驱动器状态。

#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum StateCiA402 {
NotReadyToSwitchOn = 0, // 初始化中
SwitchOnDisabled = 1, // 驱动禁用
ReadyToSwitchOn = 2, // 准备就绪
SwitchedOn = 3, // 已开启
OperationEnabled = 4, // 运行使能
QuickStopActive = 5, // 快速停止
FaultReactionActive = 6, // 故障反应中
Fault = 7, // 故障
Unknown = 99, // 未知状态
}

statusword() / controlword()

pub fn statusword(&self) -> u16
pub fn controlword(&self) -> u16
pub fn set_controlword(&self, value: u16)

相关方法:

  • target_reached() -> bool — 目标已到达 (Bit 10)
  • has_fault() -> bool — 存在故障 (Bit 3)
  • has_warning() -> bool — 存在警告 (Bit 7)
  • is_remote() -> bool — 远程模式 (Bit 9)

操作模式

operation_mode() / set_operation_mode()

pub fn operation_mode(&self) -> i8
pub fn set_operation_mode(&self, mode: ModeCiA402)
#[repr(i8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ModeCiA402 {
PP = 1, // 轮廓位置模式
VL = 2, // 速度模式
PV = 3, // 轮廓速度模式
PT = 4, // 轮廓转矩模式
HM = 6, // 回零模式
IP = 7, // 插补位置模式
CSP = 8, // 周期同步位置模式
CSV = 9, // 周期同步速度模式
CST = 10, // 周期同步转矩模式
CSTCA = 11, // 周期同步转矩加速度模式
}

is_mode_supported()

pub fn is_mode_supported(&self, mode: ModeCiA402) -> bool

检查驱动器是否支持指定操作模式(通过 0x6502 SupportedDriveModes 判断)。

运动参数

方法类型访问说明
position_actual()i32只读实际位置 (0x6064)
velocity_actual()i32只读实际速度 (0x606C)
torque_actual()i16只读实际转矩 (0x6077)
target_position() / set_target_position()i32读写目标位置 (0x607A)
target_velocity() / set_target_velocity()i32读写目标速度 (0x60FF)
target_torque() / set_target_torque()i16读写目标转矩 (0x6071)

轮廓参数

方法类型说明
profile_velocity() / set_profile_velocity()u32轮廓速度 (0x6081)
profile_acceleration() / set_profile_acceleration()u32轮廓加速度 (0x6083)
profile_deceleration() / set_profile_deceleration()u32轮廓减速度 (0x6084)
quick_stop_deceleration() / set_quick_stop_deceleration()u32快速停止减速度 (0x6085)

极性与轮廓配置

方法类型说明
polarity() / set_polarity()u8极性 (0x607E)
motion_profile_type() / set_motion_profile_type()i16运动轮廓类型 (0x6086)
quick_stop_option_code() / set_quick_stop_option_code()i16快速停止选项 (0x605A)

触发探针 (Touch Probe)

方法类型说明
configure_touch_probe(function: u16)-配置探针功能 (0x60B8)
touch_probe_status()u16探针状态 (0x60B9)
touch_probe_positive_edge()i32正边沿捕获位置 (0x60BA)
touch_probe_negative_edge()i32负边沿捕获位置 (0x60BB)

数字 IO

方法类型访问说明
digital_inputs()u32只读数字输入 (0x60FD),32 位位图
digital_outputs() / set_digital_outputs()u32读写数字输出 (0x60FE:01),32 位位图

示例:

// 读取数字输入
let inputs = drv.digital_inputs();
let limit_switch = (inputs & 0x01) != 0; // 位 0

// 设置数字输出
drv.set_digital_outputs(0x03); // 输出位 0 和位 1

软件位置限制

方法类型访问说明
software_position_limit_min() / set_software_position_limit_min()i32读写软件位置限位下限 (0x607D:01)
software_position_limit_max() / set_software_position_limit_max()i32读写软件位置限位上限 (0x607D:02)

示例:

// 设置运动范围限制
drv.set_software_position_limit_min(-1_000_000);
drv.set_software_position_limit_max(1_000_000);

扩展运动参数

方法类型访问说明
max_torque() / set_max_torque()u16读写最大转矩 (0x6072),千分之额定
motor_rated_torque() / set_motor_rated_torque()u32读写电机额定转矩 (0x6076),mNm
position_offset() / set_position_offset()i32读写位置偏移 (0x60B0),CSP 模式叠加
velocity_offset() / set_velocity_offset()i32读写速度偏移 (0x60B1),CSV 模式叠加
torque_offset() / set_torque_offset()i16读写转矩偏移 (0x60B2)
interpolation_time_period_value() / set_interpolation_time_period_value()u8读写插补时间周期值 (0x60C2:01)
interpolation_time_period_index() / set_interpolation_time_period_index()i8读写插补时间周期指数 (0x60C2:02),周期 = Value × 10^Index 秒

力矩限制

方法类型访问说明
positive_torque_limit() / set_positive_torque_limit()u16读写正方向力矩限制 (0x60E0),千分之额定
negative_torque_limit() / set_negative_torque_limit()u16读写负方向力矩限制 (0x60E1),千分之额定

回零速度与加速度

方法类型访问说明
homing_speed_search() / set_homing_speed_search()u32读写回零搜索速度 (0x6099:01),快速搜索参考信号
homing_speed_zero() / set_homing_speed_zero()u32读写回零零位速度 (0x6099:02),慢速精确定位零位
homing_acceleration() / set_homing_acceleration()u32读写回零加速度 (0x609A)

示例:

drv.set_operation_mode(ModeCiA402::HM);
drv.set_homing_method(1);

// 设置回零速度和加速度
drv.set_homing_speed_search(5000); // 搜索速度
drv.set_homing_speed_zero(500); // 零位速度
drv.set_homing_acceleration(10000); // 回零加速度

快速运动控制

new_setpoint()

pub fn new_setpoint(&self, position: i32, relative: bool)

PP 模式发送新定位命令。设置目标位置并触发 Controlword Bit 4 (New Setpoint)。

参数:

  • position -- 目标位置
  • relative -- true = 相对定位,false = 绝对定位

示例:

drv.set_operation_mode(ModeCiA402::PP);
drv.set_profile_velocity(10000);
drv.set_profile_acceleration(50000);

// 在 PDO 回调中: 先使能,使能后发送定位命令
if drv.state_drive() == StateCiA402::OperationEnabled {
drv.new_setpoint(100000, false); // 绝对定位到 100000
// drv.new_setpoint(5000, true); // 或相对移动 5000
}

clear_new_setpoint()

pub fn clear_new_setpoint(&self)

PP 模式清除 NewSetpoint 标志(Controlword Bit4=0)。在 target_reached() 后调用,完成 SetPointAck 握手。

示例:

if drv.target_reached() {
drv.clear_new_setpoint();
}

start_homing()

pub fn start_homing(&self)

HM 模式启动回零。需先设置 set_homing_method()

相关方法:

  • homing_method() / set_homing_method() (i8) -- 回零方法 (0x6098)
  • home_offset() / set_home_offset() (i32) -- 回零偏移 (0x607C)
  • homing_attained() (bool) -- 回零完成 (Bit 12)
  • homing_error() (bool) -- 回零错误 (Bit 13)

示例:

drv.set_operation_mode(ModeCiA402::HM);
drv.set_homing_method(35); // 当前位置回零

// 在 PDO 回调中:
if drv.state_drive() == StateCiA402::OperationEnabled {
drv.start_homing();
// 后续周期检查 drv.homing_attained() / drv.homing_error()
}

驱动器信息

supported_drive_modes()

pub fn supported_drive_modes(&self) -> u32

支持的驱动模式位掩码 (0x6502)。Bit 0=PP, Bit 1=VL, Bit 2=PV, Bit 3=PT, Bit 5=HM, Bit 6=IP, Bit 7=CSP, Bit 8=CSV, Bit 9=CST。

supported_homing_methods()

pub fn supported_homing_methods(&self) -> Vec<i8>

读取驱动器支持的回零方法列表 (0x60E3)。返回所有支持的回零方法编号数组。

示例:

let methods = drv.supported_homing_methods();
println!("支持 {} 种回零方法: {:?}", methods.len(), methods);

TxPDO 数据有效性

txpdo_data_invalid()

pub fn txpdo_data_invalid(&self) -> bool

TxPDO 数据是否无效 (0x603E)。非零表示驱动器 TxPDO 数据不可信(如编码器未就绪时位置值无意义)。

if !drv.txpdo_data_invalid() {
let pos = drv.position_actual(); // 数据有效
}

同步功能

方法类型访问说明
synchronization_settings() / set_synchronization_settings()u16读写同步设置 (0x60D9:01)
drive_sync_status()u16只读驱动同步状态 (0x60DA)

完整示例

CSP 模式 — 周期同步位置控制

use ethercat::{Cia402PdoMap, CiA402Instance, ModeCiA402, StateCiA402};

let pdo_map = Cia402PdoMap::scan(master.index(), 1)?;
let drv = CiA402Instance::new(master.index(), 1, pdo_map);

// 设置操作模式
drv.set_operation_mode(ModeCiA402::CSP);

// 一次性使能 (内部完成完整状态机)
if !drv.enable_default() {
println!("使能失败: {:?}", drv.state_drive());
return Ok(());
}

// PDO 回调中每周期下发目标
let events = master.events();
events.on_pdo_cyclic_sync(move |_master_idx| {
drv.set_target_position(calculate_next_position());
});

PP 模式 — 轮廓位置控制

use ethercat::{Cia402PdoMap, CiA402Instance, ModeCiA402};
use std::sync::atomic::{AtomicBool, Ordering};

let pdo_map = Cia402PdoMap::scan(master.index(), 1)?;
let drv = CiA402Instance::new(master.index(), 1, pdo_map);

drv.set_operation_mode(ModeCiA402::PP);
drv.set_profile_velocity(10000);
drv.set_profile_acceleration(50000);
drv.set_profile_deceleration(50000);

// 一次性使能
if !drv.enable_default() {
println!("使能失败: {:?}", drv.state_drive());
return Ok(());
}

// 发送定位命令
drv.new_setpoint(100000, false); // 绝对定位

// PDO 回调等待目标到达后清标志
let homing_done = AtomicBool::new(false);
let events = master.events();
events.on_pdo_cyclic_sync(move |_| {
if !homing_done.load(Ordering::Relaxed) && drv.target_reached() {
drv.clear_new_setpoint();
homing_done.store(true, Ordering::Relaxed);
}
});

HM 模式 — 回零

use ethercat::{Cia402PdoMap, CiA402Instance, ModeCiA402};

let pdo_map = Cia402PdoMap::scan(master.index(), 1)?;
let drv = CiA402Instance::new(master.index(), 1, pdo_map);

drv.set_operation_mode(ModeCiA402::HM);
drv.set_homing_method(35); // 当前位置回零
drv.set_homing_speed_search(5000);
drv.set_homing_speed_zero(500);
drv.set_homing_acceleration(10000);

// 一次性使能
if !drv.enable_default() {
println!("使能失败: {:?}", drv.state_drive());
return Ok(());
}

// 启动回零
drv.start_homing();

let events = master.events();
events.on_pdo_cyclic_sync(move |_| {
if drv.homing_attained() {
println!("回零完成");
}
if drv.homing_error() {
println!("回零错误");
}
});

参数验证

let drv = CiA402Instance::new(master.index(), 1, pdo_map);

// 检查轮廓参数是否满足 PP/PV 模式需求
let warnings = drv.validate_profile_parameters(Some(1)); // PP 模式
for w in &warnings {
println!("警告: {}", w);
}

标准对象索引常量

可搭配 slave.sdo_read/sdo_write 使用:

常量说明
OD_CONTROLWORD0x6040控制字
OD_STATUSWORD0x6041状态字
OD_MODES_OF_OPERATION0x6060操作模式设置
OD_MODES_OF_OPERATION_DISPLAY0x6061操作模式显示
OD_TARGET_POSITION0x607A目标位置
OD_POSITION_ACTUAL0x6064实际位置
OD_TARGET_VELOCITY0x60FF目标速度
OD_VELOCITY_ACTUAL0x606C实际速度
OD_TARGET_TORQUE0x6071目标转矩
OD_TORQUE_ACTUAL0x6077实际转矩
OD_PROFILE_VELOCITY0x6081轮廓速度
OD_PROFILE_ACCELERATION0x6083轮廓加速度
OD_PROFILE_DECELERATION0x6084轮廓减速度
OD_MAX_TORQUE0x6072最大转矩
OD_MOTOR_RATED_TORQUE0x6076电机额定转矩
OD_HOME_OFFSET0x607C回零偏移
OD_SOFTWARE_POSITION_LIMIT0x607D软件位置限制
OD_POLARITY0x607E极性
OD_MAX_PROFILE_VELOCITY0x6080最大轮廓速度
OD_MOTION_PROFILE_TYPE0x6086运动轮廓类型
OD_HOMING_METHOD0x6098回零方法
OD_HOMING_SPEEDS0x6099回零速度
OD_HOMING_ACCELERATION0x609A回零加速度
OD_POSITION_OFFSET0x60B0位置偏移 (CSP)
OD_VELOCITY_OFFSET0x60B1速度偏移 (CSV)
OD_TORQUE_OFFSET0x60B2转矩偏移
OD_TOUCH_PROBE_FUNCTION0x60B8Touch Probe 功能控制
OD_TOUCH_PROBE_STATUS0x60B9Touch Probe 状态
OD_TOUCH_PROBE_POS_EDGE0x60BATouch Probe 正边沿位置
OD_TOUCH_PROBE_NEG_EDGE0x60BBTouch Probe 负边沿位置
OD_INTERPOLATION_TIME_PERIOD0x60C2插补时间周期
OD_DIGITAL_INPUTS0x60FD数字输入
OD_DIGITAL_OUTPUTS0x60FE数字输出
OD_QUICK_STOP_OPTION_CODE0x605A快速停止选项码
OD_QUICK_STOP_DECELERATION0x6085快速停止减速度
OD_SUPPORTED_DRIVE_MODES0x6502支持的驱动模式位掩码

控制字命令常量

常量说明
CW_SHUTDOWN0x06关机命令
CW_SWITCH_ON0x07开启命令
CW_ENABLE_OPERATION0x0F使能运行
CW_DISABLE_VOLTAGE0x00禁用电压
CW_QUICK_STOP0x02快速停止
CW_FAULT_RESET0x80故障复位
CW_HALT0x0100暂停位 (Bit 8, 暂停运动但不禁用)

状态字位掩码常量

常量说明
SW_READY_TO_SWITCH_ON0x0001 (Bit 0)准备就绪
SW_SWITCHED_ON0x0002 (Bit 1)已开启
SW_OPERATION_ENABLED0x0004 (Bit 2)运行使能
SW_FAULT0x0008 (Bit 3)故障
SW_VOLTAGE_ENABLED0x0010 (Bit 4)电压已使能
SW_QUICK_STOP0x0020 (Bit 5)快速停止
SW_SWITCH_ON_DISABLED0x0040 (Bit 6)开启已禁用
SW_WARNING0x0080 (Bit 7)警告
SW_REMOTE0x0200 (Bit 9)远程模式
SW_TARGET_REACHED0x0400 (Bit 10)目标已到达
SW_INTERNAL_LIMIT0x0800 (Bit 11)内部限位激活
SW_OP_MODE_SPECIFIC_10x1000 (Bit 12)模式相关位 1
SW_OP_MODE_SPECIFIC_20x2000 (Bit 13)模式相关位 2