IEC 61499 分布式控制
Darra IDE 支持 IEC 61499 分布式控制模型,采用事件驱动的功能块网络架构,适用于跨 PLC 协调、分布式 I/O 与模块化工艺单元控制。与 IEC 61131-3 周期扫描模型互补,覆盖从单机到产线的全场景需求。
1. IEC 61499 标准概述
1.1 标准背景
IEC 61499 是国际电工委员会发布的分布式控制系统功能块标准,第一版于 2005 年发布,第二版于 2012 年修订。其核心目标是为分布式工业控制系统提供统一的软件架构模型,使控制逻辑可以在不同厂商的设备之间移植和互操作。
与 IEC 61131-3 面向单控制器的周期扫描模型不同,IEC 61499 从设计之初就面向多控制器、分布式、事件驱动的场景。
1.2 核心概念
| 概念 | 说明 |
|---|---|
| 功能块 (FB) | 控制逻辑的最小封装单元,具有输入/输出事件和数据接口 |
| 事件控制图 (ECC) | 定义功能块的内部状态机行为,事件触发状态迁移 |
| 应用 (Application) | 由多个功能块通过事件/数据连接构成的分布式控制程序 |
| 设备 (Device) | 物理或虚拟控制器,承载功能块网络的运行 |
| 资源 (Resource) | 设备内部的独立执行上下文,可同时运行多个资源 |
| 分布模型 | 一个应用可跨多个设备部署,功能块分布在不同的 Runtime 上 |
2. 与 IEC 61131-3 的区别
2.1 执行模型对比
| 维度 | IEC 61131-3 | IEC 61499 |
|---|---|---|
| 执行驱动 | 周期扫描(OB 循环) | 事件驱动(事件触发 FB 执行) |
| 控制流 | 固定扫描顺序(OB1 → OB35 → …) | 由事件连接图决定 |
| 数据流 | 全局变量 / DB 共享 | 功能块间显式数据连接 |
| 分布模型 | 单控制器 + 远程 I/O | 多控制器原生支持 |
| 状态机 | 无原生状态机(需自行编写 SCL) | ECC 原生状态机 |
| 实时性 | 确定周期扫描,适合硬实时 | 事件响应时间取决于网络拓扑 |
| 模块化 | 功能块为组织单元 | 功能块 + 分布式应用 |
2.2 何时使用 IEC 61499
- 跨 PLC 协调: 两台以上 PLC 需要协同执行同一工艺逻辑
- 模块化产线: 每个工位独立控制器,通过事件同步
- 分布式 I/O 架构: I/O 站点分散在多处,需事件触发采集
- 灵活重配置: 运行时动态更改控制拓扑而不停机
- 与 IT 系统集成: 事件驱动更适合与 MES / SCADA / 数据库交互
2.3 何时使用 IEC 61131-3
- 单机高速控制: 伺服周期 ≤ 1ms,需确定扫描周期
- 安全相关逻辑: SIL 2/3 安全功能要求确定性扫描
- 已有成熟代码: 大量现有 IEC 61131-3 工程迁移成本高
- 硬实时约束: 微秒级抖动要求下,周期扫描更可靠
Darra 推荐: 单机运动控制、安全逻辑、高速 IO 走 IEC 61131-3(SCL/LAD);产线协调、分布式控制、模块化工艺单元走 IEC 61499。两种模型可在同一项目中混合使用。
3. 功能块与事件控制图
3.1 功能块接口模型
IEC 61499 功能块的标准接口包含四个区域:
┌─────────────────────────────┐
│ FB_Type_Name │
│ ┌───────┐ ┌───────┐ │
│ │ EI1 │ │ EO1 │ │
│ │ EI2 │ │ EO2 │ │
│ └───────┘ └───────┘ │
│ │
│ ┌───────┐ ┌───────┐ │
│ │ DI1 │ │ DO1 │ │
│ │ DI2 │ │ DO2 │ │
│ └───────┘ └───────┘ │
└─────────────────────────────┘
- 左侧上方: 输入事件 (Event Inputs) — 触发 FB 执行
- 右侧上方: 输出事件 (Event Outputs) — 执行完成后发出
- 左侧下方: 输入数据 (Data Inputs) — 事件触发时读取
- 右侧下方: 输出数据 (Data Outputs) — 事件触发后更新
3.2 事件与数据的关系
核心原则: 数据通过事件驱动流动。当输入事件到达时,FB 读取关联的输入数据,执行内部逻辑,更新输出数据,然后发出输出事件。
// E_CYCLE — 周期触发功能块 (Basic FB)
FUNCTION_BLOCK E_CYCLE
EVENT INPUT
START : EVENT;
STOP : EVENT;
END_EVENT
EVENT OUTPUT
EO : EVENT;
END_EVENT
DATA INPUT
DT : TIME := T#1s; // 周期
END_DATA
DATA OUTPUT
OUT : BOOL;
END_DATA
// 内部变量
VAR
timer : TIME;
running : BOOL := FALSE;
END_VAR
// ECC 状态机行为
ECC
INITIAL STATE IDLE:
START -> RUNNING;
END_STATE
STATE RUNNING:
// 每 DT 时间发出 EO 事件
EO -> IDLE (DT);
END_STATE
END_ECC
END_FUNCTION_BLOCK
3.3 基本功能块类型
| 类型 | 说明 | 用途 |
|---|---|---|
| Basic FB | 内含 ECC 状态机,行为由状态图定义 | 逻辑控制、状态管理 |
| Composite FB | 由多个子 FB 组成的网络 | 复杂逻辑的层级封装 |
| Service Interface FB | 封装硬件或系统服务接口 | 驱动封装、通信接口 |
| Adapter FB | 提供标准化交互接口 | 设备互操作、即插即用 |
3.4 事件控制图 (ECC) 详解
ECC 是 IEC 61499 的核心创新 — 它将功能块的内部行为定义为显式状态机,每个状态可以执行一组算法(用 SCL 或 LAD 实现),并在满足条件时触发状态迁移。
ECC 的关键要素:
- 状态 (State): 功能块的生命周期阶段,每个状态可关联零到多个算法
- 迁移 (Transition): 从当前状态到下一状态的条件,由事件 + 布尔条件组成
- 算法 (Algorithm): 状态中执行的逻辑,用 SCL、LAD 或 IEC 61499 原生语言编写
- 初始状态 (Initial State): 功能块初始化后进入的默认状态
// 带 ECC 的 Basic FB 完整示例
FUNCTION_BLOCK CONVEYOR_CTRL
EVENT INPUT
START : EVENT;
STOP : EVENT;
PART_ARRIVED : EVENT;
RESET : EVENT;
END_EVENT
EVENT OUTPUT
RUNNING_EO : EVENT;
STOPPED_EO : EVENT;
FAULT_EO : EVENT;
END_EVENT
DATA INPUT
Sensor1 : BOOL;
Sensor2 : BOOL;
MotorSpeed : INT;
END_DATA
DATA OUTPUT
MotorOut : BOOL;
SpeedCmd : INT;
FaultCode : INT;
END_DATA
VAR
cycleCount : INT := 0;
timer : TIME;
END_VAR
ECC
INITIAL STATE IDLE:
START -> RUNNING;
RESET -> IDLE; // 自环
END_STATE
STATE RUNNING:
ALGORITHM StartMotor IN SCL:
MotorOut := TRUE;
SpeedCmd := MotorSpeed;
cycleCount := cycleCount + 1;
END_ALGORITHM
PART_ARRIVED AND Sensor1 -> CHECKING;
STOP -> IDLE;
Sensor2 AND NOT Sensor1 -> ERROR;
END_STATE
STATE CHECKING:
ALGORITHM CheckPart IN LAD:
// 使用梯形图检查工件位置
// Network 1: Sensor1 AND Sensor2 -> OK
END_ALGORITHM
RUNNING_EO -> RUNNING;
FAULT_EO AND NOT Sensor1 -> ERROR;
END_STATE
STATE ERROR:
ALGORITHM SetFault IN SCL:
MotorOut := FALSE;
SpeedCmd := 0;
FaultCode := 100;
END_ALGORITHM
RESET -> IDLE;
END_STATE
END_ECC
END_FUNCTION_BLOCK
4. 分布式应用模型
4.1 应用的概念
在 IEC 61499 中,应用是最高层级的编程单元 — 它是由多个功能块通过事件连接和数据连接构成的完整控制程序,且这些功能块可以分布在不同的物理设备上。
4.2 事件连接
事件连接定义了功能块之间的事件传递路径,决定控制流的走向。每个输出事件可以连接到多个输入事件(扇出),也可以多个输出事件合并到一个输入(通过 OR 逻辑)。
// 应用级别的事件连接
APPLICATION ConveyorRobotApp
// 事件连接
EVENTS
// SensorInput.EO → ConveyorLogic.OBJ_DETECTED
CONNECT SensorInput.EO TO ConveyorLogic.OBJ_DETECTED;
// ConveyorLogic.ROBOT_REQ → RobotController.START
CONNECT ConveyorLogic.ROBOT_REQ TO RobotController.START;
// RobotController.GRIP_CMD → GripperControl.GRIP
CONNECT RobotController.GRIP_CMD TO GripperControl.GRIP;
// GripperControl.DONE → SensorInput.RESET
CONNECT GripperControl.DONE TO SensorInput.RESET;
END_EVENTS
// 数据连接
DATA
CONNECT SensorInput.Position TO ConveyorLogic.PosIn;
CONNECT ConveyorLogic.SpeedRef TO RobotController.SpeedRef;
CONNECT RobotController.GripForce TO GripperControl.ForceSet;
END_DATA
END_APPLICATION
4.3 数据连接
数据连接定义了功能块之间的数据传递。关键约束: 数据不独立流动,必须由关联的事件触发传输。
4.4 跨设备部署
将一个应用的功能块部署到不同设备时,底层通信由 Darra 运行时自动处理:
- 同设备: 事件和数据通过共享内存传递(零拷贝)
- 跨设备: 事件和数据通过 DarraLink 18821 或 OPC UA 自动编组传输
- 跨子网: 通过 RemoteAccessServer 18443 中继,支持 NAT 穿透
// 设备映射声明
DEVICE_MAPPING
// 将 FB 实例部署到指定设备
INSTANCE SensorInput ON Device_A;
INSTANCE ConveyorLogic ON Device_A;
INSTANCE RobotController ON Device_B;
INSTANCE GripperControl ON Device_B;
END_DEVICE_MAPPING
5. IDE 中的 FbEditor 使用指南
5.1 打开 FbEditor
- 在项目树中右键单击 "IEC 61499 应用" → "新建功能块"
- 选择 FB 类型(Basic / Composite / Service Interface / Adapter)
- 输入 FB 名称,自动创建
.fb文件并在 FbEditor 中打开
5.2 FbEditor 布局
┌─────────────────────────────────────────────────────┐
│ 工具栏: 添加事件 / 添加数据 / 连线 / 删除 / 验证 │
├──────────────────┬──────────────────────────────────┤
│ 接口定义面板 │ ECC 可视化画布 │
│ ┌────────────┐ │ ┌──────────────────────────┐ │
│ │ Event In │ │ │ 状态节点 + 迁移箭头 │ │
│ │ Event Out │ │ │ 拖拽编辑 │ │
│ │ Data In │ │ └──────────────────────────┘ │
│ │ Data Out │ │ │
│ └────────────┘ │ │
├──────────────────┴──────────────────────────────────┤
│ 属性面板: 当前选中元素的详细参数 │
└─────────────────────────────────────────────────────┘
5.3 操作步骤
- 定义接口: 在接口定义面板中,通过"添加事件输入"、"添加数据输出"等按钮定义 FB 的接口签名
- 设计 ECC: 在 ECC 画布上拖拽状态节点,用箭头连接迁移
- 编写算法: 双击状态节点,在代码编辑器中用 SCL 或 LAD 编写算法逻辑
- 验证: 点击"验证"检查接口一致性、ECC 可达性、类型匹配
- 保存: 自动保存为
.fb文件,编译时生成对应的运行时代码
5.4 快捷操作
| 操作 | 快捷键 | 说明 |
|---|---|---|
| 添加状态 | Ctrl+Shift+S | 在 ECC 画布添加新状态 |
| 添加迁移 | Ctrl+Shift+T | 从当前状态添加迁移到目标状态 |
| 添加算法 | Ctrl+Shift+A | 为当前状态添加新算法 |
| 验证 | F7 | 编译并验证 FB 完整性 |
| 自动布局 | Ctrl+L | 自动排列 ECC 状态节点 |
| 缩放适应 | Ctrl+0 | 缩放画布适应窗口 |
6. IDE 中的 EccEditor 使用指南
6.1 ECC 编辑基础
ECC 编辑器是 FbEditor 内置的可视化状态机设计工具。每个状态节点包含:
- 状态名称: 位于节点顶部
- 关联算法列表: 状态进入时执行的算法
- 输出事件: 算法执行后发出的输出事件
- 迁移出口: 指向下一个状态的条件箭头
6.2 状态类型
| 类型 | 图标 | 说明 |
|---|---|---|
| 初始状态 | 双圈 | FB 初始化后自动进入,每个 FB 有且仅有一个 |
| 普通状态 | 单圈 | 执行算法的中间状态 |
| 终止状态 | 粗圈 | 可选,表示执行结束 |
6.3 迁移条件语法
迁移条件支持以下格式:
// 纯事件触发
EVENT_NAME
// 事件 + 数据条件
EVENT_NAME AND (variable > 100)
// 事件 + 多个条件
EVENT_NAME AND (sensor1 AND NOT sensor2)
// 超时迁移 (DT 时间后自动触发)
EO -> NEXT_STATE (T#500ms)
6.4 验证规则
ECC 编辑器会在验证时检查以下规则:
- 可达性: 所有状态必须从初始状态可达
- 确定性: 同一状态在相同事件下不应有歧义迁移
- 完整性: 所有输入事件必须被至少一个迁移引用
- 类型安全: 数据连接的类型必须兼容
- 循环检测: 检测无限循环(无出口的迁移环)
7. 应用示例
7.1 示例一: 分布式输送线控制
场景: 一条输送线由两台 PLC 控制(入口段 + 出口段),中间通过转台衔接。需要事件同步确保工件不会在转台处碰撞。
// ==== PLC #1: 入口段控制 ====
FUNCTION_BLOCK INFEED_CTRL
EVENT INPUT
REQUEST_PART : EVENT;
TURNTABLE_READY : EVENT;
END_EVENT
EVENT OUTPUT
PART_READY : EVENT;
FEED_DONE : EVENT;
END_EVENT
DATA OUTPUT
PartID : INT;
PartType : INT;
END_DATA
VAR
currentPart : INT := 0;
END_VAR
ECC
INITIAL STATE IDLE:
REQUEST_PART -> FEEDING;
END_STATE
STATE FEEDING:
ALGORITHM FeedPart IN SCL:
currentPart := currentPart + 1;
PartID := currentPart;
PartType := currentPart MOD 3; // 三种类型循环
END_ALGORITHM
PART_READY -> WAIT_TURNTABLE;
END_STATE
STATE WAIT_TURNTABLE:
TURNTABLE_READY -> IDLE;
FEED_DONE -> IDLE; // 超时兜底
END_STATE
END_ECC
END_FUNCTION_BLOCK
// ==== PLC #2: 出口段控制 ====
FUNCTION_BLOCK OUTFEED_CTRL
EVENT INPUT
PART_ARRIVED : EVENT;
END_EVENT
EVENT OUTPUT
TURNTABLE_READY : EVENT;
PROCESS_DONE : EVENT;
END_EVENT
DATA INPUT
PartID : INT;
PartType : INT;
END_DATA
VAR
processTimer : TIME;
END_VAR
ECC
INITIAL STATE IDLE:
PART_ARRIVED -> PROCESSING;
END_STATE
STATE PROCESSING:
ALGORITHM ProcessPart IN SCL:
// 根据 PartType 选择工艺
CASE PartType OF
0: // 焊接
processTimer := T#2s;
1: // 贴标
processTimer := T#1s;
2: // 检测
processTimer := T#3s;
END_CASE
END_ALGORITHM
TURNTABLE_READY -> IDLE;
PROCESS_DONE AND (processTimer <= T#0s) -> IDLE;
END_STATE
END_ECC
END_FUNCTION_BLOCK
应用级连接:
APPLICATION ConveyorLineApp
EVENTS
// PLC #1 内部
CONNECT HMI_Start.EO TO Infeed.REQUEST_PART;
CONNECT Infeed.PART_READY TO Turntable.START;
CONNECT Turntable.DONE TO Outfeed.PART_ARRIVED;
// 跨 PLC (自动编组)
CONNECT Outfeed.TURNTABLE_READY TO Infeed.TURNTABLE_READY;
END_EVENTS
DATA
CONNECT Infeed.PartID TO Outfeed.PartID;
CONNECT Infeed.PartType TO Outfeed.PartType;
END_DATA
END_APPLICATION
DEVICE_MAPPING
INSTANCE Infeed ON PLC_1;
INSTANCE Turntable ON PLC_1;
INSTANCE Outfeed ON PLC_2;
END_DEVICE_MAPPING
7.2 示例二: 多轴机器人协调
场景: 两台 SCARA 机器人共享一个工作台,需要互锁防止碰撞。
FUNCTION_BLOCK SCARA_Coordinator
EVENT INPUT
CYCLE_START : EVENT;
ACK1 : EVENT;
ACK2 : EVENT;
EMERGENCY : EVENT;
END_EVENT
EVENT OUTPUT
REQ1 : EVENT;
REQ2 : EVENT;
CYCLE_DONE : EVENT;
FAULT : EVENT;
END_EVENT
DATA OUTPUT
FaultCode : INT;
Zone1Occupied : BOOL;
Zone2Occupied : BOOL;
END_DATA
VAR
overlapZone : BOOL := FALSE;
cycleActive : BOOL := FALSE;
END_VAR
ECC
INITIAL STATE STANDBY:
CYCLE_START -> PLAN;
EMERGENCY -> SAFE_STOP;
END_STATE
STATE PLAN:
ALGORITHM PlanSequence IN SCL:
// 检查重叠区域
IF NOT overlapZone THEN
Zone1Occupied := TRUE;
Zone2Occupied := FALSE;
ELSE
// 重叠时只允许一台进入
Zone1Occupied := TRUE;
Zone2Occupied := FALSE;
overlapZone := FALSE;
END_IF;
END_ALGORITHM
REQ1 -> WAIT_R1;
END_STATE
STATE WAIT_R1:
ACK1 -> CHECK_R2;
EMERGENCY -> SAFE_STOP;
END_STATE
STATE CHECK_R2:
ALGORITHM CheckZone IN SCL:
// 安全互锁:R1 离开重叠区后才释放 R2
Zone2Occupied := TRUE;
END_ALGORITHM
REQ2 -> WAIT_R2;
END_STATE
STATE WAIT_R2:
ACK2 -> COMPLETE;
EMERGENCY -> SAFE_STOP;
END_STATE
STATE COMPLETE:
ALGORITHM FinishCycle IN SCL:
Zone1Occupied := FALSE;
Zone2Occupied := FALSE;
cycleActive := FALSE;
END_ALGORITHM
CYCLE_DONE -> STANDBY;
END_STATE
STATE SAFE_STOP:
ALGORITHM EmergencyStop IN SCL:
Zone1Occupied := FALSE;
Zone2Occupied := FALSE;
cycleActive := FALSE;
FaultCode := 999;
END_ALGORITHM
FAULT -> STANDBY;
END_STATE
END_ECC
END_FUNCTION_BLOCK
8. 最佳实践
8.1 设计原则
- 事件粒度适中: 每个事件携带的数据量不宜过大,典型事件应触发一个完整的控制动作
- 状态数量控制: 单个 FB 的 ECC 状态数建议控制在 10 个以内,超过时考虑拆分为 Composite FB
- 数据封装: 功能块的内部数据对外部不可见,通过数据输出接口暴露
- 跨设备延迟预算: 跨 PLC 的事件传播延迟应考虑网络开销,硬实时路径走同设备
- 故障传播隔离: 每个 FB 应有独立的 ERROR 状态和 RESET 路径,防止故障级联
8.2 性能考虑
| 部署方式 | 事件延迟 | 适用场景 |
|---|---|---|
| 同设备 (共享内存) | < 10 µs | 高速逻辑、互锁 |
| 同网络 (EtherCAT) | < 100 µs | 分布式运动控制 |
| 同网络 (DarraLink 18821) | < 1 ms | 跨 PLC 协调 |
| 跨子网 (RemoteAccess) | < 10 ms | 远程监控、上位机联动 |
8.3 调试与诊断
- 事件跟踪: 在 IDE 在线监视模式下,可以实时看到每个功能块的事件触发计数
- 状态快照: 读取每个 FB 的当前 ECC 状态,帮助定位卡在哪个状态
- 断点: 在 ECC 迁移上设置断点,事件到达时暂停执行
- 日志: 每个 FB 的输入/输出事件变化自动记录到诊断日志
9. 局限性说明
IEC 61499 在 Darra 中的当前实现为 P4 优先级,以下能力尚在开发中:
| 能力 | 状态 | 预计版本 |
|---|---|---|
| Basic FB + ECC 编辑器 | 可用 (P3) | v1.0.6 |
| Composite FB 层级嵌套 | 骨架可用 | v1.1.0 |
| Service Interface FB 扩展 SDK | 待开发 | v1.2.0 |
| Adapter FB 即插即用协议 | 待开发 | v1.3.0 |
| 跨设备自动编组部署 | 待开发 | v1.4.0 |
| IEC 61499 与 IEC 61131-3 混合工程 | 设计阶段 | v1.5.0 |
| OPC Foundation CTT 一致性认证 | 计划中 | v2.0.0 |
10. 参考资源
- IEC 61499-1: 架构 — 功能块模型、应用模型、设备模型
- IEC 61499-2: 软件工具需求 — IDE 接口与数据交换格式
- IEC 61499-4: 一致性行规 — 互操作性测试规范
- Darra IDE: 项目树 → IEC 61499 应用 → 新建功能块
- 示例项目:
Darra_Software_PLC/examples/iec61499/conveyor-line/
本文档对应 Darra IDE v1.0.6+,IEC 61499 编辑器功能持续演进中。