跳到主要内容

代码模板

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 + 抗积分饱和 + 过温保护

使用模板

拖入项目

  1. 项目树 → 模板库
  2. 找到目标模板 (如 FB_Cylinder)
  3. 拖到项目树的 POU 文件夹
  4. IDE 复制模板代码到项目
  5. 改参数, 实例化, 使用

实例化模板

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 模板

现有代码转换为模板:

  1. 项目树 → 选中要转模板的 FB
  2. 右键 → 另存为模板
  3. 填写:
    • 模板名: FB_MyCustomDevice
    • 分类: "自定义 / 专用设备"
    • 描述: 详细用途
    • 参数标记: 哪些 VAR 可被调参
  4. 保存到模板库

模板参数化

模板里用占位符:

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 说明必不可少

相关文档