跳到主要内容

CiA 401 — 通用 I/O 模块

CiA 401 (IEC 61131-9) 是基于 CoE 的通用数字/模拟 I/O 设备协议。

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

通过 slave.cia401 访问。从站不支持 CiA 401 时为 None

快速开始

通过方法读写 IO 通道,所有通道号从 0 开始。

方法类型说明
read_di(n)bool读取数字输入通道 n
write_do(n, state)None写入数字输出通道 n
read_ai(n)int读取模拟输入通道 n
write_ao(n, value)None写入模拟输出通道 n

示例:

io = slave.cia401
if io is None:
return

# 数字 IO
sensor: bool = io.read_di(0)
io.write_do(0, True)
io.write_do(1, sensor)

# 模拟 IO
adc: int = io.read_ai(0)
io.write_ao(0, 16384)
实时控制

高频率 I/O 控制应使用 PDO 映射 而非 SDO。SDO 适合参数配置和诊断。

方法 API

read_di()

def read_di(self, channel: int) -> bool

读取数字输入。内部按 8 通道一组自动计算组号和位偏移。

参数:

  • channel (int) — 通道号(从 0 开始)

read_do()

def read_do(self, channel: int) -> bool

读回上次写入的数字输出状态 (SDO 0x6200)。

参数:

  • channel (int) — 通道号 (从 0 开始)

write_do()

def write_do(self, channel: int, state: bool) -> None

设置数字输出,不影响同组其他通道。

参数:

  • channel (int) — 通道号(从 0 开始)
  • state (bool) — 目标状态

read_ai()

def read_ai(self, channel: int) -> int

读取模拟输入值。自动适应 16 位和 32 位设备。

read_ao()

def read_ao(self, channel: int) -> int

读回当前模拟输出设定值 (SDO 0x6411)。

参数:

  • channel (int) — 通道号 (从 0 开始)

write_ao()

def write_ao(self, channel: int, value: int) -> None

写入模拟输出值。

参数:

  • channel (int) — 通道号(从 0 开始)
  • value (int) — 16 位输出值

read_ai_unsigned()

def read_ai_unsigned(self, channel: int) -> int

读取模拟输入值(无符号 16 位)。适用于 AI 数据范围为 0~65535 的设备。

参数:

  • channel (int) — 通道号(从 0 开始)

返回值:

  • int — 无符号 16 位模拟值

read_ai32_unsigned()

def read_ai32_unsigned(self, channel: int) -> int

读取模拟输入值(无符号 32 位)。适用于高精度 AI 设备,数据范围 0~4294967295。

参数:

  • channel (int) — 通道号(从 0 开始)

返回值:

  • int — 无符号 32 位模拟值

示例:

io = slave.cia401

# 有符号读取 (默认, 可能高位值变负数)
ai_signed = io.read_ai(0)

# 无符号 16 位读取 (0~65535)
ai_u16 = io.read_ai_unsigned(0)

# 无符号 32 位读取 (高精度设备)
ai_u32 = io.read_ai32_unsigned(0)

批量 IO 方法

除逐通道操作外,还支持 16/32 位批量读写,一次操作多个通道。

read_di16()

def read_di16(self, group: int) -> int

读取 16 位数字输入 (16 个通道)。

参数:

  • group (int) — 组号 (从 0 开始, 每 16 通道一组)

返回值:

  • int — 16 位输入值, 每位对应一个通道

read_di32()

def read_di32(self, group: int) -> int

读取 32 位数字输入 (32 个通道)。

read_do16() / write_do16()

def read_do16(self, group: int) -> int
def write_do16(self, group: int, value: int) -> None

读取或写入 16 位数字输出 (16 个通道)。

示例:

io.write_do16(0, 0x00FF)          # 通道 0-7 输出高, 8-15 输出低
do16 = io.read_do16(0)

read_do32() / write_do32()

def read_do32(self, group: int) -> int
def write_do32(self, group: int, value: int) -> None

读取或写入 32 位数字输出 (32 个通道)。

read_ao32() / write_ao32()

def read_ao32(self, channel: int) -> int
def write_ao32(self, channel: int, value: int) -> None

读取或写入 32 位模拟输出值。适用于高精度模拟输出设备。

示例:

io.write_ao32(0, 65536)           # 写入 32 位高精度值
ao = io.read_ao32(0) # 读回当前值

模拟输入中断与限值

read_global_interrupt_enable() / write_global_interrupt_enable()

def read_global_interrupt_enable(self) -> bool
def write_global_interrupt_enable(self, enable: bool) -> None

读取或设置模拟输入全局中断使能 (0x6423)。

参数:

  • enable (bool) — True = 使能, False = 禁用

read_ai_upper_limit() / write_ai_upper_limit()

def read_ai_upper_limit(self, channel: int) -> int
def write_ai_upper_limit(self, channel: int, value: int) -> None

读取或写入模拟输入中断上限值 (0x6424)。当 AI 值超过上限时触发中断。

参数:

  • channel (int) — 通道号(从 0 开始)
  • value (int) — 上限值

read_ai_lower_limit() / write_ai_lower_limit()

def read_ai_lower_limit(self, channel: int) -> int
def write_ai_lower_limit(self, channel: int, value: int) -> None

读取或写入模拟输入中断下限值 (0x6425)。当 AI 值低于下限时触发中断。

参数:

  • channel (int) — 通道号(从 0 开始)
  • value (int) — 下限值

示例:

io = slave.cia401

# 启用全局中断
io.write_global_interrupt_enable(True)

# 设置通道 0 的上下限
io.write_ai_upper_limit(0, 30000)
io.write_ai_lower_limit(0, 1000)

# 读取当前限值配置
upper = io.read_ai_upper_limit(0)
lower = io.read_ai_lower_limit(0)
enabled = io.read_global_interrupt_enable()

数字输入配置

set_di_polarity() / get_di_polarity()

def set_di_polarity(self, group: int, polarity: int) -> None
def get_di_polarity(self, group: int) -> int

设置或读取数字输入极性 (0x6002)。可按位反转输入信号逻辑。

set_di_filter() / get_di_filter()

def set_di_filter(self, group: int, filter_enable: int) -> None
def get_di_filter(self, group: int) -> int

设置或读取数字输入滤波使能 (0x6003)。用于消除输入信号抖动。

错误状态读取

get_do_error_mode() / get_do_error_value()

def get_do_error_mode(self, group: int) -> CiA401ErrorMode
def get_do_error_value(self, group: int) -> int

读取数字输出错误模式和错误安全值的当前配置。

错误处理

set_do_error_mode()

def set_do_error_mode(self, group: int, mode: CiA401ErrorMode) -> None

设置数字输出错误模式。当 EtherCAT 通信丢失时,决定输出如何响应。

参数:

  • group (int) — 组号(从 0 开始,每 8 个通道为一组:组 0 = 通道 0-7,组 1 = 通道 8-15)
  • mode (CiA401ErrorMode) — 错误模式

CiA401ErrorMode 枚举:

from enum import IntEnum

class CiA401ErrorMode(IntEnum):
HOLD = 0 # 保持当前输出值
SAFE_VALUE = 1 # 切换到预设的安全值

set_do_error_value()

def set_do_error_value(self, group: int, value: int) -> None

设置数字输出通信丢失时的安全值。仅在 SAFE_VALUE 模式下生效。

参数:

  • group (int) — 组号(从 0 开始)
  • value (int) — 安全输出值(8 位,每位对应一个通道)

set_ao_error_mode()

def set_ao_error_mode(self, channel: int, mode: CiA401ErrorMode) -> None

设置模拟输出错误模式。

参数:

  • channel (int) — 通道号(从 0 开始)
  • mode (CiA401ErrorMode) — 错误模式

set_ao_error_value()

def set_ao_error_value(self, channel: int, value: int) -> None

设置模拟输出通信丢失时的安全值。仅在 SAFE_VALUE 模式下生效。

参数:

  • channel (int) — 通道号(从 0 开始)
  • value (int) — 16 位安全输出值

get_ao_error_mode() / get_ao_error_value()

def get_ao_error_mode(self, channel: int) -> CiA401ErrorMode
def get_ao_error_value(self, channel: int) -> int

读取模拟输出错误模式和错误安全值的当前配置。

示例:

io.set_do_error_mode(0, CiA401ErrorMode.SAFE_VALUE)
io.set_do_error_value(0, 0x00)

io.set_ao_error_mode(0, CiA401ErrorMode.SAFE_VALUE)
io.set_ao_error_value(0, 0)

标准对象索引常量

可搭配 slave.coe.sdo_read / sdo_write 直接访问:

常量说明
OD_DI0x6000数字输入
OD_DI_16BIT0x600116 位数字输入
OD_DI_POLARITY0x6002数字输入极性
OD_DI_FILTER0x6003数字输入滤波使能
OD_DI_INTERRUPT0x6005数字输入中断触发
OD_DI_INTERRUPT_EDGE0x6006数字输入中断边沿
OD_DI_32BIT0x602032 位数字输入
OD_DO0x6200数字输出
OD_DO_16BIT0x620116 位数字输出
OD_DO_POLARITY0x6202数字输出极性
OD_DO_ERROR_MODE0x6206数字输出错误模式
OD_DO_ERROR_VALUE0x6207数字输出错误值
OD_DO_32BIT0x622032 位数字输出
OD_AI0x6400模拟输入
OD_AI_SI_UNIT0x6420模拟输入量程
OD_AI_GLOBAL_INTERRUPT0x6423模拟输入全局中断使能
OD_AI_UPPER_LIMIT0x6424模拟输入中断上限
OD_AI_LOWER_LIMIT0x6425模拟输入中断下限
OD_AO0x6411模拟输出
OD_AO_32BIT0x641232 位模拟输出
OD_AO_SI_UNIT0x6430模拟输出量程
OD_AO_ERROR_MODE0x6443模拟输出错误模式
OD_AO_ERROR_VALUE0x6444模拟输出错误值

完整示例

io = slave.cia401
if io is None:
return

# 数字 IO
sensor = io.read_di(0)
limit = io.read_di(5)

io.write_do(0, True)
io.write_do(1, sensor)

# 批量数字 IO
di16 = io.read_di16(0) # 读取通道 0-15
io.write_do16(0, 0x00FF) # 通道 0-7 输出高

# 模拟 IO
adc = io.read_ai(0)
temp = adc * 0.1
io.write_ao(0, 0 if temp > 50 else 16384)

# 无符号读取
ai_u16 = io.read_ai_unsigned(0)
ai_u32 = io.read_ai32_unsigned(0)

# 模拟输入限值配置
io.write_global_interrupt_enable(True)
io.write_ai_upper_limit(0, 30000)
io.write_ai_lower_limit(0, 1000)

# 安全配置
io.set_do_error_mode(0, CiA401ErrorMode.SAFE_VALUE)
io.set_do_error_value(0, 0x00)

io.set_ao_error_mode(0, CiA401ErrorMode.SAFE_VALUE)
io.set_ao_error_value(0, 0)