
1. 项目概述与核心思路1.1 为什么用S7-1200做恒温热水器控制之前接了一个小型恒温热水器的控制项目客户要求把水温稳定在设定值正负1度以内而且要在进水流量波动的情况下尽量不产生大幅温度起伏。我第一反应就是用温控表但客户现场已经有了一套S7-1200 PLC在跑其他逻辑不希望为了一个温度回路单独再上一块表于是直接在S7-1200里做PID控制就成了最顺理成章的方案。选择S7-1200而不是S7-200 SMART或者S7-300主要考虑三点。第一S7-1200的CPU自带模拟量输入输出通道通过扩展SM1231/ SM1232或者直接用1214C DC/DC/DC再加模拟量模块就能采集温度传感器信号并输出控制量给加热执行器不需要额外的PID控制器硬件。第二TIA Portal里集成了PID_Compact指令这是西门子专门为S7-1200/1500做的PID功能块内部已经封装好了抗积分饱和、手动/自动无扰切换、自整定等逻辑比自己写位置式或增量式算法省太多事。第三S7-1200的扫描周期足够快PID运算一般放在OB30循环中断里执行中断时间设个100到200毫秒对温度这种大惯性对象来说完全够用。这个项目的控制对象是一个储水式加热罐加热管功率大概6kW温度传感器用PT100通过SB1231热电阻模块接入PLC。执行机构是可控硅调功器输出4到20mA信号控制加热功率。整个回路从传感器采样到加热功率变化中间隔着水的热容量和罐体热传导惯性很大纯靠手动开关加热的方式会让温度上下乱窜所以必须用PID做闭环调节。1.2 PID控制方案选型串联级联还是单回路有朋友问过我恒温热水器需不需要上串级PID。串级PID一般用在对象滞后很大、或者说内外两个被控量之间有明显耦合关系的场合比如加热炉的外壁温度和炉膛温度或者蒸汽换热器的出口温度和蒸汽流量。热水器这种单容对象水的混合和传热过程虽然有一定惯性但用单回路PID加合理的参数整定就能达到不错的控制效果上串级反而会把系统搞复杂调起来也麻烦。那有没有必要用模糊PID或者自适应PID呢实话说S7-1200的PID_Compact里已经包含了自适应能力——它可以根据过程值的变化趋势动态调整部分参数但对于恒温热水器这种工况相对固定的对象固定参数的PID完全够用。我最后采用的是单回路PID_Compact控制模式选为“温度调节”输出直接控制可控硅调功器的电流信号。这里也顺便说说位置式PID和增量式PID的区别。如果自己写算法位置式PID输出的直接是执行机构应该达到的开度绝对值比如加热功率百分之六十增量式PID输出的是在当前开度基础上的变化量比如在当前开度上再加百分之二。位置式的缺点是容易出现积分饱和也就是长时间偏差大时积分项不断累积导致输出打到上限误差消掉后还要很久才能退回来。增量式因为输出的是增量天然不会积分饱和但需要外部累加逻辑来记录当前实际输出值。PID_Compact内部用的是什么形式看西门子的资料和反推它的行为它实现的是带抗积分饱和的位置式PID变体内部对积分项做了限幅和动态调整所以不需要我额外处理积分饱和的问题。2. 硬件配置与接线实操2.1 硬件清单和信号类型选择我的CPU选的是1214C DC/DC/DC订货号6ES7 214-1AG40-0XB0。这个CPU自带14路数字量输入、10路数字量输出和2路模拟量输入温度信号我额外加了一块SM1231 AI 4xRTD模块用来接PT100热电阻。可控硅调功器的控制信号是4到20mA电流所以还需要一路模拟量输出于是又加了一块SM1232 AQ 2xAO模块。这里要特别提醒温度信号采样的硬件选型决定了后面PID控制的天花板。PT100用三线制接法接SM1231西门子这个模块支持两线制和四线制三线制需要把三根线分别接到对应通道的I、I-和COM上。实际接线时我花了点时间整理屏蔽线和接地因为现场有一台变频器在附近运行如果屏蔽层接地处理不好温度信号上会叠加高频干扰PID运算出来的结果就会抖得厉害输出电流也跟着来回摆。模拟量输出到可控硅调功器信号线用屏蔽双绞线屏蔽层单端接地。可控硅调功器的输入阻抗一般是250欧姆4到20mA信号对应0到100%功率。我在程序里把PID_Compact的输出上限设为100.0下限设为0.0输出值直接作为模拟量输出的工程量百分比。2.2 硬件接线中的几个坑第一个坑是PT100传感器的接线。SM1231模块的通道端子是分A、B、C三个接线位的三线制PT100的红色线电源线接I另一根红色同一根PT100三线制实际上就是热电阻两端各引出两根线其中一端有两根线会并联成一个公共端接COM白色线对应另一端的信号线接I-。这里如果不仔细看模块端子图很容易把三根线顺序接错导致温度读数偏差或者干脆报错。第二个坑是模拟量输出模块的供电。SM1232需要外部供电才能输出4到20mA信号吗其实它由背板总线供电但输出回路的负载电阻大小会影响精度。我用的调功器输入阻抗约250欧姆属于模块的推荐负载范围。如果遇到输入阻抗更大的执行器比如500欧姆以上就需要确认模块是否还能满足精度要求不然输出电流会偏低。第三个坑是接地和布线。这种模拟量信号最怕和动力线走同一个线槽。我第一次调试时温度值一直在正负0.5度左右波动后来把所有模拟量信号线单独走了一个弱电线槽离动力线至少保持30厘米以上波动明显小了很多。3. TIA Portal中PID_Compact的组态与参数设置3.1 添加PID_Compact指令打开TIA Portal V16在OB1里可以从“指令”选项卡的“PID控制”下找到PID_Compact V2.2版本的指令。拖拽到程序段中时系统会提示为PID_Compact分配一个背景数据块我给它命名为“DB_PID_WaterHeater”。PID_Compact指令的背景数据块里包含了一堆参数包括Setpoint设定值、Input过程值、Output输出值、ManualEnable手动模式使能、ManualValue手动输出值、Retain参数等。实际编写程序时我是在OB30循环中断里调用PID_Compact的这样时间基准稳定PID运算周期可控。如果放在OB1里调用由于OB1的扫描周期会随着程序量变化PID的采样时间就不固定控制效果会变差。把PID_Compact放在OB30里调用中断时间设为200毫秒这样每一轮PID运算间隔都是恒定的200毫秒。3.2 设定值、过程值、输出值的量纲处理PID_Compact的输入输出都是实数且范围默认是0到100代表百分比。对于温度控制我做了这样的映射PT100通过SM1231读到的原始温度值比如45.6我直接在程序里用SCALE_X指令或者直接做标准化把0到100摄氏度映射到0到100的PID量程。这里有个关键点如果将Input直接连接到温度值比如45.6度而PID_Compact内部认为最大值就是100那45.6在内部计算时会被当成45.6%来处理控制逻辑会错乱。所以必须明确量程。我在输入侧这样处理DB_PID_WaterHeater.Input : INT_TO_REAL(测温模块通道.温度原始值) / 100.0 * 100.0;其实更规范的做法是给PID_Compact组态一个InputScaler。在PID_Compact的属性中有一个“输入缩放”选项可以定义InputPerOn输入上限工程值、InputPerOff输入下限工程值。我把InputPerOn设为100InputPerOff设为0Input直接连实际温度值45.6PID_Compact内部就知道45.6对应于45.6%的量程。输出侧也类似。Output默认是0到100可以直接接到模拟量输出的格式化指令上。SM1232模块在TIA中组态成4到20mA信号程序里将0到100的实数输出线性映射为0到27648的整数然后送到模拟量输出地址。这一步要用NORM_X和SCALE_X指令完成。3.3 PID参数组态界面详解PID_Compact组态界面分几个Tab基本设置、参数、输出限制、高级设置。我习惯先在“基本设置”里选择控制类型为“温度”因为温度对象一般是一阶惯性加纯滞后PID_Compact会根据控制类型给出默认的算法结构。“参数”选项卡里能看到自动模式和手动模式两套PID参数。自动模式下可以填PID增益、积分时间、微分时间也可以勾选“微分激活”。温度控制我一般不建议开太大的微分作用因为温度信号本身噪声不大但微分对高频噪声敏感。S7-1200 PID_Compact里微分项是作用于过程值的也就是只对测量值变化率做响应不作用于设定值变化这样可以避免设定值改变瞬间输出发生冲击。“输出限制”选项卡里可以设定输出上限、下限以及输出变化率限制。对于可控硅调功器变化率限制比较重要。如果允许输出从0%直接跳到100%可能让加热管和供电线路承受较大的冲击电流甚至会因为水温惯性造成超调。我这里设了最大变化率为每秒钟10%相当于输出从0到100需要10秒加热功率是斜坡上升的实际运行效果不错。3.4 PID_Compact的自整定功能S7-1200 PID_Compact自带自整定里面有两个模式“启动阶段整定”和“运行阶段整定”。自整定按钮在在线模式下监控PID_Compact的背景数据块时可以看到“Start Self-tuning”的触发位。自整定的原理是PID_Compact会先强制输出一个阶跃信号从当前值突然增加或者减少一定幅度的输出观察过程值温度的响应曲线然后基于响应曲线上的一阶惯性加纯滞后模型来推算PID参数。这个方法本质上是基于反应曲线法和Ziegler-Nichols经验公式的工程实现。在实际项目的自整定过程里我先把设定值设到了45度此时水温从常温开始加热PID_Compact先以开环方式让温度爬升到接近设定值然后自动开始阶跃扰动测试。整定过程大概持续了5分钟期间输出有一个明显的小幅阶跃变化。整定完成后背景数据块里的PID参数被自动更新。自整定得到的结果能否直接用我的经验是自整定参数可以作为很好的初始值但要根据实际运行效果再微调。比如自整定给的积分时间可能偏短系统会有点振荡。我这次自整定后得到的增益约8.5积分时间约120秒微分时间被自动设为0。实际运行时水温在设定值附近有大约正负0.8度的波动我手动把增益降到6.0积分时间提高到150秒波动收窄到正负0.3度以内。4. 手动整定PID参数的完整流程4.1 工程上的整定顺序有人会问能不能不自整定直接手动调完全可以而且了解了手动整定的思路才能更好地理解自整定给你的参数意味着什么。我整理了一套适合温度对象的整定流程。第一步先把积分和微分全部关掉只保留比例项。也就是说积分时间设成很大相当于不积分微分时间设成0。然后给一个设定值观察温度变化。举个例子如果设定值是50度刚开始加热时温度慢慢爬升接近设定值时由于纯比例控制存在稳态误差最后温度可能停在47度就上不去了。这时把增益逐步加大比如从2.0加到4.0再到6.0观察哪个增益下温度在设定值附近开始出现周期性小振荡。临界振荡的增益记为临界增益Ku。第二步在纯比例临界振荡的基础上测量振荡周期Tu。然后在工程上通常用Ziegler-Nichols参数表来整定比如控制规律比例增益Kp积分时间Ti微分时间TdP0.5Ku——PI0.45Ku0.85Tu—PID0.6Ku0.5Tu0.125Tu我这次用的是PID_Compact本身对温度对象的处理方式未开微分所以可以按PI规律来参考。实测得到Ku约为12.0Tu约为50秒那么参考值就是Kp约5.4Ti约42.5秒。但这是临界比例法给出的保守参数实际加上分别调整后我用Kp6.0、Ti150秒效果反而更好原因在于温度对象滞后较大过短的积分时间会加剧振荡。第三步就是微调。增益偏大会产生超调增益偏小会有稳态误差积分时间偏大是调节太慢偏小是产生低频振荡。我调完参数后做的第一个测试是设定值从45度阶跃到50度观察实际温度曲线的超调量。最终调出来超调量在1度以内调节时间约3分钟达到了客户的期望。4.2 PID参数整定中的关键观察指标调试时不能只盯着温度最终稳不稳要同时看两个信号温度过程值和PID输出值。在TIA Portal的监控表里我同时加了“DB_PID_WaterHeater”.Input和“DB_PID_WaterHeater”.Output用趋势视图观察。如果温度在设定值附近持续小幅振荡幅度大约正负0.5度且输出也在周期性波动说明增益偏大或者积分时间偏短。如果温度偏离设定值后长时间回不来比如进水流量突然增大导致温度跌了2度过了5分钟还没回到设定值附近说明积分作用太弱或者增益太小。还有一个非常有用的观察点——输出变化率的合理性。温度控制的电动调节是慢工出细活如果输出值像锯齿一样频繁大幅变动说明参数过于激进对执行机构和供电线路都是不利的。另外我建议在PID_Compact的输出侧加一个低通滤波或者SM1232模块本身的平滑处理来稳定输出吗对于可控硅调功器其实可以用这种方式减小输出的频繁跳变。但要注意PID_Compact的输出已经经过其内部的输出值平滑处理采样周期固定为200毫秒只要参数不是太激进输出不会太跳。5. 程序逻辑与辅助功能实现5.1 手动模式和自动模式的无扰切换PID_Compact自带手动/自动切换功能通过ManualEnable输入指定。ManualEnable为FALSE时是自动模式为TRUE时是手动模式。手动模式下输出值直接由ManualValue决定PID算法仍然在后台计算保证切换回自动模式时输出不会突变这就是无扰切换。我在工程上做了两个辅助逻辑一是当系统刚上电、温度还没建立起来的时候强制切到手动模式输出一个较小值比如20%进行预热避免PID在温度很低时因为偏差过大导致输出直接冲到100%。二是当温度超过安全上限比如80度时无论当前模式是什么都直接切断加热输出这个逻辑放在PID_Compact输出的后面作为硬性保护。这个安全上限的逻辑很重要尤其是PID处于自动模式时如果温度传感器出现故障比如断线过程值会突然变成负值或者不正常的数值PID会误以为温度偏低而全功率加热非常危险。所以程序里我加了传感器断线检测功能一旦SM1231反馈的通道状态位为故障立即将输出切为零并在人机界面上报警。5.2 设定值斜坡功能另一个实用的功能是设定值斜坡。PID_Compact支持设定值斜坡发生器Setpoint Ramp可以在组态里启用。这个功能的作用是让设定值不是阶跃变化而是按指定的速率缓慢变化到目标值。比如设定值从45度改到55度如果不加斜坡PID会立刻感受到10度的偏差增益又大输出瞬间打满温度超调会很大。加上斜坡后设定值以每分钟1度的速率爬升整个升温过程平稳很多。我在组态里把斜坡上升速率设为每分钟2度下降速率同样每分钟2度。这样做在换班或调整目标温度时非常好用避免了每次都把水温冲过头再降下来浪费能量。5.3 模拟量输入输出处理的标准程序片段下面是我在OB30里调用PID_Compact时的核心程序片段供参考// OB30中200ms循环中断 // 模拟量输入 - 温度值标准化SM1231的CH0整型4-20mA对应PT100量程 温度原始值 : SM1231_CH0.AI_RAW; // 0~27648 温度工程值 : INT_TO_REAL(温度原始值) * 100.0 / 27648.0; // 0~100度映射 // 手动/自动切换 DB_PID_WaterHeater.ManualEnable : HMI手动模式; DB_PID_WaterHeater.ManualValue : HMI手动输出百分比; // 调用PID_Compact DB_PID_WaterHeater( Setpoint : 目标温度, Input : 温度工程值, Output PID输出百分比 ); // 输出限幅处理在PID内部已完成这里做安全保护 IF 温度工程值 80.0 OR 传感器故障信号 THEN 加热输出指令百分比 : 0.0; ELSE 加热输出指令百分比 : PID输出百分比; END_IF; // 输出标准化至模拟量模块SM12320~27648对应4~20mA 输出原始值 : REAL_TO_INT(加热输出指令百分比 * 27648.0 / 100.0); SM1232_CH0.AQ_RAW : 输出原始值;注意一个细节PID_Compact的Input我连接的是温度工程值量程是0到100度。如果现场最高温度超过100度比如热水器可能到120度那InputPerOn要相应改成120否则PID内部计算会错误地认为过程值超量程。6. 调试过程中遇到的典型问题与排查方法6.1 温度振荡不停PID输出也在大幅波动这个问题在实际调试中最常见。我遇到过一次温度在设定值附近正负1.5度持续振荡输出电流也从4mA到20mA来回猛拉。排查步骤是这样的第一步检查传感器信号是否正常。用万用表在SM1231的端子上测PT100的电阻值换算成温度后和程序里的读数对比。如果没有偏差说明传感器和模块没问题。第二步检查PID的采样周期是否设置正确。如果OB30的中断周期设成了200ms而PID_Compact内部又从组态里读到了一个不同的采样时间会导致控制节拍错乱。这个可以通过在趋势视图里看Output是每200ms更新一次还是不定期跳变来判断。第三步是回头去看参数。振荡多半是因为增益太大或者积分时间太短。我的做法是把PID参数先切到手动模式输出一个固定值比如50%等温度稳定后再切回自动模式观察切换瞬间的输出变化。如果自动模式一开始输出就有大幅阶跃说明增益设置过于敏感。6.2 设定值附近始终有残余偏差这种情况和前面的振荡相反温度可能稳定在设定值以下0.8度就再也不动了。纯比例控制有静差是正常的但PID_Compact默认是有积分项的所以不会出现比例控制那种静差。如果还有偏差先检查积分时间是否设太大比如设到3000秒以上积分作用几乎不存在。如果积分时间合理还要检查PID_Compact是否处于手动模式或者积分项是否被保持功能冻结了。另外PID_Compact的背景数据块里有一个参数叫“ResetIntegral”当它被触发时会清零积分。如果程序里不小心把这个位置为TRUE积分永远累积不起来同样会有静差。我犯过这个错排查了很久才注意到是有人误触发了这个保持位。6.3 输出不够大温度怎么都提不上去这通常是量程映射的问题。我遇到过一次PID输出已经打到100%但加热棒就是不工作。查了一圈发现是SM1232的输出接线接反了4到20mA的负极没有接对。还有一种情况是PID_Compact的输出上限被设成了50%导致无论怎么调增益输出都最多只有50%。从现象上区分这两种原因的办法是在监控表里强制给SM1232通道发一个20mA对应的值27648如果加热棒能全功率工作说明执行机构和输出通道没问题问题在PID组态如果强制输出也不动作那就要回头查硬件接线和模块配置。6.4 常见问题速查表现象可能原因快速排查方法温度高频小幅波动信号受到干扰或微分作用过强检查屏蔽接地关闭微分温度长时间缓慢波动积分时间过短增大积分时间温度稳定但有静差积分项异常或ManualEnable误置真检查ResetIntegral和ManualEnable输出经常打到上限输出限制设置不合理或增益过小检查输出上限和PID参数PID参数自整定失败工艺过程中存在强干扰或系统不稳定先手动稳定工况再自整定传感器断线导致全功率加热缺少断线检测保护添加通道状态判断和输出安全逻辑6.5 自整定的使用建议自整定不是万灵丹它对工况稳定性的要求比较高。如果整定过程中进水流量波动频繁或者恒温罐的负载时大时小自整定给出的参数可能不靠谱。我建议在夜间或者产线停机的时候做自整定尽量让对象处于一个相对稳定的条件下。而且自整定完成后要观察一段时间至少一个完整的升温-保温周期。有些参数在设定值附近看还行但在升温过程中可能出现超调。我自己习惯用“自整定参数打底加经验微调”的组合策略这样既走捷径又保留了对工况的掌控感。7. 实际运行效果项目交付后已经运行了将近两个月水温控制稳定在设定值正负0.3度左右。客户的进水流量大约每小时200升温度设定在45到55度之间可调从25度进水加热到设定温度大约需要10到15分钟。能耗方面PID控制明显比之前他们用的通断式温控器节省电能因为加热功率是连续调节的不像通断式那样频繁地满负荷启停。有人问过我为啥不直接买一台市售温控器非要费劲在PLC里做PID其实除了前面说的硬件复用考虑还有一个重要原因是客户想把温度曲线记录下来做生产追溯。PLC方案天然能和HMI、上位机通信实时记录温度趋势和加热功率曲线这是传统温控器做不到的。这个项目做完之后我的体会是S7-1200的PID_Compact指令其实已经把很多底层细节封装好了但真正决定控制效果的不是指令本身而是对过程对象的理解和对参数整定逻辑的把握。你如果能说清楚你的对象是快是慢、是纯滞后还是一阶惯性再去看PID参数该往哪个方向调心里就有底了。最后分享一个小技巧——调试结束后别忘了把PID参数备份一份到存储卡里免得以后程序被误删或者CPU更换时重新调参。