跳到主要内容

CiA 402 — 伺服驱动器辅助

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

CiA 402 运行在 CoE (SDO) 之上,仅当从站支持 CoE 时可用。

通过 slave.CoE.CiA402 访问。从站不支持 CiA 402 时为 null。​

PDO 初始化​

InitializePdoOffsets()​

public void InitializePdoOffsets()

初始化所有 PDO 偏移缓存。读取 0x1C12/0x1C13 PDO Assignment 配置,解析各对象在 IOmap 中的偏移位置。

备注

通常无需手动调用 — 首次访问 StateDrive 等 PDO 属性时自动初始化。仅在需要提前确认 PDO 映射正确时手动调用。

示例:

var drv = slave.CoE.CiA402;
drv.InitializePdoOffsets();
drv.OperationMode = ModeCiA402.CSP;

状态控制​

Enable() 仅在 StatusWord 解析为 OperationEnabled 时返回 true。Fault / FaultReaction 不会自动复位(返回 false,须先 FaultReset)。QuickStopActive 走 DisableVoltage→Shutdown→SwitchOn→EnableOperation,不读 0x605A、不做 T16。Disable / DisableOperation / QuickStop / FaultReset 只写控制字;使能/停止方法全部非阻塞,状态机推进由运行时完成;运动命令(NewSetpoint / ClearNewSetpoint / StartHoming)在非 OperationEnabled 或故障态抛错,禁止把 Fault 当使能。

Enable(int maxRetries = 10)​

public bool Enable(int maxRetries = 10)

使能驱动器: native CiA402_Enable 按 CiA 402-2 写 0x06 → 0x07 → 0x0F,仅当解析为 OperationEnabled 才返回 true。当前已是 Fault / FaultReaction 时托管层直接返回 false,不自动 FaultReset、不把故障态当使能。QuickStop 恢复不读 0x605A。

参数:

  • maxRetries — 最大重试次数 (默认 10)

返回值:

  • bool — true = 已使能到 OperationEnabled, false = 失败/超时/当前故障(含 Fault,须先 FaultReset)

示例:

// 进入 OP 后调用一次, 内部一步完成全套状态机
if (drv.Enable())
{
drv.TargetPosition = nextPosition;
}
else
{
Console.WriteLine($"使能失败, 当前状态: {drv.StateDrive}");
}

Disable()​

public void Disable()

禁用伺服 (→ SwitchOnDisabled)。完全断电。

DisableOperation()​

public void DisableOperation()

禁用运行 (Transition 5: OperationEnabled → SwitchedOn)。电机仍通电,可快速重新 Enable()。

QuickStop()​

public void QuickStop()

快速停止 (→ QuickStopActive)。

FaultReset()​

public void FaultReset()

清除故障。低相位写 Shutdown 0x0006(bit2=1 不 QS),高相位写 0x0086(bit7 上升沿 + bit2=1)。禁止 0x0000 / 0x0080(bit2 低有效,会顺带 QuickStop)。PDO 实时回调请用 FaultResetStep(0/1),不要 Thread.Sleep。

状态读取​

StateDrive​

public StateCiA402 StateDrive { get; }

解析当前驱动器状态。

返回值:

  • StateCiA402 — 驱动器状态枚举
public enum StateCiA402
{
NotReadyToSwitchOn = 0, // 初始化中
SwitchOnDisabled = 1, // 驱动禁用
ReadyToSwitchOn = 2, // 准备就绪
SwitchedOn = 3, // 已开启
OperationEnabled = 4, // 运行使能
QuickStopActive = 5, // 快速停止
FaultReactionActive = 6, // 故障反应中
Fault = 7, // 故障
Unknown = 99 // 未知状态
}

示例:

var state = slave.CoE.CiA402.StateDrive;
Console.WriteLine(state.GetDescription()); // "运行使能"

ParseState(ushort statusword)​

public static StateCiA402 ParseState(ushort statusword)

静态方法:从状态字解析驱动器状态(StateDrive 即取此解析结果)。纯计算,不访问从站。

参数:

  • statusword — 状态字原始值

返回值:

  • StateCiA402 — 驱动器状态枚举

Statusword​

public ushort Statusword { get; }

读取状态字。

相关属性:

  • TargetReached (bool) — 目标已到达 (Bit 10)
  • HasFault (bool) — 存在故障 (Bit 3)
  • HasWarning (bool) — 存在警告 (Bit 7)
  • IsRemote (bool) — 远程模式已激活 (Bit 9)

Controlword​

public ushort Controlword { get; set; }

读取或写入控制字。

示例:

ushort sw = slave.CoE.CiA402.Statusword;
slave.CoE.CiA402.Controlword = 0x000F;

操作模式​

OperationMode​

public ModeCiA402 OperationMode { get; set; }

设置或读取操作模式。

返回值:

  • ModeCiA402 — 操作模式枚举
public enum ModeCiA402 : sbyte
{
PP = 1, // 轮廓位置模式
VL = 2, // 速度模式
PV = 3, // 轮廓速度模式
PT = 4, // 轮廓转矩模式
HM = 6, // 回零模式
IP = 7, // 插补位置模式
CSP = 8, // 周期同步位置模式
CSV = 9, // 周期同步速度模式
CST = 10, // 周期同步转矩模式
CSTCA = 11 // 周期同步转矩加速度模式
}

示例:

slave.CoE.CiA402.OperationMode = ModeCiA402.CSP;
var mode = slave.CoE.CiA402.OperationMode;
Console.WriteLine(mode.GetDescription()); // "周期同步位置 (CSP)"

运动参数​

类别属性类型读写说明
位置PositionActualint只读实际位置 (0x6064)
速度VelocityActualint只读实际速度 (0x606C)
转矩TorqueActualshort只读实际转矩,千分之额定 (0x6077)
位置TargetPositionint读写目标位置 (0x607A)
速度TargetVelocityint读写目标速度 (0x60FF)
转矩TargetTorqueshort读写目标转矩,千分之额定 (0x6071)

示例:

var drv = slave.CoE.CiA402;

// 读取实际值
Console.WriteLine($"位置: {drv.PositionActual}");
Console.WriteLine($"速度: {drv.VelocityActual}");

// 写入目标值
drv.TargetPosition = 100000;
drv.TargetVelocity = 5000;

轮廓参数​

SDO 写入失败抛 InvalidOperationException,不再静默丢弃。

类别属性类型读写说明
轮廓ProfileVelocityuint读写轮廓速度 (0x6081)
轮廓ProfileAccelerationuint读写轮廓加速度 (0x6083)
轮廓ProfileDecelerationuint读写轮廓减速度 (0x6084)

示例:

var drv = slave.CoE.CiA402;
drv.ProfileVelocity = 10000;
drv.ProfileAcceleration = 50000;
drv.ProfileDeceleration = 50000;

极性与轮廓配置​

类别属性类型读写说明
极性Polaritybyte读写极性配置 (0x607E)。位 6 = 速度极性反转,位 7 = 位置极性反转
轮廓MotionProfileTypeshort读写运动轮廓类型(0x6086)。0 = 线性斜坡(梯形),1 = 正弦,2 = 抛物线(S 曲线)
停止QuickStopDecelerationuint读写快速停止减速度 (0x6085)

示例:

var drv = slave.CoE.CiA402;

// 反转位置方向
drv.Polarity = 0x80; // 位 7 = 位置极性反转

// 设置 S 曲线(抛物线)
drv.MotionProfileType = 2;

// 设置快速停止减速度
drv.QuickStopDeceleration = 100000;

触探功能 (Touch Probe)​

ConfigureTouchProbe(ushort function)​

public void ConfigureTouchProbe(ushort function)

配置触探功能 (0x60B8)。通过设置功能位启用/禁用触探及其触发条件。

参数:

  • function — 触探功能字。位 0 = 启用探针 1,位 1 = 正边沿触发,位 2 = 第一个事件

相关属性:

  • TouchProbeStatus (ushort) — 触探状态 (0x60B9),只读
  • TouchProbePositiveEdge (int) — 上升沿捕获位置 (0x60BA),只读
  • TouchProbeNegativeEdge (int) — 下降沿捕获位置 (0x60BB),只读

示例:

var drv = slave.CoE.CiA402;

// 启用触探 1,上升沿触发
drv.ConfigureTouchProbe(0x0001);

// 读取触探结果
if ((drv.TouchProbeStatus & 0x0002) != 0) // 上升沿已捕获
{
int capturedPos = drv.TouchProbePositiveEdge;
Console.WriteLine($"触探捕获位置: {capturedPos}");
}

回零速度与加速度​

类别属性类型读写说明
回零HomingSpeedSearchuint读写回零搜索速度 (0x6099:01),快速搜索参考信号
回零HomingSpeedZerouint读写回零零位速度 (0x6099:02),慢速精确定位零位
回零HomingAccelerationuint读写回零加速度 (0x609A)

示例:

var drv = slave.CoE.CiA402;
drv.OperationMode = ModeCiA402.HM;
drv.HomingMethod = 1;

// 设置回零速度和加速度
drv.HomingSpeedSearch = 5000; // 搜索速度
drv.HomingSpeedZero = 500; // 零位速度
drv.HomingAcceleration = 10000; // 回零加速度

扩展运动参数​

类别属性类型读写说明
转矩MaxTorqueushort读写最大转矩 (0x6072),千分之额定转矩
转矩MotorRatedTorqueuint读写电机额定转矩 (0x6076),单位 mNm
偏移PositionOffsetint读写位置偏移 (0x60B0),CSP 模式下叠加到目标位置
偏移VelocityOffsetint读写速度偏移 (0x60B1),CSV 模式下叠加到目标速度
插补InterpolationTimePeriodValuebyte读写插补时间周期值 (0x60C2:01)
插补InterpolationTimePeriodIndexsbyte读写插补时间周期指数 (0x60C2:02),实际周期 = Value x 10^Index 秒
选项码QuickStopOptionCodeshort读写快速停止选项码 (0x605A)。0=禁用驱动, 1/2=减速停止, 5/6=减速后保持在 QuickStopActive。与 QuickStopOption 同一读路径:读失败返回 ReadFailSentinelI16 (-32768) 哨兵,用 CiA402Instance.IsReadFailSentinel(v) 判别,见下方「选项码 (0x605A–0x605E)」一节

示例:

var drv = slave.CoE.CiA402;

// 转矩配置
drv.MaxTorque = 1000; // 最大转矩 = 100% 额定
uint rated = drv.MotorRatedTorque;

// CSP 模式偏移叠加
drv.PositionOffset = 100; // 位置附加偏移
drv.VelocityOffset = 50; // 速度附加偏移

// 插补时间周期 (1ms = 1 × 10^(-3) 秒)
drv.InterpolationTimePeriodValue = 1;
drv.InterpolationTimePeriodIndex = -3;

// 快速停止选项 (5=减速后保持, 允许直接恢复)
drv.QuickStopOptionCode = 5;

力矩限制​

类别属性类型读写说明
转矩PositiveTorqueLimitushort读写正方向力矩限制 (0x60E0),千分之额定转矩
转矩NegativeTorqueLimitushort读写负方向力矩限制 (0x60E1),千分之额定转矩

示例:

var drv = slave.CoE.CiA402;

// 限制正负方向转矩为额定的 50%
drv.PositiveTorqueLimit = 500;
drv.NegativeTorqueLimit = 500;

数字 IO​

类别属性类型读写说明
输入DigitalInputsuint只读数字输入 (0x60FD),32 位位图
输出DigitalOutputsuint读写数字输出(0x60FE:01),32 位位图

示例:

var drv = slave.CoE.CiA402;

// 读取数字输入
uint inputs = drv.DigitalInputs;
bool limitSwitch = (inputs & 0x01) != 0; // 位 0

// 设置数字输出
drv.DigitalOutputs = 0x03; // 输出位 0 和位 1

软件位置限位​

类别属性类型读写说明
限位SoftwarePositionLimitMinint读写软件位置限位下限 (0x607D:01)
限位SoftwarePositionLimitMaxint读写软件位置限位上限 (0x607D:02)

示例:

var drv = slave.CoE.CiA402;

// 设置运动范围限制
drv.SoftwarePositionLimitMin = -1000000;
drv.SoftwarePositionLimitMax = 1000000;

快速运动控制​

NewSetpoint(int position, bool relative = false)​

public void NewSetpoint(int position, bool relative = false)

PP 模式发送新定位命令。要求当前已是 OperationEnabled;Fault / FaultReaction 抛 InvalidOperationException,禁止把故障态当使能。成功时写目标位置并触发 Controlword Bit 4(0x0F|0x10 = 0x1F)。

参数:

  • position — 目标位置
  • relative — true = 相对定位,false = 绝对定位(默认)

示例:

var drv = slave.CoE.CiA402;
drv.OperationMode = ModeCiA402.PP;
drv.ProfileVelocity = 10000;
drv.ProfileAcceleration = 50000;

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

ClearNewSetpoint()​

public void ClearNewSetpoint()

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

示例:

if (drv.TargetReached)
{
drv.ClearNewSetpoint();
}

StartHoming()​

public void StartHoming()

HM 模式启动回零。需先设置 HomingMethod,且当前必须是 OperationEnabled。Fault / FaultReaction 抛错,禁止把故障态当使能。成功时写 Controlword 0x1F(0x0F|0x10)。

相关属性:

  • HomingMethod (sbyte) — 回零方法 (0x6098)
  • HomeOffset (int) — 回零偏移 (0x607C)
  • HomingAttained (bool) — 回零完成 (Bit 12)
  • HomingError (bool) — 回零错误 (Bit 13)

示例:

var drv = slave.CoE.CiA402;
drv.OperationMode = ModeCiA402.HM;
drv.HomingMethod = 35; // 当前位置回零

// 在 PDO 回调中:
if (drv.StateDrive == StateCiA402.OperationEnabled)
{
drv.StartHoming();
// 后续周期检查 drv.HomingAttained / drv.HomingError
}

标准对象索引常量​

可搭配 OD 属性访问或 slave.CoE.SDORead / SDOWrite 使用:

常量值说明
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支持的驱动模式位掩码
OD_ERROR_CODE0x603F当前错误代码 (只读)
OD_DRIVE_DATA0x6510厂商特定驱动数据 (RECORD, 只读)

控制字命令常量​

常量值说明
CW_SHUTDOWN0x06关机命令
CW_SWITCH_ON0x07开启命令
CW_ENABLE_OPERATION0x0F使能运行
CW_DISABLE_VOLTAGE0x00禁用电压
CW_QUICK_STOP0x02快速停止
CW_FAULT_RESET0x86故障复位 (T15: bit7 上升沿 + bit2=1;禁止单独 0x80)
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

驱动器信息​

SupportedDriveModes​

public uint SupportedDriveModes { get; }

支持的驱动模式位掩码 (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。

IsModeSupported(ModeCiA402 mode)​

public bool IsModeSupported(ModeCiA402 mode)

检查驱动器是否支持指定操作模式。

参数:

  • mode — 要检查的操作模式

示例:

var drv = slave.CoE.CiA402;
if (drv.IsModeSupported(ModeCiA402.CSP))
drv.OperationMode = ModeCiA402.CSP;

SupportedHomingMethods​

public sbyte[] SupportedHomingMethods { get; }

读取驱动器支持的回零方法列表 (0x60E3)。

三种情形各返什么:

  • 失败(SDO 超时 / 通讯异常 / 其它 abort)— 抛 InvalidOperationException,按失败处理
  • 空集(SI0=0 且读成功,从站真返回 0 条)— 返空数组
  • 不支持(从站无 0x60E3 或 0x60E3:00,SDO abort 0x06020000 对象不存在 / 0x06090011 子索引不存在)— 抛 InvalidOperationException,与失败同档

返回值:

  • sbyte[] — 回零方法编号列表,条目为 sbyte(-128..-1 厂商自定义方法,0 未选,1..35 与 37 为 ETG.6010 标准方法)
备注

失败与不支持都按失败处理,禁止当成「支持 0 种回零方法」。对应导出 CiA402_GetSupportedHomingMethods 读失败整体返回 -1(fail-closed),本属性按 C# 惯例映射为异常,不返回 -1。

示例:

var drv = slave.CoE.CiA402;

try
{
sbyte[] methods = drv.SupportedHomingMethods;
if (methods.Length == 0)
Console.WriteLine("从站确认支持 0 种回零方法");
else
Console.WriteLine($"支持 {methods.Length} 种回零方法: {string.Join(", ", methods)}");
}
catch (InvalidOperationException)
{
// 读失败或从站不支持 0x60E3, 与不支持同档, 按失败处理
Console.WriteLine("回零方法读取失败, 按失败处理");
}

TxPDO 数据有效性​

TxPdoDataInvalid​

public bool TxPdoDataInvalid { get; }

TxPDO 数据是否无效 (0x603E)。非零表示驱动器 TxPDO 数据不可信。SDO 读失败/不支持时 fail-closed 返回 true(视为无效),禁止把读失败假装成数据有效。

示例:

var drv = slave.CoE.CiA402;
if (!drv.TxPdoDataInvalid)
{
int pos = drv.PositionActual; // 数据有效,可安全使用
}

同步功能​

类别属性类型读写说明
同步SynchronizationSettingsushort读写同步设置 (0x60D9:01),同步使能位掩码
同步DriveSyncStatusushort只读驱动同步状态(0x60DA:00)寄存器原值,指示驱动器是否已同步到主站时钟

示例:

var drv = slave.CoE.CiA402;

// 读取驱动器同步状态
ushort syncStatus = drv.DriveSyncStatus;
Console.WriteLine($"同步状态: 0x{syncStatus:X4}");

// 配置同步设置
drv.SynchronizationSettings = 0x0001;

深度合规 API (ETG.6010 + CiA 402-2)​

以下方法实现 CiA 402-2 状态机的完整合规控制:状态转换合法性校验、五类选项码 (0x605A–0x605E)、驱动器内部错误历史 (0x1003)、标准回零方法校验 (0x60E3)。状态机解码与选项码读写下沉到 DLL,托管层为薄封装。

RequestTransition(StateCiA402 target)​

public bool RequestTransition(StateCiA402 target)

请求指定状态转换。合法性由 DLL 按 CiA 402-2 Fig.3 的 T1–T16 转换图校验;非法转换 (如 Fault → OperationEnabled 直跳) 返回 false 且不发命令。

参数:

  • target (StateCiA402) — 目标状态

返回值:

  • bool — true = 转换合法且已发出对应控制字, false = 非法转换/未发命令

示例:

var drv = slave.CoE.CiA402;
// 仅当目标状态可从当前状态合法到达时才发命令
if (drv.RequestTransition(StateCiA402.SwitchedOn))
Console.WriteLine("已请求 → SwitchedOn");

GetTransitionCommand(StateCiA402 current, StateCiA402 target)​

public static ushort GetTransitionCommand(StateCiA402 current, StateCiA402 target)

查询 (current → target) 的合法控制字。静态方法,纯计算不访问从站。

返回值:

  • ushort — 应写入的控制字;0xFFFF = 非法转换

示例:

ushort cw = CiA402Instance.GetTransitionCommand(
StateCiA402.SwitchOnDisabled, StateCiA402.ReadyToSwitchOn);
if (cw != 0xFFFF)
drv.Controlword = cw;

FaultResetStep(int step)​

public bool FaultResetStep(int step)

非阻塞 Fault Reset 单步。用于 PDO 回调中分两个周期触发故障复位上升沿 (避免 FaultReset() 内的 Thread.Sleep 阻塞实时线程):第一周期 step=0 写 Shutdown 0x0006,第二周期 step=1 写 0x0086。

参数:

  • step (int) — 0 = 低相位 0x0006,1 = 高相位 0x0086

返回值:

  • bool — 是否成功

示例:

int fr = 0;
master.Events.ProcessDataCyclicSync += (mi) =>
{
if (drv.HasFault && fr < 2)
drv.FaultResetStep(fr++); // 周期 0 写 0x06, 周期 1 写 0x86
};

状态机驱动模式查询 (DLL 路径)​

  • SupportedDriveModesDll — public uint SupportedDriveModesDll { get; } — 经 DLL 查询支持的驱动模式位掩码 (0x6502),与 SupportedDriveModes 属性等价,由 DLL 内部按 PDO/SDO 分流
  • IsModeSupportedDll(ModeCiA402 mode) — public bool IsModeSupportedDll(ModeCiA402 mode) — 经 DLL 检查从站是否支持指定操作模式 (0x6502 位掩码)

选项码 (0x605A–0x605E)​

五类驱动器选项码,决定各状态转换时的减速/停止行为。每个均为 short 读写属性。

  • QuickStopOption (short, 读写) — 快速停止选项码 (0x605A)。0=直接切断, 1=斜坡减速, 2=Quick Stop 减速, 3=转矩停止; 5/6/7/8=减速后保持 QuickStopActive (允许 T16 直接 → OperationEnabled)
  • ShutdownOption (short, 读写) — Shutdown 选项码 (0x605B): OperationEnabled → ReadyToSwitchOn 时的减速行为
  • DisableOperationOption (short, 读写) — Disable Operation 选项码 (0x605C): OperationEnabled → SwitchedOn 时的行为
  • HaltOption (short, 读写) — Halt 选项码 (0x605D): CW Bit8 Halt 行为 (1=轮廓斜坡, 2=QS 减速, 3=转矩停止)
  • FaultReactionOption (short, 读写) — Fault Reaction 选项码 (0x605E): 故障检测后行为 (-1=厂商, 0=直接切断, 1/2/3=减速)

返回值与读失败哨兵:正常 = 真值;读失败 = -32768 (INT16_MIN)。-32768 不是合法取值(合法选项码为小值含 0),请勿当作真实数值使用。读失败哨兵按返回形分三档:

  • ReadFailSentinelI16 (short) — -32768 (INT16_MIN)。有符号 16 位选项码 (0x605A-0x605E) 读失败
  • ReadFailSentinelU16 (ushort) — 0xFFFF。无符号 16 位 ErrorCode (0x603F) 读失败
  • ReadFailSentinelInt (int) — -1。返回 int 的计数形读取接口(GetErrorHistory / GetSupportedHomingMethodsDll 等)读失败整体返回 -1(fail-closed)

判别用 CiA402Instance.IsReadFailSentinel(v) 三个重载,按返回形取 short / ushort / int,命中后按失败处理。

备注

sbyte 方法编号(0x60E3 列表项,-128..-1 为厂商自定义方法)是真实取值,不属哨兵,请勿用 IsReadFailSentinel 判别。

QuickStopOption (0x605A) 与 扩展运动参数 中的 QuickStopOptionCode (0x605A) 指向同一对象、共用同一读路径,读失败一律返回哨兵。哨兵口径适用于上述五个属性与 QuickStopOptionCode。

示例:

var drv = slave.CoE.CiA402;

// 快速停止后保持在 QuickStopActive (5), 便于直接恢复运行
drv.QuickStopOption = 5;

// 故障反应使用斜坡减速 (2) 而非直接切断
drv.FaultReactionOption = 2;

// 读选项码: 读失败 = -32768 哨兵 (非合法取值), 按失败处理
short qs = drv.QuickStopOption;
if (CiA402Instance.IsReadFailSentinel(qs))
Console.WriteLine("QuickStopOption 读取失败, 按失败处理");

错误代码与错误历史​

  • ErrorCode (ushort, 只读) — 当前 Error Code (0x603F, CiA 402 附录)。正常 = 真值;读失败 = 0xFFFF 哨兵。0xFFFF 不是合法取值 (0x0000 表无错误), 请勿当作真实数值使用, 判别用 CiA402Instance.IsReadFailSentinel(v)
  • GetErrorHistory(int maxCount = 32) (uint[], 只读) — 读取 Pre-defined Error Field (0x1003), 返回驱动器内部持久错误历史的 Error Code 数组 (低 16 位)。区别于本主站侧维护的 EMCY 缓冲。底层读失败整体返回 -1 (fail-closed), 封装层映射为空数组, 调用方应按失败处理
  • ClearErrorHistory() (返回 bool) — 清除驱动器内部错误历史 (0x1003:00 = 0)

示例:

var drv = slave.CoE.CiA402;

// 当前错误码 (读失败 = 0xFFFF 哨兵, 不是真实错误码)
ushort ec = drv.ErrorCode;
if (CiA402Instance.IsReadFailSentinel(ec))
Console.WriteLine("Error Code 读取失败, 按失败处理");
else
Console.WriteLine($"Error Code = 0x{ec:X4}");

// 读取驱动器内部错误历史 (空数组 = 无历史或读失败, 应按失败处理)
uint[] history = drv.GetErrorHistory(maxCount: 16);
if (history.Length == 0) Console.WriteLine("错误历史为空或读取失败");
foreach (uint code in history)
Console.WriteLine($"历史错误: 0x{code:X4}");

// 清除历史
drv.ClearErrorHistory();

回零方法 (0x60E3)​

  • GetSupportedHomingMethodsDll(int maxCount = 64) — public sbyte[] GetSupportedHomingMethodsDll(int maxCount = 64) — 经 DLL 读取支持的回零方法列表 (0x60E3,ETG.6010 最多 35 标准方法 + 厂商自定义)。失败与空集在本方法都返回空数组,与 SupportedHomingMethods 属性的异常语义不同,二者不可互换
  • IsStandardHomingMethod(sbyte method) — public static bool IsStandardHomingMethod(sbyte method) — 校验 Homing Method 是否属于 ETG.6010 标准 35 方法 (1..35 或 37)。静态方法

GetSupportedHomingMethodsDll 三种情形各返什么:

  • 失败(SDO 超时 / 通讯异常 / 其它 abort)— 底层返 -1(fail-closed),本封装映射为空数组,按失败处理
  • 空集(SI0=0 且读成功,从站真返回 0 条)— 返空数组
  • 不支持(从站无 0x60E3 或 0x60E3:00,SDO abort 0x06020000 / 0x06090011)— 底层返 -1,与失败同档,本封装映射为空数组

返回值:

  • sbyte[] — 回零方法编号列表,条目为 sbyte(-128..-1 厂商自定义方法,0 未选,1..35 与 37 为 ETG.6010 标准方法)
备注

本方法返回空数组不能读作「支持 0 种回零方法」。需要区分失败 / 空集 / 不支持三种情形时,改用 SupportedHomingMethods 属性。

示例:

var drv = slave.CoE.CiA402;

sbyte[] methods = drv.GetSupportedHomingMethodsDll();
if (methods.Length == 0)
{
// 空数组 = 失败 / 不支持 / 真空列表, 不代表支持 0 种方法
Console.WriteLine("回零方法读取为空, 需区分请用 SupportedHomingMethods 属性");
}

foreach (sbyte m in methods)
{
bool standard = CiA402Instance.IsStandardHomingMethod(m);
Console.WriteLine($"回零方法 {m}: {(standard ? "ETG.6010 标准" : "厂商自定义")}");
}

可观测只读 API (区分真值 / 不支持 / 读失败)​

只读返回值的读失败语义按接口区分:

  • 哨兵路径 — 有符号 16 位选项码 (QuickStopOption / QuickStopOptionCode / ShutdownOption / DisableOperationOption / HaltOption / FaultReactionOption,共用同一读路径) 读失败返回 -32768 (INT16_MIN) 哨兵;无符号 16 位 ErrorCode (0x603F) 读失败返回 0xFFFF 哨兵;返回 int 的计数形读取接口读失败返回 -1 哨兵(封装层的处理见 fail-closed 路径)。三档常量为 ReadFailSentinelI16 / ReadFailSentinelU16 / ReadFailSentinelInt。哨兵不是合法取值(合法选项码为小值含 0;ErrorCode 0x0000 表无错误),请勿当作真实数值使用,用 CiA402Instance.IsReadFailSentinel(v) 三个重载(按返回形取 short / ushort / int)判别后按失败处理
  • 折叠路径 — 其余纯 PDO / 数值 getter (如 TorqueActual / MotionProfileType / TargetTorque) 读失败折返默认值 0,无法与真值 0 区分,需区分请用 LastReadStatus 或 TryRead*
  • fail-closed 路径 — 计数形数组读取接口 (如 GetErrorHistory / GetSupportedHomingMethodsDll) 底层读失败整体返回 -1,封装层映射为空数组,调用方应按失败处理
  • 抛错路径 — SupportedHomingMethods 属性读失败或从站不支持 0x60E3 都抛 InvalidOperationException,不返回哨兵、不返回空数组;仅 SI0=0 且读成功才返回空数组

可观测只读 API 通过 CiA402ReadResult<T> 携带读取状态三态 (真值 / 不支持 / 读失败),可完整区分"从站真返 0"与读失败。

备注

这些 API 是纯只读的 SDO 直读尝试,无任何写对象字典/写 PDO/改状态副作用。实时高频读仍请用对应的 PDO 优先属性 (Statusword / PositionActual / VelocityActual / OperationMode),零网络开销。

CiA402ReadStatus 枚举​

public enum CiA402ReadStatus
{
NotAttempted = 0, // 尚未尝试读取
Success = 1, // 读取成功, 返回的是从站真值
NotSupported = 2, // 从站不支持该对象 (SDO abort 0x06020000 / 0x06090011)
ReadFailed = 3 // SDO 读取失败 (超时 / 通讯异常 / 其它 abort)
}

CiA402ReadResult<T> 结构​

public readonly struct CiA402ReadResult<T> where T : struct

带状态的读取结果。

  • Value (T, 只读) — 读到的值 (仅 Status == Success 时有意义; 否则为 default)
  • Status (CiA402ReadStatus, 只读) — 读取状态 (成功 / 不支持 / 失败 / 未尝试)
  • AbortCode (uint, 只读) — SDO Abort Code (0 = 无 abort; 不支持/失败时为底层 abort code)
  • Ok (bool, 只读) — 是否读取成功且值可信 (Status == Success)
  • NotSupported (bool, 只读) — 从站是否不支持该对象 (Status == NotSupported)

TryReadObject<T>(ushort index, byte subindex = 0)​

public CiA402ReadResult<T> TryReadObject<T>(ushort index, byte subindex = 0) where T : struct

通用可观测只读 — 对任意 CiA 402 对象做一次 SDO 只读尝试,返回带状态的结果。T 支持 byte/sbyte/ushort/short/uint/int/ulong/long。

示例:

var drv = slave.CoE.CiA402;
var r = drv.TryReadObject<uint>(0x6502, 0);
if (r.Ok)
Console.WriteLine($"Supported Drive Modes = 0x{r.Value:X8}");
else if (r.NotSupported)
Console.WriteLine("从站不支持 0x6502");
else
Console.WriteLine($"读失败 abort=0x{r.AbortCode:X8}");

预置可观测读取方法​

以下方法对常用 CiA 402 只读对象的 TryReadObject<T> 薄封装,返回带状态结果。

  • TryReadStatusword() (CiA402ReadResult<ushort>, 0x6041) — 状态字 (SDO 路径; 高频读用 Statusword)
  • TryReadOperationModeDisplay() (CiA402ReadResult<ModeCiA402>, 0x6061) — 操作模式显示 (强制 SDO,区分真模式与读失败)
  • TryReadSupportedDriveModes() (CiA402ReadResult<uint>, 0x6502) — 支持的驱动模式位掩码 (ETG.6010 mandatory)
  • TryReadErrorCode() (CiA402ReadResult<ushort>, 0x603F) — 当前错误代码 (SDO 直读,与 ErrorCode 经 DLL 路径独立)
  • TryReadTorqueActual() (CiA402ReadResult<short>, 0x6077) — 实际转矩 (千分之额定转矩)
  • TryReadDigitalInputs() (CiA402ReadResult<uint>, 0x60FD) — 数字输入
  • TryReadPositionActual() (CiA402ReadResult<int>, 0x6064) — 实际位置 (SDO 路径; 高频读用 PositionActual)
  • TryReadVelocityActual() (CiA402ReadResult<int>, 0x606C) — 实际速度 (SDO 路径; 高频读用 VelocityActual)
  • TryReadDriveData(byte subindex) (CiA402ReadResult<uint>, 0x6510) — 厂商特定驱动数据 (子索引由从站 ESI 定义)

示例:

var drv = slave.CoE.CiA402;

// 上电自检: 区分"从站真返 0 模式掩码"与"读 0x6502 失败/不支持"
var modes = drv.TryReadSupportedDriveModes();
switch (modes.Status)
{
case CiA402ReadStatus.Success:
Console.WriteLine($"支持模式掩码 = 0x{modes.Value:X8}");
break;
case CiA402ReadStatus.NotSupported:
Console.WriteLine("从站不支持 0x6502 (非标准 CiA 402 驱动?)");
break;
case CiA402ReadStatus.ReadFailed:
Console.WriteLine($"读 0x6502 失败 abort=0x{modes.AbortCode:X8}");
break;
}

// 显式读模式 (PDO 高频路径无法判失败时)
var md = drv.TryReadOperationModeDisplay();
if (md.Ok)
Console.WriteLine($"当前模式: {md.Value.GetDescription()}");

最近一次只读状态查询​

走 SDO 回退路径读取任一公开只读属性后,可查询以下成员判断返回值是真值还是读失败时的默认值。

  • LastReadStatus (CiA402ReadStatus, 只读) — 最近一次 SDO 只读尝试的状态 (成功 / 不支持 / 失败 / 未尝试)
  • LastReadAbortCode (uint, 只读) — 最近一次只读失败/不支持时的 Abort Code (0 = 无 abort / 成功)。0x06020000=对象不存在, 0x06090011=子索引不存在, 0x05040000=超时
  • LastReadObject ((ushort Index, byte SubIndex), 只读) — 最近一次 SDO 只读尝试的对象索引/子索引 (诊断定位用)
  • SupportedDriveModesReadable (bool, 只读) — 从站是否真支持 0x6502 对象 (据只读尝试结果判断)。true=读成功; false=不支持或读失败 (用 LastReadStatus 进一步区分)

示例:

var drv = slave.CoE.CiA402;

// 读普通只读属性后, 用 LastReadStatus 判断 0 是真值还是失败
uint modes = drv.SupportedDriveModes;
if (drv.LastReadStatus != CiA402ReadStatus.Success)
Console.WriteLine($"0x6502 读取异常: {drv.LastReadStatus.GetDescriptionFromAttribute()}, " +
$"abort=0x{drv.LastReadAbortCode:X8}, 对象=0x{drv.LastReadObject.Index:X4}");

诊断属性​

类别属性类型读写说明
PDO 状态PdoInitializedbool只读PDO 偏移是否已初始化
CanSwitchModeViaPdobool只读模式切换是否可通过 PDO (0x6060 在 RxPDO 且 IOmap 已分配)
HasPdoModesDisplaybool只读模式显示 (0x6061) 是否在 TxPDO 中 (PDO 零开销读取)
HasPdoVelocityActualbool只读速度实际值 (0x606C) 是否在 TxPDO 中 (PDO 零开销读取)
PdoFallbackCountlong只读PDO 优先读取在边界检查失败时回退到 SDO 的累计次数 (映射健康度诊断)
状态SlaveEcStateEcState只读从站当前 EtherCAT 状态
IsMasterDisposedbool只读主站是否已释放

ResetPdoOffsets()​

public void ResetPdoOffsets()

重置 PDO 偏移缓存。从站状态降级时调用,下次进入 SafeOp+ 会重新初始化偏移。

完整示例​

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

var drv = slave.CoE.CiA402;
if (drv == null) return;

// 初始化 (OP 状态后调用一次)
drv.InitializePdoOffsets();
drv.OperationMode = ModeCiA402.CSP;

// 一次性使能 (内部完成完整状态机)
if (!drv.Enable()) { Console.WriteLine($"使能失败: {drv.StateDrive}"); return; }

// PDO 回调中每周期下发目标
master.Events.ProcessDataCyclicSync += (masterIndex) =>
{
drv.TargetPosition = CalculateNextPosition();
};

PP 模式 — 轮廓位置控制​

var drv = slave.CoE.CiA402;
if (drv == null) return;

drv.InitializePdoOffsets();
drv.OperationMode = ModeCiA402.PP;
drv.ProfileVelocity = 10000;
drv.ProfileAcceleration = 50000;
drv.ProfileDeceleration = 50000;

// 一次性使能
if (!drv.Enable()) { Console.WriteLine($"使能失败: {drv.StateDrive}"); return; }

// 发送定位命令
drv.NewSetpoint(100000);

// 在 PDO 回调中等待目标到达后清标志
bool homing = false;
master.Events.ProcessDataCyclicSync += (masterIndex) =>
{
if (!homing && drv.TargetReached)
{
drv.ClearNewSetpoint();
homing = true;
}
};