跳到主要内容

IO 系统概述

IO 系统连接 PLC 程序和现场硬件,支持 EtherCAT、Modbus、CANopen 等 100 多种工业协议。不论哪种协议,PLC 程序里写变量的方式完全一样。

IEC 61131-3 内存区域

Darra 遵循 IEC 61131-3 标准,用 4 个前缀区分用途:

区域前缀说明访问权限
I (Input)%I物理输入只读
Q (Output)%Q物理输出读写
M (Marker)%M中间变量读写
V (Variable)%V全局变量读写

数据宽度

后缀宽度地址示例说明
X (Bit)1 bit%IX0.0单个 DI 点
B (Byte)8 bit%IB0字节
W (Word)16 bit%IW100字(模拟量)
D (DWord)32 bit%ID200双字(浮点)

扫描周期

PLC 每个扫描周期分三个阶段:

一致性保证

输入在周期开始时一次性读完,程序执行期间输入不会变。所有输出在周期末尾一次性写出。这样 PLC 程序始终看到一致的 IO 快照。

核心功能

功能说明
点位注册统一管理所有 IO 点位及其地址
读写缓存减少对硬件的重复访问
边沿检测自动识别 DI 上升沿/下降沿
消抖处理可配置消抖时间(默认 10ms)
强制值调试时锁定 IO 为指定值
变更通知值变化时触发回调

支持的协议

类别协议
实时以太网EtherCAT、EtherNet/IP
现场总线CANopen、Modbus
串行Modbus RTU、RS-232、RS-485
工业以太网Modbus TCP、S7、MC、FINS
IT 协议OPC UA、MQTT、HTTP、SQL

新增协议、查找设备参数模板详见 基础使用 → 通讯协议

地址映射

IO 地址映射支持双向查询:

PLC 地址 (%IX0.0) ←→ 硬件端口 (EtherCAT Slave 2, PDO 0x6000:01, Bit 0)

详见 IO 地址映射

地址优化

IDE 自动优化 IO 地址分配:

  • 间隔合并 — 相邻地址合并成连续块,减少读写次数
  • 边界对齐 — 按字节/字/双字对齐,提高访问效率
  • 冲突检测 — 自动发现地址重叠

HAL 层设计

所有 IO 协议通过硬件抽象层 (HAL) 接入 PLC 扫描引擎:

IHardwareDriver 接口只有三个核心方法:

public interface IHardwareDriver
{
void Read(IOBuffer inputBuffer); // 读硬件 → 输入映像
void Write(IOBuffer outputBuffer); // 输出映像 → 写硬件
DriverStatus GetStatus(); // 健康状态
}

PLC 每个扫描周期调用所有驱动的 Read → 执行程序 → 调用所有 Write。驱动实现对上层透明, 用户不用关心底层协议。

IOBuffer 结构

IOBuffer 是一个连续的字节数组, PLC 程序通过 %IX/%IW/%IB/%ID 定位到其中的字节偏移:

IOBuffer:
Offset 0: IX0.0~0.7 (8 bits 的 DI)
Offset 1: IX1.0~1.7
...
Offset 100: IW100 (2 bytes)
Offset 200: ID200 (4 bytes REAL)

不同协议的驱动通过自己的 PDO/寄存器映射把数据搬运到 IOBuffer 的对应偏移。

地址空间规划

推荐地址空间规划约定:

范围用途
%IX0~%IX100EtherCAT 从站 DI
%IX100~%IX200Modbus / CANopen DI
%IW200~%IW500模拟输入
%ID500~%ID800伺服反馈
%QX0~%QX100EtherCAT DO
%QX100~%QX200Modbus / CANopen DO
%QW200~%QW500模拟输出
%QD500~%QD800伺服指令
%MX0~%MX500内部布尔标志
%MW500~%MW2000内部字变量
%MD2000~%MD4000内部实数变量

固定规划便于维护, 也方便文档交付。

扫描周期选择

周期长度决定 IO 响应时效:

周期场景代价
250 μs高端运动控制CPU 占用最高
500 μs中高端运动隔离核心要够
1 ms常见运动 + IO典型配置
2~5 ms纯 IO 采集CPU 轻松
10~50 ms慢速监控最省

选错周期的症状:

  • 太短 → CPU 持续 100%, 偶发抖动
  • 太长 → 输出响应滞后, 运动精度不够

调优方法: 先试 1ms, 看 CPU 占用 → 占用 < 50% 可以缩短 → 占用 > 80% 要延长。

过程映像模式

有两种映像模式:

同步映像 (默认)

周期开始:
1. 所有驱动 Read → 输入映像
2. 执行 PLC 程序 (读输入, 计算, 写输出)
3. 所有驱动 Write ← 输出映像
周期结束

程序看到"一致快照"。这是默认模式, 满足绝大多数 PLC 语义。

异步映像 (高级)

部分协议 (如 MQTT 订阅) 不是周期性采样, 数据可以随时到达。异步映像模式下:

  • 输入映像在任意时刻被协议栈更新
  • 程序看到的是"最新值", 不保证周期内一致

仅少数需要极低延迟的事件驱动场景启用。

强制值

调试时, 可以锁定某个 IO 的值, 程序写入和硬件采集都被忽略:

// 强制 %IX0.0 永远为 TRUE
ioManager.ForceValue("%IX0.0", true);

// 强制 %QW100 固定为 5000
ioManager.ForceValue("%QW100", (short)5000);

// 解除强制
ioManager.ReleaseForce("%IX0.0");

强制值与正常值同时显示在 IO 监视面板, 强制项有黄色标记。

强制值风险

生产环境禁止使用强制值。强制输出可能驱动真实设备产生未预期动作 (如气缸误动、电机乱转)。只在离线调试或仿真时使用。

边沿与消抖

对于数字输入, 内置信号处理:

  • 上升沿 / 下降沿 (R_TRIG, F_TRIG 标准 FB)
  • 消抖滤波: 信号必须稳定 N 个扫描周期才视为变化
  • 脉冲捕获: 即使比扫描周期短的脉冲也不丢

消抖时间在每个 IO 点的属性里配置, 不影响其他点。

模拟量处理

模拟量原始值一般是 ADC/DAC 的整数, 需要工程量转换:

// 配置: 原始值 0~32767 对应 0~10V
mapping.Add(new IOPoint {
Address = "%IW100",
ScaleFactor = 10.0 / 32767.0,
Offset = 0,
Unit = "V"
});

// PLC 读到的 %IW100 可以直接用, 已经是工程量

还支持:

  • 极限值报警: 超上下限触发报警
  • 死区过滤: 小于阈值的波动视为噪声
  • 一阶滤波: 低通平滑
  • 线性化: 对热电偶等非线性传感器分段插值

掉线保护

每个 IO 设备有通讯超时监测:

device.TimeoutMs = 3000;
device.OnTimeout = () => {
// 设为通讯故障
device.Status = DeviceStatus.Offline;
// 设置默认值 (由配置决定)
// - FreezeLast: 保持最后值
// - SetToSafe: 设为安全值
// - Passthrough: 不变, 由程序决定
};

推荐安全值方案: 输出设为 0 (停止), PLC 程序判断通讯故障标志后走安全分支。

诊断

IDE 内置 IO 诊断面板:

  • 所有 IO 设备的实时状态 (在线/离线/错误)
  • 每台设备的错误计数 (RX error / Timeout / CRC)
  • 最近 100 条设备事件日志
  • 对 EtherCAT 从站: 显示 AL_STATUS, 各端口状态
  • 对 Modbus: 显示响应时间直方图
  • 对 CANopen: 显示 NMT 状态和 EMCY 历史

更多见 IO 监控连接诊断