1. 为什么非要拿S7-1200给热水器做恒温控制
1.1 传统开关控制的问题,远比你想象的严重
先去现场看过一遍就明白了。很多热水器温度控制用的是最原始的办法:温度到了阈值就断电,低于阈值就通电。这种开关量控制放在加热功率小、用水量稳定的场合,勉强能用,但一遇到加热功率偏大或者进水温度波动,温度曲线就完全失控。波动范围动不动就有正负3度到5度,用户把设定温度调在45度,实际出水可能先是48度烫一下,过一会儿又变成42度的温水澡。
你会说,热水器嘛,差个两三度有什么关系?对生活热水,你可能觉得能忍。但同样的逻辑放在化工恒温反应釜、清洗线槽液恒温、实验室恒温水浴这些场景里,两三度可能就导致产品报废。即便回到家用或者商用热水器上,水温忽冷忽热也是投诉重灾区。所以做恒温热水器,本质要解决的是一件事:让温度稳定在设定值附近,波动小、响应快、不超调。
1.2 S7-1200做恒温控制的底气在哪
S7-1200不是功能最豪华的PLC,但在中小型温度控制场景里,它有一个特别合适的点:CPU里直接集成了PID功能块,不需要另外买温控仪表,也不需要自己做复杂的算法。程序里调用一个PID_Compact,把温度变送器的测量值读进来,把控制输出写到加热执行机构上,闭环控制就跑起来了。
你可能要问:用温控仪不更简单吗?是的,如果只控一个点,温控仪确实更省钱。但恒温热水器往往不是孤立设备,它可能连了上位机、连了触摸屏、带了报警输出,还要跟整个产线联动。用S7-1200的好处是PID控制和逻辑控制在同一套系统里,设定温度、实际温度、输出百分比都走同一个通讯网络,不需要再从温控仪上单独拉485线去读数据。后期想加什么联锁、报警、报表,改程序就行了,不用再去拆仪表。
1.3 PID_Compact和PID_3Step,别选错
S7-1200的PID库里有PID_Compact和PID_3Step两个主要块。PID_Compact适用于连续控制对象,比如加热功率连续可调,或者用PWM方式控制加热管通断;PID_3Step则适用于带积分作用的执行机构,比如电动调节阀、步进电机阀门这类需要正反转控制的场合。
热水器项目里,如果加热管用可控硅调压模块或者固态继电器控制,那用PID_Compact就对了。如果是用电动三通阀调节冷热水混合比例,那才需要考虑PID_3Step。我见过有人拿着PID_3Step去控加热管,结果输出从来到不了稳定状态,因为PID_3Step的输出是带位置的,需要把输出值映射成阀门正反转的时间,不是直接给0到100的功率百分比。选错块,后面调参全是坑。用PID_Compact做恒温热水器,是最贴合的控制架构。
2. 硬件组态之前,先想清楚传感器和执行机构怎么接
2.1 温度传感器怎么进S7-1200
恒温热水器项目里,最常见的温度检测方案有两种:一种是PT100热电阻,直接接在带热电阻输入通道的模拟量模块上;另一种是温度变送器,把热电阻或热电偶信号转换成标准的4-20mA电流信号,再接到S7-1200的模拟量输入通道。
对于S7-1200,如果CPU本体不带模拟量输入,可能需要加一个SM1231模拟量输入模块,或者使用信号板。要注意的是,S7-1200有些型号本体带了两个模拟量输入通道,但输入信号是0-10V,接4-20mA传感器的时候需要并接一个250欧姆精密电阻,把电流信号转成1-5V电压,然后在组态里对应设置量程。这么做虽然能用,但精度受电阻温漂影响,有条件还是直接上信号板或者模块的电流通道更稳妥。
我给热水器做恒温控制,更习惯用4-20mA的温度变送器,测温范围0-100度对应4-20mA。原因很简单:电流信号抗干扰能力强,传输距离远,现场走线不容易出问题。而且PID_Compact的输入端可以直接做工程量换算,把电流对应的温度值标定好,调试的时候看实际温度一目了然。
2.2 加热功率输出:模拟量调压还是PWM通断
热水器的加热执行机构,常见的是这几种:
- 交流接触器直接控制加热管通断,只通或者只断,加热功率只有0和100%两个状态;
- 固态继电器SSR,可以用PWM方式控制,在一个固定周期内调整导通比例,实现0到100%功率可调;
- 可控硅调压模块,接收4-20mA模拟量信号,连续调节加热功率。
交流接触器这种方案,如果直接用PID输出,PID输出50%接触器就疯狂通断,机械寿命和电磁干扰都会出问题,必须配合时间比例控制,让PID的输出值转换成一段时间内的通断占空比。S7-1200的PID_Compact里自带PWM输出模式,可以设置一个PWM周期,比如3秒或者5秒,PID算出要输出60%功率,那就导通1.8秒、断开1.2秒,周而复始。这样接触器或固态继电器的动作频率就降下来了。
如果用可控硅调压模块,PID输出直接走模拟量信号,控制连续性好,加热电压从0到220V连续变化,温度曲线也最平滑。缺点是成本比固态继电器高一些,而且需要对模拟量输出模块。
我的习惯是:小的热水器设备,功率在3kW以内,用固态继电器加PWM方案;功率大的,比如9kW到15kW的三相加热,用可控硅调压模块,模拟量控制。PWM方案便宜,可控硅方案控制品质更高。从PID调参的角度来说,模拟量连续控制会舒服很多,因为PWM方式相当于在控制回路里增加了一个周期性的扰动源,输出小幅变动时,实际加热功率的波动会被周期量化,温度曲线会有微小的锯齿状波动,PID参数如果调得太激进,这种锯齿会被放大。
2.3 采样周期和执行机构周期怎么搭配
这是很多人忽视的一个点。S7-1200的PID_Compact在OB1里调用,每次扫描都执行,但内部有一个采样周期的概念。PID运算不是每次扫描都重新算一次,而是按设定的采样周期执行。热水器温度对象惯性特别大,采样周期不需要太短,0.5秒到2秒都是合理范围。
关键在于,采样周期要跟PWM周期匹配好。比如PWM周期设了5秒,PID采样周期就不能小于这个值,否则PID在同一个PWM周期内多次计算,输出值来回跳,实际上加热管并没有那么多状态可以切换。我通常把PWM周期设在3到8秒之间,采样周期在100毫秒到1秒之间,两者相差5到10倍以上,这样控制动作既平滑又有余量。
温度控制的滞后问题,很多人不理解为什么会振荡:热水器加热后,热量传递到温度传感器位置需要时间,传感器读到的温度变化滞后于实际加热功率变化。滞后越大,系统越容易振荡。减少滞后的办法,一个是把传感器装在循环管路靠近出水口的位置,另一个是加热内胆里加循环泵,让水温均匀。但传感器位置也不能离加热管太近,否则局部温度高,整箱水温没到设定值,PID就以为到了。
3. 在TIA Portal里把PID_Compact跑起来
3.1 调用位置和背景数据块的处理
在TIA Portal里新建项目,添加S7-1200 CPU之后,PID_Compact的使用方式要注意一个关键细节:PID_Compact是一个FB功能块,调用的时候必须指定背景数据块。很多人第一次用,直接在OB1里拖一个PID_Compact,系统问你要不要生成背景DB,选是,然后发现程序里多了一个DB。
实际项目里,我建议把PID_Compact调用放到一个循环中断组织块OB中,而不是OB1。这样做的原因是为了保证PID计算的周期确定性。温度控制虽然不要求微秒级精度,但如果放在OB1里,PID每次调用的时间间隔会随着OB1里其他程序长短变化而变化,PID计算周期不固定,整定好的参数在不同负载条件下会有偏差。放到循环中断OB里,比如设置循环时间为100ms,那么PID_Compact会严格按照100ms的周期被调用,后面在PID块里配置的采样时间也更容易对上。
背景DB可以直接用PID_Compact生成的实例DB,也可以自己建一个全局DB然后在调用时指定。我的做法是让系统自动生成实例DB,然后在HMI上通过DB里的变量监控设定值和实际值。需要注意的是,实例DB里的参数很多,不要试图手动改里面的值,尤其那些带内部状态的变量,改错一个就可能让PID块运行异常。所有调试操作都在PID_Compact的面板里做,或者在HMI上直接连设定值和输出值相关的接口变量。
3.2 PID_Compact的配置界面,到底哪些参数要动
PID_Compact的组态界面分几个区域:基本设置、输入、输出、PID参数。
基本设置里有Manual/Automatic模式切换,有控制器的采样时间。采样时间默认是1秒,热水器项目可以根据实际设定。我一般设为0.5秒到1秒,取整数值方便观察。
输入区需要配置过程值的来源和量程。来源可以选模拟量输入通道,也可以选内部变量。量程就是你传感器对应的工程量范围,比如0到100,单位是摄氏度。这里有个容易忽略的点:如果模拟量输入模块的诊断报错或者超量程,PID_Compact会进入错误状态,输出被钳制在安全值。所以输入区旁边有一项“Process value limits”,默认是跟量程一致,一旦超限会触发报警。做热水器的时候我建议把上限稍微放宽一点,比如量程0到100,上限设到110,避免传感器干扰尖峰导致系统误动。
输出区要选输出类型。如果选模拟量输出,会要求指定输出值的上下限,默认0到100,代表0%到100%功率。如果选PWM输出,需要设置PWM周期,还要指定输出继电器的逻辑,是加热时输出为True还是False。有些设备的常闭触点逻辑跟常开相反,选反了会导致PID输出越大温度反而越低,调试时会莫名奇妙。
PID参数区就是三个数值:增益、积分时间、微分时间。很多人上来就手动填,不看对象特性。实际项目里,我强烈建议先让PID_Compact做一次自动整定,用自动整定出来的值做基础,再手动微调。手动从零开始填P、I、D参数不是不行,但对于大惯性温度对象,效率太低。
3.3 自动整定的过程和坑
自动整定在PID_Compact的在线面板里有一个“启动自整定”按钮。点击之后,PID_Compact会暂时接管输出,一般先输出一个强制功率,让温度产生一个阶跃变化,然后观察温度上升曲线,通过上升曲率、滞后时间等特征,内部拟合出对象的一阶惯性模型,再按模型计算出PID参数。
这里有几个关键前提:第一,系统必须在闭环状态下,反馈信号正常;第二,整定过程中不能让系统进入保护停机或者联锁动作;第三,强制输出阶段温度可能会超过设定值,如果设备不能承受超温,需要做好安全防护。
我在一次热水器调试中,自动整定失败了三次才找出原因。前两次整定输出一直达不到预设的功率,是因为我在程序里写了别的联锁,强制让PID输出为0了。当时PID_Compact整定命令下发以后,系统检测到对象没有响应,直接报错中止。第三次我关掉了联锁,结果又因为温度变送器的响应太慢,整定出来的参数阻尼过大,温度爬得非常慢。后来把传感器换成铠装式的,热响应速度上来了,整定一次就成功。
自动整定成功之后,PID_Compact会把参数写入背景DB,同时给出一些整定质量评估。但要记住,自动整定得到的参数是基于某一特定工况的,比如水量、初始温度。如果运行工况变化大,同一个参数可能表现不佳,这时就得考虑手动微调或者分段参数。对恒温热水器来说,如果水温设定范围很宽,从35度到75度都要用,温度对象在低温段和高温段的热损耗差异很大,一套参数覆盖全范围可能有困难,后面单独讲这个问题。
4. 调参手法和现场调试里那些绕不开的问题
4.1 手动微调P、I、D各参数的手感
自动整定给了基础参数之后,手动微调是躲不掉的。我的调试顺序是:先调比例增益,再调积分时间,最后才碰微分时间。
比例增益决定输出对偏差的响应强度。增益太小,温度到达设定值附近时,输出功率已经收得很小,温度会在设定值下方慢慢爬,半天稳不下来,出现持续的稳态误差。增益太大,温度还没到设定值,输出已经剧烈摆动,表现出来就是温度在设定值上下来回窜,甚至会引发振荡。
积分的作用是消除稳态误差。温度偏离设定值时,积分项会持续累积偏差,推动输出向消除误差的方向走。积分时间越小,积分作用越强,但过强的积分会导致超调——温度越过设定值之后,积分已经被喂了很多,要花很长时间才能“消化”掉,表现出来就是过冲后久久回不来。积分时间太大,积分作用太弱,稳态误差消除得很慢。我一般调积分时间时偷个懒:先把比例调到系统开始有微小振荡,然后把增益降到临界值的60%到70%,积分时间设成这个值的3到5倍,作为初始参数,再观察曲线微调。
微分项对温度控制的作用,要辩证看。微分能提前感知温度变化的趋势,对抑制超调有帮助,但温度信号本身带有噪声,传感器稍微有一点抖动,微分项就会被放大,导致输出高频抖动。所以我经常把微分时间设成0,仅用PI控制。对热水器这种大惯性对象,PI控制配合正确的PWM周期,已经完全能实现稳定恒温。微分只有在对象滞后特别大、PI怎么调都有明显超调时才用,而且采样信号必须加滤波。
4.2 温度上不去、超调、振荡,排查逻辑是什么
现场调试恒温热水器,最常见的三个症状是温度上不去、超调过大、持续振荡。各自的排查方向完全不同。
温度上不去,先别急着加P增益。先检查PID输出值是多少,是不是已经顶到100%了。如果是,说明系统热量需求大于加热功率,可能是初始水温太低、水量太大,或者保温效果差。这个时候调参数毫无意义,得先解决硬件能力问题。如果PID输出只有50%但温度还是上不去,那就要怀疑传感器位置是不是离加热管太远,导致读取的温度比实际水温低,或者执行机构没有真实输出。
超调过大,一定是PID参数太激进,或者系统滞后过大。当温度快接近设定值时,加热功率还保持在很高水平,热量“冲过去”了。遇到这种情况,我会降低增益,适当增加微分(如果信号质量好的话),同时把输出上升的速度限制一下。PID_Compact里可以设置输出值变化率,让输出不能一蹴而就跳到最大值。这个限幅对温度控制特别有用:允许输出以每秒百分之几的速度变化,相当于给加热功率加了惯性,超调自然就被削平了。记得我调过一台热水器,增益从15降到5,再把输出变化率限制在每秒5%,超调直接从8度降到1度以内。
持续振荡,往往不是参数问题,而是系统结构问题。最常见的原因是滞后时间与采样周期不匹配。温度变化从加热位置传到传感器要10秒,PID采样周期却设了0.2秒,控制器频繁判断温度没变化,积分不断累积,等到温度开始变化时,输出已经冲过头了,于是产生周期性振荡。这种时候把采样时间适当放大,或者减少PID的计算频率,让每一次控制动作都能在传感器上看到响应,反而更容易稳定。所以调参遇到振荡,不要只盯着P、I、D数值,回看一下时间参数是否匹配对象的物理特性。
4.3 恒温热水器分段控制的实用思路
之前提到,一套PID参数难以覆盖很宽的设定温度范围,这在热水器项目里确实常见。低温段比如40度,水箱温度和环境温差小,散热量小,系统惯性相对大;高温段比如75度,温差大,散热量大,需要更大的稳态输出功率。同一个增益值,在低温段可能让温度平滑靠近设定点,在高温段却显得拖沓。
解决思路有两种。一种是在程序里做参数分段:根据当前设定温度或当前实际温度,切换PID_Compact的增益、积分时间。S7-1200的PID_Compact支持在线修改参数,用赋值指令直接写P、I、D对应的DB变量,不必停CPU。水温在40到50度用一套参数,50到65度用一套,65度以上用另一套,每套参数在对应工况下做一次自动整定,然后运行中根据温度区间自动切换。
另一种思路是只做一套保守的参数,牺牲一点高温段的响应速度,换取全范围不振荡。如果用户对恒温精度要求不是特别苛刻,么偏移零点几度,这种做法最简单可靠。但如果用户要求温度波动在正负0.5度以内,尤其是高温用水场景,那还是老老实实做分段参数,别偷懒。
我自己的项目里,最终用了一个简化的折中方案:把PID_Compact的增益设为自动整定结果的80%,积分时间保持自动整定值不变,另外在程序里加了一个温度前馈。前馈的逻辑是这样的:根据目标温度和当前温度的差值,估算一个稳态加热功率的偏移量,把这个偏移量加在PID输出上。升温阶段,前馈直接给出一个比较大的功率基础,PID只需要在基础值上进行微调,大幅缩短了升温时间;接近设定值时,前馈功率自动减小,PID负责精确修正。这个做法本质上是不修改PID参数,而是优化控制策略,效果非常明显。
4.4 防超温和防干烧的逻辑,和PID一起做
恒温热水器用PID控制,不代表可以去掉安全逻辑。PID的职责是控制温度,安全联锁必须独立于PID架构,用单独的硬件或软件逻辑实现。
我在程序里会放一个超温和干烧保护:温度超过上限比如85度,不管PID输出多大,直接切断加热输出;液位低或者循环泵故障,也直接断开加热。这个联锁变量放在PID输出回路的外面,可以是一条简单的开关逻辑:PID输出乘以联锁允许位,得到最终输出。联锁动作时PID模块本身还在运行,不会因为输出被切断而进入错误状态,等故障恢复后,PID从当前状态继续调节,不会产生突兀的跳变。
这个细节很重要。如果直接修改PID_Compact的输出变量,相当于强制把它输出的值改为0,PID内部会以为温度下来了,积分项会急剧累积,当联锁解除后,输出会被突然拉高,造成一次很大的温度过冲。我在自己的项目里把联锁放在赋值环节,而不是直接操作PID内部接口,逻辑上更干净。做完这一步,热水器的恒温系统才算真正完整——既有PID的精细调节,又有独立的安全兜底。
那次调完整套系统之后,我记录了连续运行八小时的曲线:设定温度60度,实际温度波动始终在正负0.4度以内。升温阶段比原来的开关控制快了差不多一半,首次达到设定值时的超调控制在0.8度以内。后来我把这套思路复用到另外两个项目上,一台是小型清洗线槽液加热,一台是恒温反应罐,都是S7-1200加PID_Compact,区别只在传感器量程和加热功率参数上。核心逻辑没有变,效果也都是一遍过。