跳到主要内容

AoE (ADS over EtherCAT)

AoE 协议实现了 ADS (Automation Device Specification) over EtherCAT 通信,支持 Beckhoff TwinCAT 和类似设备的 ADS 通信。

通过 slave.AoE 访问。从站不支持 AoE 时为 null

属性

属性类型访问说明
DefaultTimeoutMsint只读默认超时时间(毫秒),500

数据读写

Read(uint indexGroup, uint indexOffset, uint length, int timeoutMs = DefaultTimeoutMs)

public byte[]? Read(uint indexGroup, uint indexOffset, uint length, int timeoutMs = DefaultTimeoutMs)

读取 ADS 数据。

参数:

  • indexGroup (uint) — 索引组
  • indexOffset (uint) — 索引偏移
  • length (uint) — 读取长度
  • timeoutMs (int) — 超时时间(毫秒)

返回值:

  • byte[]? — 读取的数据,失败返回 null

示例:

byte[]? status = slave.AoE.Read(0x4020, 0, 4);
if (status != null)
{
uint value = BitConverter.ToUInt32(status, 0);
Console.WriteLine($"状态值: 0x{value:X8}");
}

Read<T>(uint indexGroup, uint indexOffset, int timeoutMs = DefaultTimeoutMs)

public T? Read<T>(uint indexGroup, uint indexOffset, int timeoutMs = DefaultTimeoutMs) where T : struct

泛型读取,自动按结构体大小读取并转换为指定类型。

参数:

  • indexGroup (uint) — 索引组
  • indexOffset (uint) — 索引偏移
  • timeoutMs (int) — 超时时间(毫秒)

返回值:

  • T? — 读取的值,失败返回 null

示例:

uint? status = slave.AoE.Read<uint>(0x4020, 0);
int? position = slave.AoE.Read<int>(0x4020, 4);

Write(uint indexGroup, uint indexOffset, byte[] data, int timeoutMs = DefaultTimeoutMs)

public bool Write(uint indexGroup, uint indexOffset, byte[] data, int timeoutMs = DefaultTimeoutMs)

写入 ADS 数据。

参数:

  • indexGroup (uint) — 索引组
  • indexOffset (uint) — 索引偏移
  • data (byte[]) — 写入数据
  • timeoutMs (int) — 超时时间(毫秒)

返回值:

  • bool — 成功返回 true

Write<T>(uint indexGroup, uint indexOffset, T value, int timeoutMs = DefaultTimeoutMs)

public bool Write<T>(uint indexGroup, uint indexOffset, T value, int timeoutMs = DefaultTimeoutMs) where T : struct

泛型写入,自动将值转换为字节写入。

参数:

  • indexGroup (uint) — 索引组
  • indexOffset (uint) — 索引偏移
  • value (T) — 写入的值
  • timeoutMs (int) — 超时时间(毫秒)

返回值:

  • bool — 成功返回 true

示例:

slave.AoE.Write<uint>(0x4020, 0, 0x0006);
slave.AoE.Write<int>(0x4020, 4, 100000);

ReadWrite(uint indexGroup, uint indexOffset, uint readLength, byte[]? writeData = null, int timeoutMs = DefaultTimeoutMs)

public byte[]? ReadWrite(uint indexGroup, uint indexOffset, uint readLength, byte[]? writeData = null, int timeoutMs = DefaultTimeoutMs)

同时读写数据(ADS ReadWrite 命令)。

参数:

  • indexGroup (uint) — 索引组
  • indexOffset (uint) — 索引偏移
  • readLength (uint) — 读取长度
  • writeData (byte[]?) — 写入数据(可选)
  • timeoutMs (int) — 超时时间(毫秒)

返回值:

  • byte[]? — 读取的数据

设备信息

ReadDeviceInfo(int timeoutMs = DefaultTimeoutMs)

public (bool success, byte majorVer, byte minorVer, ushort build, string deviceName) ReadDeviceInfo(int timeoutMs = DefaultTimeoutMs)

读取 ADS 设备信息。

返回值:

  • success (bool) — 是否成功
  • majorVer (byte) — 主版本号
  • minorVer (byte) — 次版本号
  • build (ushort) — 编译号
  • deviceName (string) — 设备名称

示例:

var (success, major, minor, build, name) = slave.AoE.ReadDeviceInfo();
if (success)
Console.WriteLine($"设备: {name} v{major}.{minor}.{build}");

ReadState(int timeoutMs = DefaultTimeoutMs)

public (bool success, ushort adsState, ushort deviceState) ReadState(int timeoutMs = DefaultTimeoutMs)

读取 ADS 状态。

返回值:

  • success (bool) — 是否成功
  • adsState (ushort) — ADS 状态
  • deviceState (ushort) — 设备状态

相关结构:

  • 0Invalid 无效状态
  • 1Idle 空闲
  • 2Reset 复位
  • 3Init 初始化
  • 4Start 启动
  • 5Run 运行
  • 6Stop 停止
  • 7SaveConfig 保存配置
  • 8LoadConfig 加载配置
  • 9PowerFailure 电源故障
  • 10PowerGood 电源正常
  • 11Error 错误
  • 12Shutdown 关闭
  • 13Suspend 挂起
  • 14Resume 恢复
  • 15Config 配置
  • 16Reconfig 重新配置

示例:

var (success, adsState, deviceState) = slave.AoE.ReadState();
if (success)
Console.WriteLine($"ADS 状态: {slave.AoE.GetAdsStateName(adsState)} ({adsState})");

WriteControl(ushort adsState, ushort deviceState, byte[]? data = null, int timeoutMs = DefaultTimeoutMs)

public bool WriteControl(ushort adsState, ushort deviceState, byte[]? data = null, int timeoutMs = DefaultTimeoutMs)

写入控制命令(切换设备状态)。

参数:

  • adsState (ushort) — 目标 ADS 状态
  • deviceState (ushort) — 目标设备状态
  • data (byte[]?) — 附加数据(可选)
  • timeoutMs (int) — 超时时间(毫秒)

返回值:

  • bool — 成功返回 true

示例:

slave.AoE.WriteControl(5, 0);  // 切换到 Run 状态

GetAdsStateName(ushort adsState)

public string GetAdsStateName(ushort adsState)

获取 ADS 状态名称。

数据订阅

Subscribe(...)

public AoESubscription? Subscribe(
uint indexGroup, uint indexOffset, uint dataLength,
Action<AoENotificationEventArgs> callback,
AoETransmissionMode mode = AoETransmissionMode.OnChange,
int cycleTimeMs = 100)

订阅数据变化通知。

参数:

  • indexGroup (uint) — 索引组
  • indexOffset (uint) — 索引偏移
  • dataLength (uint) — 数据长度
  • callback (Action<AoENotificationEventArgs>) — 数据变化回调
  • mode (AoETransmissionMode) — 传输模式(默认 OnChange
  • cycleTimeMs (int) — 检查周期(毫秒,默认 100)

返回值:

  • AoESubscription? — 订阅对象,失败返回 null

AoETransmissionMode 枚举

public enum AoETransmissionMode : uint
{
NoTransmission = 0, // 无通知
Cyclic = 1, // 循环通知 - 按指定周期发送
OnChange = 2, // 变化通知 - 数据变化时发送
CyclicInDevice = 3, // 设备端循环通知
OnChangeInDevice = 4 // 设备端变化通知
}

示例:

var sub = slave.AoE.Subscribe(0x4020, 0, 4, e =>
{
uint value = BitConverter.ToUInt32(e.Data, 0);
Console.WriteLine($"数据变化: 0x{value:X8}");
});

Unsubscribe(AoESubscription subscription)

public bool Unsubscribe(AoESubscription subscription)

取消订阅。

UnsubscribeAll()

public void UnsubscribeAll()

取消所有订阅。

示例:

if (slave.AoE)
{
// AoE 可用
}

完整示例

类型化读写

if (slave.AoE)
{
// 泛型读取
uint? status = slave.AoE.Read<uint>(0x4020, 0);
Console.WriteLine($"状态: 0x{status:X8}");

// 泛型写入
slave.AoE.Write<uint>(0x4020, 0, 0x0006);

// 设备信息
var (ok, major, minor, build, name) = slave.AoE.ReadDeviceInfo();
if (ok) Console.WriteLine($"设备: {name} v{major}.{minor}.{build}");
}

数据订阅

if (slave.AoE)
{
var sub = slave.AoE.Subscribe(0x4020, 0, 4, e =>
{
Console.WriteLine($"数据变化, 订阅 ID: {e.SubscriptionId}");
});

Thread.Sleep(10000);
slave.AoE.UnsubscribeAll();
}