代码模板
DarraRT PLC 提供代码模板系统, 把常用的控制逻辑封装为可复用模板: 标准动作块 (Cylinder/Motor/Conveyor/Pump) / FB 模板 / 工艺流程模板。新项目不用从零写, 拖模板改参数即可。
模板类型
| 类型 | 用途 | 颗粒度 |
|---|---|---|
| FB 模板 | 功能块代码骨架 | POU 级 |
| 动作块 | 常见机械动作 | 多 FB 组合 |
| 工艺流程 | 多步骤工艺流程骨架 | 完整工艺 |
| 接口模板 | 标准接口定义 | INTERFACE |
| HMI 组件 | 与 HMI 绑定的模板 | 含 UI |
标准动作块库
Darra 内置一套标准动作块, 直接拖入项目:
Cylinder (气缸)
双向气缸的完整控制逻辑:
FUNCTION_BLOCK FB_Cylinder
VAR_INPUT
bExtendCmd : BOOL; // 伸出命令
bRetractCmd : BOOL; // 缩回命令
bExtendSensor : BOOL; // 伸出到位传感器
bRetractSensor : BOOL; // 缩回到位传感器
tTimeout : TIME := T#5s; // 超时时间
bReset : BOOL;
END_VAR
VAR_OUTPUT
bExtendOut : BOOL; // 伸出电磁阀
bRetractOut : BOOL; // 缩回电磁阀
bAtExtend : BOOL; // 伸出到位
bAtRetract : BOOL; // 缩回到位
bMoving : BOOL; // 运动中
bTimeout : BOOL; // 超时故障
sDiagMsg : STRING[64];
END_VAR
VAR
tonTimeout : TON;
eState : E_CylinderState;
END_VAR
// ... 完整状态机逻辑
内含:
- 互锁 (伸出 + 缩回不同时)
- 超时检测
- 到位保持
- 故障诊断
- 复位逻辑
- HMI 绑定属性
Motor (电机)
变频器 / 伺服电机通用驱动:
FUNCTION_BLOCK FB_Motor
VAR_INPUT
bEnable : BOOL;
bStart : BOOL;
bStop : BOOL;
bReset : BOOL;
rSetSpeed : REAL; // rpm
rAccelRate : REAL := 100.0; // rpm/s
rDecelRate : REAL := 200.0;
END_VAR
VAR_OUTPUT
bRunning : BOOL;
bReady : BOOL;
bFault : BOOL;
rActSpeed : REAL;
iErrorCode : INT;
sDiagMsg : STRING[64];
END_VAR
// 包含: 斜坡加减速 / 最大速度限制 / 堵转检测 / 超温检测 / 过载检测
Conveyor (输送带)
皮带 / 滚筒输送带:
FUNCTION_BLOCK FB_Conveyor
VAR_INPUT
bStart, bStop, bEStop : BOOL;
rSpeed : REAL; // m/min
bPhotoEnter : BOOL; // 进口光电
bPhotoExit : BOOL; // 出口光电
tPartTimeout : TIME := T#30s;
END_VAR
VAR_OUTPUT
bRunning : BOOL;
rActSpeed : REAL;
iPartCount : INT;
bJamFault : BOOL;
sDiagMsg : STRING[64];
END_VAR
// 包含: 启停斜坡 / 产品计数 / 堵料检测 / 节拍统计
Pump (水泵)
液体泵控制:
FUNCTION_BLOCK FB_Pump
VAR_INPUT
bStart, bStop : BOOL;
rSetFlow : REAL; // L/min
bLowLevel : BOOL; // 低液位保护
bHighLevel : BOOL; // 高液位
bDryRun : BOOL; // 空转保护
END_VAR
VAR_OUTPUT
bRunning, bFault : BOOL;
rActFlow : REAL;
iCavitation : INT; // 气蚀计数
sDiagMsg : STRING[64];
END_VAR
// 包含: 液位联锁 / 空转保护 / 气蚀检测 / PID 流量控制
Valve (阀门)
电磁阀 / 比例阀:
FUNCTION_BLOCK FB_Valve
VAR_INPUT
bOpenCmd : BOOL;
bCloseCmd : BOOL;
rSetPosition : REAL; // 比例阀 0-100%
bOpenFB : BOOL; // 开到位反馈
bCloseFB : BOOL; // 关到位反馈
END_VAR
VAR_OUTPUT
bOpenOut, bCloseOut : BOOL;
rActPosition : REAL;
bAtOpen, bAtClose : BOOL;
sDiagMsg : STRING[64];
END_VAR
Heater (加热器)
FUNCTION_BLOCK FB_Heater
VAR_INPUT
bEnable : BOOL;
rSetTemp : REAL;
rActTemp : REAL;
rMaxPower : REAL := 100.0;
rMaxTemp : REAL := 200.0; // 安全上限
END_VAR
VAR_OUTPUT
rPowerOut : REAL; // PWM 输出
bHeating : BOOL;
bOverTemp : BOOL;
sDiagMsg : STRING[64];
END_VAR
// 内置 PID + 抗积分饱和 + 过温保护
使用模板
拖入项目
- 项目树 → 模板库
- 找到目标模板 (如
FB_Cylinder) - 拖到项目树的 POU 文件夹
- IDE 复制模板代码到项目
- 改参数, 实例化, 使用
实例化模板
VAR
fbCyl_Clamp : FB_Cylinder; // 夹紧气缸
fbCyl_Push : FB_Cylinder; // 推料气缸
fbMotor_Main : FB_Motor; // 主电机
fbConveyor_In : FB_Conveyor; // 入口输送带
END_VAR
// 使用 — 每个实例独立状态
fbCyl_Clamp(bExtendCmd := bClampReq, bExtendSensor := %IX1.0, bRetractSensor := %IX1.1);
fbCyl_Push (bExtendCmd := bPushReq, bExtendSensor := %IX1.2, bRetractSensor := %IX1.3);
自定义模板
创建 FB 模板
现有代码转换为模板:
- 项目树 → 选中要转模板的 FB
- 右键 → 另存为模板
- 填写:
- 模板名:
FB_MyCustomDevice - 分类: "自定义 / 专用设备"
- 描述: 详细用途
- 参数标记: 哪些 VAR 可被调参
- 模板名:
- 保存到模板库
模板参数化
模板里用占位符:
FUNCTION_BLOCK FB_MyDevice
VAR_INPUT
bEnable : BOOL;
rTarget : REAL := {{DEFAULT_TARGET}}; // 默认值
END_VAR
VAR
tonDelay : TON;
rRange : REAL := {{VALID_RANGE}}; // 有效范围
END_VAR
// 占位符
tonDelay(IN := bEnable, PT := {{DEFAULT_DELAY}});
实例化时 IDE 弹窗让用户填写:
创建 FB_MyDevice 实例:
DEFAULT_TARGET = [ 100.0 ] (默认 100.0)
DEFAULT_DELAY = [ T#500ms ]
VALID_RANGE = [ 10.0 ]
模板导入导出
导出模板
- 右键模板 → 导出 →
.darratpl文件 - 包含: 代码 + 元数据 + 依赖声明
- 可上传到公司模板库或分享给第三方
导入模板
- 菜单 → 导入模板 → 选择
.darratpl - 检查依赖 (需要的 UDT / 常量 / 库)
- 导入后自动出现在模板库
模板包 (Template Pack)
多个相关模板打包分发:
MachineryPack_v1.2.darratpack
├── FB_Cylinder.darratpl
├── FB_Motor.darratpl
├── FB_Conveyor.darratpl
├── UDT_MotorStatus.darratpl
└── manifest.xml
整包导入, 一次获得一套完整模板。
项目级模板库
每个项目维护自己的模板子库:
项目: WeldingLine
├── 模板库
│ ├── 标准动作块 (引用全局)
│ │ ├── FB_Cylinder
│ │ └── FB_Motor
│ └── 项目专属
│ ├── FB_WeldTorch
│ ├── FB_WeldingRobot
│ └── Workflow_WeldCycle
项目专属模板不污染全局库, 其他项目无需看到。
公司模板库
多项目共享的组织级模板库:
- 配置: 设置 → 模板库 → 添加网络库
- 位置: 局域网共享盘 / Git / 云存储
- 版本控制: 每次更新模板生成新版本号
- 访问控制: 读 / 写 / 管理权限分级
跨项目一致性:
- 所有项目的
FB_Cylinder来自同一个模板 - 发现 Bug 修一次, 所有项目受益
- 新工程师不用猜命名, 直接用标准模板
模板版本管理
模板也需要版本控制:
FB_Cylinder
├── v1.0 2024-01-01 初版
├── v1.1 2024-06-01 加超时故障
├── v1.2 2025-03-01 加 HMI 诊断属性
└── v2.0 2026-01-01 重构使用 OOP
项目引用模板时锁定版本:
- 锁版本: 项目用 v1.2, 模板升级到 v2.0 不影响
- 跟随最新: 每次打开项目都提示新版本
- 手动升级: 项目主动升级, 评估兼容性
最佳实践示例: FB_Cylinder
完整的气缸模板内部实现 (简化):
FUNCTION_BLOCK FB_Cylinder
VAR_INPUT
bExtendCmd : BOOL;
bRetractCmd : BOOL;
bExtendSensor : BOOL;
bRetractSensor : BOOL;
tTimeout : TIME := T#5s;
bReset : BOOL;
END_VAR
VAR_OUTPUT
bExtendOut : BOOL;
bRetractOut : BOOL;
bAtExtend : BOOL;
bAtRetract : BOOL;
bMoving : BOOL;
bTimeout : BOOL;
sDiagMsg : STRING[64];
END_VAR
VAR
tonTimeout : TON;
eState : E_CylinderState := E_CylinderState.UNKNOWN;
END_VAR
// 主状态机
CASE eState OF
E_CylinderState.UNKNOWN:
sDiagMsg := '未知位置';
bExtendOut := FALSE;
bRetractOut := FALSE;
IF bExtendSensor THEN
eState := E_CylinderState.AT_EXTEND;
ELSIF bRetractSensor THEN
eState := E_CylinderState.AT_RETRACT;
END_IF;
E_CylinderState.AT_EXTEND:
sDiagMsg := '已伸出';
bAtExtend := TRUE;
bAtRetract := FALSE;
bMoving := FALSE;
IF bRetractCmd AND NOT bExtendCmd THEN
eState := E_CylinderState.RETRACTING;
END_IF;
E_CylinderState.AT_RETRACT:
sDiagMsg := '已缩回';
bAtExtend := FALSE;
bAtRetract := TRUE;
bMoving := FALSE;
IF bExtendCmd AND NOT bRetractCmd THEN
eState := E_CylinderState.EXTENDING;
END_IF;
E_CylinderState.EXTENDING:
sDiagMsg := '伸出中';
bExtendOut := TRUE;
bRetractOut := FALSE;
bMoving := TRUE;
tonTimeout(IN := TRUE, PT := tTimeout);
IF bExtendSensor THEN
eState := E_CylinderState.AT_EXTEND;
tonTimeout(IN := FALSE);
ELSIF tonTimeout.Q THEN
eState := E_CylinderState.FAULT;
bTimeout := TRUE;
sDiagMsg := '伸出超时';
END_IF;
E_CylinderState.RETRACTING:
sDiagMsg := '缩回中';
bExtendOut := FALSE;
bRetractOut := TRUE;
bMoving := TRUE;
tonTimeout(IN := TRUE, PT := tTimeout);
IF bRetractSensor THEN
eState := E_CylinderState.AT_RETRACT;
tonTimeout(IN := FALSE);
ELSIF tonTimeout.Q THEN
eState := E_CylinderState.FAULT;
bTimeout := TRUE;
sDiagMsg := '缩回超时';
END_IF;
E_CylinderState.FAULT:
bExtendOut := FALSE;
bRetractOut := FALSE;
bMoving := FALSE;
IF bReset THEN
bTimeout := FALSE;
eState := E_CylinderState.UNKNOWN;
END_IF;
END_CASE;
END_FUNCTION_BLOCK
使用:
VAR
fbClampCyl : FB_Cylinder;
END_VAR
// 在 OB1 或 OB30 调用
fbClampCyl(
bExtendCmd := bClampReq,
bRetractCmd := bReleaseReq,
bExtendSensor := %IX0.0,
bRetractSensor := %IX0.1,
tTimeout := T#3s,
bReset := bResetBtn
);
// 输出到气阀
%QX0.0 := fbClampCyl.bExtendOut;
%QX0.1 := fbClampCyl.bRetractOut;
// 状态上 HMI
%MD100 := fbClampCyl.sDiagMsg;
排错表
| 问题 | 原因 | 解决 |
|---|---|---|
| 模板找不到 | 模板库未加载 | 设置 → 模板库 → 添加路径 |
| 导入依赖缺失 | 模板依赖其他 UDT | 先导入依赖再导入主模板 |
| 占位符未替换 | 实例化跳过了 | 重新实例化, 填写所有占位符 |
| 模板和项目 FB 冲突 | 同名 | 重命名或改命名空间 |
| 更新模板后项目出错 | 接口不兼容 | 锁版本或手动迁移 |
最佳实践
- 优先用标准模板: 公司 / Darra 提供的模板久经考验
- 新 FB 设计前先查模板库: 90% 的需求有现成模板
- 模板必含诊断属性:
sDiagMsg/iErrorCode是标配 - 占位符命名清晰:
{{DEFAULT_TIMEOUT}}不如{{HomeTimeoutSec}} - 模板版本锁定: 项目用 LTS 版本, 不随意升级
- 内部规范先行: 公司建立自己的命名和接口规范, 模板套规范
- 文档齐全: 每个模板的 Markdown 说明必不可少