1. 项目背景与核心价值
在工业自动化领域,PID控制算法是最基础也最经典的控制方法。西门子S7-200 SMART系列PLC凭借其高性价比,在中小型自动化项目中应用广泛。但官方提供的PID向导存在两个明显痛点:一是每个程序最多只能配置8路PID回路,二是生成的PID块无法直接作为子程序调用且受密码保护。
这个项目正是针对这两个痛点提出的解决方案。通过完全自主编写PID算法,不仅突破了8路限制,还实现了子程序化的封装,使PID控制可以像普通功能块一样灵活调用。我在多个恒压供水、温度控制项目中实际应用过这套方案,单台PLC最多实现了16路PID控制,运行稳定可靠。
2. PID算法原理与实现要点
2.1 离散化PID公式推导
工业PLC采用的是离散化PID控制,核心公式如下:
code复制输出 = Kp×e + Ki×Σe + Kd×(e - e_prev)
其中:
- e = 设定值(SP) - 过程值(PV)
- Kp:比例系数
- Ki:积分系数 = Kp×采样时间/积分时间
- Kd:微分系数 = Kp×微分时间/采样时间
在S7-200 SMART中需要用实数(float)类型存储这些参数。特别注意SMART200的实数运算范围是±1.175495E-38到±3.402823E+38,要防止运算溢出。
2.2 关键数据结构设计
每个PID实例需要维护以下变量:
STL复制// 输入参数
PV_IN REAL // 过程值输入
SP REAL // 设定值
Kp REAL // 比例系数
Ti REAL // 积分时间(分钟)
Td REAL // 微分时间(分钟)
Out_MIN REAL // 输出下限
Out_MAX REAL // 输出上限
// 内部状态变量
Last_PV REAL // 上次过程值
Integral REAL // 积分项累加值
2.3 抗积分饱和处理
当输出持续处于极限值时,积分项会不断累积导致"积分饱和"。我的解决方案是:
- 当输出达到上限且误差为正时,停止积分累加
- 当输出达到下限且误差为负时,停止积分累加
- 增加输出限幅判断
对应的STL实现:
STL复制LD SM0.0
MOVR PV_IN, Last_PV // 保存当前值供下次使用
// 计算误差项
SUB_R SP, PV_IN, #Error
// 比例项
MUL_R Kp, #Error, #P_Term
// 积分项(带抗饱和)
LD Out >= Out_MAX
A Error > 0.0
JMP No_Integral
LD Out <= Out_MIN
A Error < 0.0
JMP No_Integral
MUL_R Error, Kp, #Temp
MUL_R #Temp, T#1m, #Temp // T#1m是采样周期
DIV_R #Temp, Ti, #Temp
ADD_R #Temp, Integral, Integral
No_Integral: NOP
// 微分项
SUB_R PV_IN, Last_PV, #D_Temp
MUL_R Kp, Td, #Temp
DIV_R #Temp, T#1m, #Temp
MUL_R #Temp, #D_Temp, #D_Term
3. 子程序化封装实现
3.1 接口标准化设计
为了使PID块可以像系统功能块一样调用,需要规范输入输出接口:
code复制// 输入参数
PV_IN REAL // I0.0等模拟量输入地址
SP REAL // VD100等设定值存储地址
...其他参数...
// 输出参数
OUT REAL // QW0等输出地址
3.2 无密码调用关键技术
西门子官方PID块受密码保护无法查看内部逻辑。我们的方案:
- 使用SBR子程序类型创建
- 所有参数通过局部变量(L区)传递
- 内部使用临时变量存储中间状态
调用示例:
STL复制LD SM0.0
CALL PID_Control, DB1.DBD0, VD100, 0.5, 2.0, 0.1, 0.0, 100.0, AQW0
3.3 多实例支持方案
通过以下方法实现多路PID:
- 每个PID实例使用独立的数据块(DB)
- 状态变量以DB块偏移地址方式访问
- 调用时传入不同的DB块指针
典型的多路PID调用结构:
STL复制Network 1: // PID回路1
LD SM0.0
CALL PID_Control, &VB0, VD100, 0.5, 2.0, 0.1, 0.0, 100.0, AQW0
Network 2: // PID回路2
LD SM0.0
CALL PID_Control, &VB100, VD200, 1.0, 3.0, 0.2, 0.0, 100.0, AQW2
4. 工程实践与优化技巧
4.1 采样周期选择经验
根据被控对象特性选择采样周期:
- 流量控制:0.5-2秒
- 压力控制:2-5秒
- 温度控制:10-30秒
- 液位控制:5-10秒
在程序中用定时中断实现精确周期控制:
STL复制// 在中断程序INT0中
LD SM0.0
CALL PID_Control, ...
4.2 参数整定现场技巧
推荐采用临界比例度法现场整定:
- 先将Ti设为无穷大,Td设为0
- 逐渐增大Kp直到系统出现等幅振荡
- 记录此时的临界增益Ku和振荡周期Tu
- 按以下经验公式设置:
- Kp = 0.6Ku
- Ti = 0.5Tu
- Td = 0.12Tu
4.3 常见问题排查指南
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 输出剧烈震荡 | Kp过大 | 减小Kp,增加Ti |
| 响应迟缓 | Kp过小 | 增大Kp,减小Ti |
| 稳态误差大 | 积分作用弱 | 减小Ti值 |
| 超调量大 | 微分作用弱 | 适当增加Td |
5. 性能优化与高级功能
5.1 变积分系数算法
对于非线性系统,可以采用变积分系数:
STL复制// 根据误差大小调整积分作用
LD ABS(Error) > 10.0
MOVR 0.5, #Ki_Actual // 大误差时减弱积分
ELSE
MOVR 1.0, #Ki_Actual // 小误差时正常积分
ENDIF
5.2 死区补偿处理
对于存在死区的执行机构:
STL复制// 死区补偿
LD OUT > 0.0
A OUT < DeadBand
MOVR DeadBand, OUT
LD OUT < 0.0
A OUT > -DeadBand
MOVR -DeadBand, OUT
5.3 串级PID实现方案
对于复杂控制对象,可以嵌套调用PID子程序实现串级控制:
STL复制// 主回路
CALL PID_Main, ...
// 副回路(将主回路输出作为设定值)
MOVR #Main_OUT, #Sub_SP
CALL PID_Sub, ...
这套方案已经在恒压供水系统中成功应用,主PID控制总管压力,副PID控制泵转速,相比单回路控制压力波动减小了60%。