跳到主要内容

高级功能块

Darra PLC 提供标准功能块 (Standard FBs) 之外的高级功能块体系,涵盖 PID 闭环控制、运动控制、安全监控以及自定义功能块开发框架。

PID 控制器

PID 功能块 (FB_PID) 实现比例-积分-微分闭环控制,适用于温度、压力、流量等连续过程。

功能块接口

FUNCTION_BLOCK FB_PID
VAR_INPUT
bEnable : BOOL; // 使能
rSetpoint : REAL; // 设定值 (SP)
rFeedback : REAL; // 反馈值 (PV)
rKp : REAL; // 比例增益
rKi : REAL; // 积分增益
rKd : REAL; // 微分增益
rOutMin : REAL; // 输出下限
rOutMax : REAL; // 输出上限
bManual : BOOL; // 手动模式
rManualOut : REAL; // 手动输出值
bReset : BOOL; // 复位积分器
rDeadband : REAL := 0.0; // 死区宽度
END_VAR
VAR_OUTPUT
rOutput : REAL; // 控制输出 (CV)
rError : REAL; // 当前偏差
bAtSetpoint : BOOL; // 到达设定值 (偏差在死区内)
bLimited : BOOL; // 输出已限幅
END_VAR

参数详细说明

PID 控制器的核心参数控制闭环响应的三个维度。正确理解每个参数的作用是调参的基础。

参数符号范围作用增大效果减小效果
比例增益rKp0.0 ~ 1e6偏差的即时放大倍数响应加快,可能振荡响应变慢,稳态误差增大
积分时间rTi0.0 ~ 1e6 s积分作用的衰减时间,越小积分越强误差快速归零,可能超调稳态误差残留
微分时间rTd0.0 ~ 1e6 s微分作用的超前时间,越大阻尼越强阻尼增强,抗干扰超调增大,响应变慢
输出下限rOutMin任意控制输出最小值限制控制范围可能无法达到设定值
输出上限rOutMax任意控制输出最大值放宽控制范围可能无法达到设定值
积分下限rIntMin任意积分项独立下限防止积分负饱和限制积分补偿能力
积分上限rIntMax任意积分项独立上限防止积分正饱和限制积分补偿能力
死区rDeadBand≥ 0偏差在此范围内输出不变动作减少,抑制抖动动作频繁
微分滤波rTauD≥ 0微分一阶低通滤波时间常数降低噪声敏感度微分响应滞后

输出限幅

输出限幅是安全防护的第一道关卡。当计算出的原始输出超出 rOutMin / rOutMax 范围时,输出被裁剪到边界值,同时 bLimited 置位:

// PID 内部计算
rRawOutput := rProportional + rIntegral + rDerivative;

// 输出限幅
IF rRawOutput > rOutMax THEN
rOutput := rOutMax;
bLimited := TRUE;
ELSIF rRawOutput < rOutMin THEN
rOutput := rOutMin;
bLimited := TRUE;
ELSE
rOutput := rRawOutput;
bLimited := FALSE;
END_IF;

抗积分饱和 (Anti-Windup)

PID 功能块内置两种抗积分饱和机制:

  • 条件积分: 输出饱和时暂停积分累积
  • 回算法: 将超出限幅的部分反馈到积分器中衰减

手动/自动模式切换时,积分器自动跟踪手动输出值,实现无扰切换 (Bumpless Transfer)。

温度控制示例

PROGRAM OB30    // 10ms 周期中断
VAR
fbPID_Temp : FB_PID;
rActTemp : REAL; // 实际温度 (°C)
rSetTemp : REAL; // 设定温度 (°C)
rHeaterPwr : REAL; // 加热功率 (%)
END_VAR

// 读取温度传感器 (PT100, 4-20mA → 0-200°C)
rActTemp := INT_TO_REAL(%IW100 - 4000) / 16000.0 * 200.0;

// 设定值来自 HMI
rSetTemp := %MD200;

// PID 计算
fbPID_Temp(
bEnable := TRUE,
rSetpoint := rSetTemp,
rFeedback := rActTemp,
rKp := 5.0,
rKi := 0.8,
rKd := 1.2,
rOutMin := 0.0,
rOutMax := 100.0,
bManual := %MX100.0,
rManualOut := %MD104
);

// 输出到加热器 (PWM 或模拟量)
rHeaterPwr := fbPID_Temp.rOutput;
%QW200 := REAL_TO_INT(rHeaterPwr * 327.67);
END_PROGRAM

参数整定建议

Ziegler-Nichols 法适用于大多数过程控制场景:

  1. rKirKd 设为 0
  2. 逐步增大 rKp 直到系统产生等幅振荡
  3. 记录临界增益 Ku 和振荡周期 Tu
  4. 按下表计算参数:
控制器类型KpTi/TuTd/Tu
P0.5 × Ku
PI0.45 × Ku0.85
PID0.6 × Ku0.50.125
实际调参

Ziegler-Nichols 法给出初始参数,实际应用中需要根据系统响应微调。建议使用 IDE 的趋势曲线面板观察 SP、PV、CV 的实时波形进行调参。

自整定 (Auto-Tuning)

PID 内置三种自整定算法:

算法适用场景耗时精度
继电式 (Relay)通用,经典方法3~10 周期
阶跃响应 (Step)大惯性系统 (温度)2~5 分钟中高
频率扫描 (Freq)高精度要求10~30 分钟
// 启动自整定 (继电式)
fbTune(
bStart := bBtn_StartTune,
rSetpoint := rSetTemp,
rFeedback := rActTemp,
rRelayAmplitude := 10.0,
rHysteresis := 0.5,
iMaxCycles := 5,
tTimeout := T#10m
);

// 完成时自动写入 PID 参数
IF fbTune.bDone THEN
fbPID.rKp := fbTune.rKp;
fbPID.rKi := fbTune.rKi;
fbPID.rKd := fbTune.rKd;
END_IF;

运动控制功能块

Darra 遵循 PLCopen Motion Control 标准,提供完整的单轴和多轴运动控制功能块。

MC_Power — 轴使能

在使用轴之前必须先使能。Enable 为 TRUE 时轴伺服上电。

VAR
PowerOn : MC_Power;
END_VAR

PowerOn(Axis := Axis1, Enable := TRUE, bRegulatorOn := TRUE);
// PowerOn.Status = TRUE 表示使能成功
// PowerOn.bRegulatorOn — 调节器已激活

MC_MoveAbsolute — 绝对定位

移动到指定位置坐标。

VAR
MoveAbs : MC_MoveAbsolute;
END_VAR

MoveAbs(
Axis := Axis1,
Execute := TRUE,
Position := 100.0, // 目标位置 (mm 或度)
Velocity := 50.0, // 运动速度 (mm/s)
Acceleration := 200.0, // 加速度 (mm/s²)
Deceleration := 200.0, // 减速度 (mm/s²)
Jerk := 1000.0 // 跃度 (mm/s³), 0=禁用
);
// MoveAbs.Done — 到达目标位置

MC_MoveRelative — 相对定位

从当前位置移动指定距离。

VAR
MoveRel : MC_MoveRelative;
END_VAR

MoveRel(
Axis := Axis1,
Execute := TRUE,
Distance := 50.0, // 移动距离 (正=正向, 负=反向)
Velocity := 30.0
);

MC_Halt — 暂停运动

中断当前运动,轴减速停止后保持使能状态。

VAR
HaltCmd : MC_Halt;
END_VAR

HaltCmd(Axis := Axis1, Execute := TRUE, Deceleration := 500.0);
// HaltCmd.Done — 轴已停止并保持使能

MC_Home — 回原点

轴回到参考原点位置。

VAR
HomeCmd : MC_Home;
END_VAR

HomeCmd(
Axis := Axis1,
Execute := TRUE,
HomeMode := HOME_REF_SWITCH, // 回零模式
Position := 0.0 // 原点位置值
);
// HomeCmd.Done — 回零完成

回零模式说明:

模式说明
HOME_REF_SWITCH参考开关 + 编码器 Zero
HOME_LIMIT_POS正限位回零
HOME_LIMIT_NEG负限位回零
HOME_DIRECT当前位置设为原点
HOME_ABS_ENCODER绝对编码器直接读取

参数表 (通用)

所有 MC 功能块共享以下接口参数:

参数类型说明
Axis / Robot轴/机器人引用目标对象
ExecuteBOOL上升沿触发
DoneBOOL (输出)完成标志
BusyBOOL (输出)正在执行
ActiveBOOL (输出)已被接收执行
CommandAbortedBOOL (输出)被中止
ErrorBOOL (输出)错误标志
ErrorIDUINT (输出)错误码

传送带定位完整示例

PROGRAM ConveyorControl
VAR
Power : MC_Power;
Home : MC_Home;
MoveTo : MC_MoveAbsolute;
State : INT := 0;
END_VAR

// 始终使能
Power(Axis := ConveyorAxis, Enable := TRUE);

CASE State OF
0: // 回原点
Home(Axis := ConveyorAxis, Execute := TRUE);
IF Home.Done THEN
Home(Execute := FALSE);
State := 1;
END_IF;

1: // 等待工件到位
IF %IX0.0 = TRUE THEN
State := 2;
END_IF;

2: // 传送到工位 1
MoveTo(Axis := ConveyorAxis, Execute := TRUE,
Position := 500.0, Velocity := 100.0);
IF MoveTo.Done THEN
MoveTo(Execute := FALSE);
State := 3;
END_IF;

3: // 等待加工完成
IF %IX0.1 = TRUE THEN
State := 4;
END_IF;

4: // 传送到出料位
MoveTo(Axis := ConveyorAxis, Execute := TRUE,
Position := 1000.0, Velocity := 100.0);
IF MoveTo.Done THEN
MoveTo(Execute := FALSE);
State := 1;
END_IF;
END_CASE;
END_PROGRAM

MC_GearIn — 电子齿轮

电子齿轮功能块将从轴与主轴按固定齿轮比同步运动,适用于印刷、包装、纺织等需要主轴-从轴同步的场景。

FUNCTION_BLOCK MC_GearIn
VAR_INPUT
bExecute : BOOL; // 上升沿触发啮合
rRatioNumerator : REAL; // 齿轮比分子
rRatioDenominator : REAL; // 齿轮比分母
rMasterOffset : REAL; // 主轴位置偏移
rMasterStartDistance : REAL; // 主轴启动距离 (提前同步准备)
eMasterValue : E_MasterSource; // 主轴来源
bContinuous : BOOL; // 连续啮合 (TRUE=不解耦)
END_VAR
VAR_OUTPUT
bInGear : BOOL; // 已同步啮合
bBusy : BOOL;
bCommandAborted : BOOL;
bError : BOOL;
udiErrorId : UDINT;
rFollowingError : REAL; // 当前跟随误差
END_VAR

主轴来源可配置:

主轴来源说明适用场景
SET_VALUE软件设定值作为主轴模拟主轴、虚拟主轴
ACTUAL_POSITION物理轴实际位置作为主轴跟随另一个物理轴
MODULO_POSITION模数轴位置 (旋转轴)旋转主轴
EXTERNAL_ENCODER外部编码器作为主轴飞锯、追剪

示例:印刷机色标跟踪,主轴(输送带)与印刷辊 1:1 同步:

fbGearIn(
bExecute := TRUE,
rRatioNumerator := 1.0,
rRatioDenominator := 1.0,
rMasterOffset := 0.0,
eMasterValue := E_MasterSource.ACTUAL_POSITION,
bContinuous := TRUE
);

// 检测啮合完成
IF fbGearIn.bInGear THEN
bSynchronized := TRUE;
END_IF;

MC_Phasing — 相位偏移

在齿轮啮合或凸轮同步状态下,对从轴附加一个相位偏移,用于调整套准误差或补偿机械间隙。

FUNCTION_BLOCK MC_Phasing
VAR_INPUT
bExecute : BOOL; // 上升沿触发相位偏移
rVelocity : REAL; // 相位调整速度
rPosition : REAL; // 相位偏移量
eMode : E_PhaseMode; // 偏移模式
END_VAR
VAR_OUTPUT
bDone : BOOL;
bBusy : BOOL;
bCommandAborted : BOOL;
bError : BOOL;
udiErrorId : UDINT;
END_VAR

相位偏移模式:

模式说明示例
RELATIVE相对偏移,在当前相位上增减调整 +5° 套准
ABSOLUTE绝对偏移,设定目标相位值直接设到 90°
CONTINUOUS连续偏移,保持偏移速度持续补偿同步误差

典型应用:印刷机套准调整

// 检测到套准偏差后,在齿轮啮合状态下调整相位
IF ABS(rRegistError) > 0.1 THEN
fbPhasing(
bExecute := TRUE,
rVelocity := 5.0,
rPosition := rRegistError * 0.8, // 按比例补偿
eMode := E_PhaseMode.RELATIVE
);
END_IF;

轴状态机

每个轴维护一个内部状态机,MC 功能块自动管理状态转换:

Disabled (未使能)
↓ Power.Enable = TRUE
Standstill (静止就绪)
↓ ↑
Homning (回零中) → Standstill (回零完成)
↓ ↑
DiscreteMotion (单次定位) → Standstill (到达)
↓ ↑
ContinuousMotion (连续运动)
↓ ↑
SynchronizedMotion (同步运动)
↓ ↑
ErrorStop (故障停止) → Standstill (故障复位)

状态可通过 Axis.GetState() 在程序中读取:

CASE Axis1.GetState() OF
E_AxisState.DISABLED: sState := '未使能';
E_AxisState.STANDSTILL: sState := '就绪';
E_AxisState.HOMING: sState := '回零中';
E_AxisState.DISCRETE_MOTION: sState := '定位中';
E_AxisState.CONTINUOUS_MOTION: sState := '连续运动';
E_AxisState.SYNCHRONIZED_MOTION: sState := '同步运动';
E_AxisState.ERROR_STOP: sState := '故障停止';
END_CASE;

安全功能块

Darra 提供 13 个安全功能块,遵循 IEC 61800-5-2 和 IEC 62061 规范,经认证 SIL 2 / PL d。

功能块名称功能
SF_MonitoredStop安全监控停止监控减速停止过程
SF_SafeStop1安全停止 1 (SS1)受控减速后 STO
SF_SafeStop2安全停止 2 (SS2)受控减速后 SOS
SF_SafeOperatingStop安全操作停止 (SOS)监控静止状态
SF_SafeLimitedSpeed安全限速 (SLS)速度超限检测
SF_SafeLimitedPosition安全限位 (SLP)位置超限检测
SF_SafeTorqueOff安全力矩关断 (STO)切断电机力矩输出
SF_EmergencyStop急停IEC 13850 紧急停止
SF_SafetyDoorMonitor安全门监控防护门状态检测
SF_BrakeControl安全制动控制制动器安全管理

完整的接口说明和示例见 安全功能块

自定义功能块开发

用户可以使用 SCL 语言创建自定义功能块,封装重复使用的控制逻辑。

FB 基本结构

FUNCTION_BLOCK FB_MyControl
TITLE := '自定义控制块'
AUTHOR := '工程师'
VERSION := '1.0'

VAR_INPUT
bEnable : BOOL;
rSetpoint : REAL;
rFeedback : REAL;
END_VAR
VAR_OUTPUT
bReady : BOOL;
rOutput : REAL;
udiStatus : UDINT;
END_VAR
VAR
rIntegral : REAL;
tonDelay : TON;
END_VAR

// 主执行逻辑
IF bEnable THEN
tonDelay(IN := TRUE, PT := T#500ms);
bReady := tonDelay.Q;
// 工艺计算
rIntegral := rIntegral + (rSetpoint - rFeedback) * 0.1;
rOutput := LIMIT(0.0, rIntegral, 100.0);
udiStatus := 0;
ELSE
tonDelay(IN := FALSE);
bReady := FALSE;
rIntegral := 0.0;
rOutput := 0.0;
udiStatus := 1;
END_IF;

END_FUNCTION_BLOCK

方法与属性

功能块可以包含方法(METHOD)和属性(PROPERTY),实现面向对象风格的封装:

FUNCTION_BLOCK FB_RecipeManager
VAR
arRecipes : ARRAY[0..9] OF STRING[32];
iActive : INT;
END_VAR

// 方法:激活配方
METHOD Activate : BOOL
VAR_INPUT
iIndex : INT;
END_VAR
IF iIndex >= 0 AND iIndex <= 9 THEN
iActive := iIndex;
Activate := TRUE;
ELSE
Activate := FALSE;
END_IF;
END_METHOD

// 方法:获取当前配方名
METHOD GetActiveName : STRING[32]
GetActiveName := arRecipes[iActive];
END_METHOD

// 属性:只读当前配方
PROPERTY ReadOnly pActiveName : STRING[32]
GET
pActiveName := arRecipes[iActive];
END_GET
END_PROPERTY

END_FUNCTION_BLOCK

开发规范

  • 单一职责: 每个 FB 只做一件事,不要混合 PID 逻辑和通讯逻辑
  • 输入参数验证: 在 FB 入口检查输入合法性,非法输入给出明确的诊断码
  • 内部状态封装: FB 内部变量对外部不可见,通过属性和方法暴露必要接口
  • 初始化路径: bReset 或首次调用时应能回到已知初始状态
  • 版本管理: 修改 FB 逻辑后递增 VERSION,便于现场排查
  • 错误输出: 所有 FB 都应输出 bError + udiErrorId,不要静默失败
  • 诊断属性: 每个 FB 暴露 sDiagMsg : STRING 便于在线监视
  • 避免深层继承: 继承层级不超过 3 层

三种扩展方式

当内置 FB 无法满足需求时,可以通过三种方式扩展:

方式性能安全适用场景
SCL 源码库纯算法、流程控制、逻辑封装
C/C++ DLL最高数学计算、图像处理、实时算法
.NET 程序集通讯协议、数据库、复杂协议解析

FB 类型与实例化

类型定义

功能块是一种用户定义的数据类型,包含数据和算法。每个功能块实例拥有独立的内部状态副本。

要素说明生命周期
VAR_INPUT调用者传入的参数每个扫描周期更新
VAR_OUTPUT返回给调用者的结果每个扫描周期计算
VAR_IN_OUT兼作输入和输出的参数引用传递
VAR内部状态变量跨扫描周期保持
VAR_STAT静态变量跨调用保持
VAR_TEMP临时变量单扫描周期内有效
METHOD功能块内部方法调用时执行
PROPERTY功能块属性调用时计算

单实例与多实例

// 单实例
VAR
fbConveyor : FB_ConveyorControl;
END_VAR

// 多实例数组
VAR
fbAxes : ARRAY[0..5] OF FB_AxisControl;
END_VAR

// 多实例 — 命名实例
VAR
fbTempZone1 : FB_PID;
fbTempZone2 : FB_PID;
fbTempZone3 : FB_PID;
END_VAR

实例初始化

功能块实例可以指定初始值:

VAR
fbPID1 : FB_PID := (
rKp := 2.0,
rTi := 1.5,
rTd := 0.3,
rOutMin := 0.0,
rOutMax := 100.0
);
END_VAR

多重背景数据块

实例的数据可以存储在独立的数据块中,便于调试和持久化:

// 背景数据块定义
DATA_BLOCK DB_PID_Background
fbPID_Zone1 : FB_PID;
fbPID_Zone2 : FB_PID;
fbPID_Zone3 : FB_PID;
END_DATA_BLOCK

// 访问
DB_PID_Background.fbPID_Zone1.rKp := 2.5;

功能块调用约定

// 方式一:标准调用(推荐)
fbPID(
bEnable := TRUE,
rSetpoint := rSetTemp,
rFeedback := rActTemp
);

// 方式二:连续赋值(适用于状态机)
fbPID.bEnable := TRUE;
fbPID.rSetpoint := rSetTemp;
fbPID.rFeedback := rActTemp;
fbPID(); // 执行 FB

// 方式三:CAL 关键字
CAL fbPID(bEnable := TRUE, rSetpoint := rSetTemp);

相关文档