ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

基于S7-200 SMART PLC的医药洁净室AHU串级PID温湿度控制方案

基于S7-200 SMART PLC的医药洁净室AHU串级PID温湿度控制方案

去年年初,我接手了一套医药洁净室空调箱(AHU)的改造项目。设备本身不算复杂,但控制要求却相当苛刻——温度要稳定在22±2℃、相对湿度要稳定在45%±10%的区间内,而且是全年各种室外工况下都要保证。医药洁净室对温湿度波动的容忍度极低,任何一点波动都可能影响药品生产和检验结果。为了让这套系统达到预期的控制精度,我全程用西门子S7-200 SMART PLC来做程序设计,在温湿度的核心调节回路上采用了串级PID控制,并把模拟量采集、PID参数、手自动状态这些数据统一封装成结构体变量来管理。这套程序从编译、仿真到现场调试,前前后后花了大半年时间,中间踩了不少坑,也沉淀了一些实际可用的思路。最近陆续有做暖通和自控的同行问起这个项目,所以我把整个设计过程、程序结构和调试经验梳理成文,希望能给准备做医药洁净室空调控制的工程师一些参考。

1. 项目背景与整体设计思路

1.1 医药洁净室空调箱到底在控制什么

很多人一听医药洁净室,第一反应是“不就是空调嘛,温度别太离谱就行”。但实际上医药车间的空调箱和普通办公楼的舒适性空调完全是两码事。药品生产过程中,温湿度直接影响物料性质、微生物滋生、静电效应,甚至某些工序的化学反应速率。药典和生产规范对洁净室的温湿度都有明确限值,通常控制在20~24℃、相对湿度45%~60%,有些特殊车间要求更窄。

这次改造的车间就属于这种情况。原系统已经运行多年,夏天湿度压不住,冬天温度波动大,出现过产品报废的苗头,业主这才决定把控制柜和程序整体升级。我去现场摸底时拿到几个关键信息:车间面积不大,送风采用一台组合式空调箱,包含新风段、初效过滤、表冷段、加热段、蒸汽加湿段、风机段和中效过滤段。送回风方式是上送下回,房间内装了一个温湿度传感器,回风管上还有一个温湿度传感器作为参考。

这个项目真正要控制的,并不是“让空调吹出多少度”,而是要保证整个房间内的温湿度长期稳定。空调箱的传感器虽然有多个,但真正可以直接反映房间状态的是回风温度和回风湿度,所以控制回路的被控变量应该取回风温湿度。送风温度则是执行层面的中间变量,它靠近冷盘管和加热盘管,响应快、滞后小,非常适合作为串级控制里的内回路。

洁净室还需要关注正压差和换气次数,但换气次数由风机频率和风阀决定,温度湿度控制主要落在冷阀、热阀和加湿阀上。这个项目的执行机构包括:冷冻水电动调节阀(模拟量4-20mA控制)、热水加热阀(模拟量4-20mA控制)、蒸汽加湿阀(模拟量4-20mA控制)。阀门的动作逻辑直接决定了整个控制系统的成败,这也是我后来坚持用串级PID的最主要原因。

1.2 硬件选型与系统架构

选PLC时我其实纠结过一段时间。现场原有控制柜里已经有一个西门子S7-200 SMART SR30,业主希望继续用同一系列,方便备件管理。我也评估过升级到S7-1200,但考虑到成本、供货周期以及这台设备的点位规模,S7-200 SMART完全够用,就保留了它作为核心控制器。

硬件配置大概是这样:

  • CPU:S7-200 SMART SR30,自带24路数字量输入、16路数字量输出、1个以太网口
  • 模拟量输入:扩展1块EM AE08,8路4-20mA模拟量输入
  • 模拟量输出:扩展1块EM AQ04,4路4-20mA模拟量输出
  • 触摸屏:配套的昆仑通态或西门子Smart Line,走以太网通讯

点位分配上,模拟量输入主要接回风温度、回风湿度、送风温度、表冷器后温度、室外温湿度、冷水阀开度反馈。模拟量输出是3个阀门加上1路备用。数字量输入接风机运行状态、故障信号、手自动切换旋钮、防冻开关;数字量输出控制风机启停、加湿器启停、报警输出。

为什么这个配置能满足需求?关键在于S7-200 SMART的PID向导支持多路PID回路,而且CPU本体带以太网口,触摸屏和上位机通讯都不需要额外加模块。EM AE08和EM AQ04的通道数刚好匹配现场点位,还留了备用通道给以后扩展。

系统架构上,PLC放在原有控制柜内,触摸屏装在洁净车间外面。传感器信号全部采用4-20mA传输,好处是抗干扰能力强,传输距离远,而且大部分变送器直接支持。温度用带4-20mA输出的温度变送器,湿度用温湿度一体变送器,露点采用表冷器后的温度探头近似计算。

整个控制系统从功能上分成三块:温度控制链、湿度控制链、联锁保护逻辑。温度控制链负责加热阀、冷阀补偿;湿度控制链负责冷阀除湿、蒸汽加湿;联锁保护逻辑负责风机与阀门的启停时序、防冻保护、手自动切换。这三块互相影响,程序里不能各自为政,必须统一调度。

2. 串级PID控制的原理与整定实战

2.1 为什么我要用串级PID而不是单回路

单回路PID在这个项目里能不能用?短期看能用,温度能稳定在±3℃左右,湿度勉强能压住,但遇到夏季暴雨降温、车间门开关、过滤器更换这种扰动时,温湿度会长时间波动,甚至震荡。原因很明显:房间温湿度对象是典型的大惯性、大滞后系统,回风温度到冷阀之间隔着房间容积、盘管热惰性、风管长度,时间常数可能接近两分钟,单回路PID为了稳定不得不把增益和积分调得很小,结果就是反应慢、恢复时间长。

串级PID的思路是把控制通道拆分。拿温度来说,加热阀到送风温度是快回路,送风温度到回风温度是慢回路。我让回风温度的主回路去计算“到底需要多高的送风温度”,再由送风温度的副回路去调节加热阀。这样做的好处是,外界的扰动如果先影响送风温度,副回路会立刻修正,根本不会等到房间温度变化了才动作。冷阀除湿那边同理,湿度主回路输出的是表冷器后温度的目标值,副回路直接稳喂送风温度,让冷阀紧紧咬住这个目标。

还有一个工程上的理由:串级PID方便现场整定。内回路参数整定好了以后,外回路就像一个“慢速纯积分”对象,调试时先把内环保持自动、外环切手动,送风温度基本稳定了再投外环自动。这样做每一步都看得见效果,不容易把回路整得紊乱。

温湿度的串级结构我最终定成:

  • 温度链:回风温度(主) → 送风温度(副) → 加热阀开度
  • 湿度链:回风湿度(主) → 表冷器后温度(副) → 冷冻水阀开度
  • 加湿链:回风湿度(主) → 蒸汽加湿阀开度(单回路PID)

这里要说明一下,冷阀除湿的副被控变量是表冷器后温度,也就是通常说的“机露点温度”。回风湿度一高,主回路就把机露点目标往下压,冷阀开大降温除湿;湿度达到要求后,机露点目标回升,冷阀收小,防止过度除湿导致温度过低。

2.2 PID向导的参数设置与实际整定流程

S7-200 SMART的PID向导确实好用,但很多人忽略了向导里设置的和实际运行时的对应关系。我在这个项目里一边用向导生成PID指令,一边在符号表里做了一套自定义的结构体变量来保存PID参数,现场调试直接改VD地址就能生效。

向导里主要设置这几个内容:

  • 回路设定值范围:温度主回路0~50℃(因为是回风温度换算后的工程值),温度副回路0~50℃,湿度主回路0~100%RH
  • 过程变量输入:选单极性4-20mA,原始值范围用5530~27648
  • 输出类型:模拟量输出,4-20mA,0~27648对应
  • 增益、积分时间、微分时间:先给经验值,现场再整定

串级回路在向导里的实现并不复杂:生成两个独立的PID块,比如温度主回路用PID0,温度副回路用PID1。主回路的输出量是一个0~100.0之间的实数,直接赋值给副回路的设定值寄存器。副回路的PID输出才真正去控制加热阀。

参数整定时我采用“先内环、后外环、再串级”的步骤。整定内环时,把主回路输出固定在一个常数上,相当于手动给定送风温度目标,然后给一个阶跃扰动,观察送风温度变化曲线,调整PID1的增益和积分时间,目标是让送风温度快速无超调地回到设定值。我实测下来,送风温度内环的P通常在3~5之间,I在30~60秒之间,D基本关闭或给很小的值。

外环整定时把PID0切自动,给回风温度设定值一个变化量,观察回风温度响应。由于内环已经把它变成了一个快速跟随的通道,外环可以放心地把增益调小一点,一般在1.0~2.5,积分时间放到150~300秒,这样房间温度变化平缓不超调。

湿度回路的整定要比温度麻烦一些,因为湿度传感器响应滞后比温度大,而且加湿、除湿过程还伴随着热量变化。我把湿度主回路的采样周期从默认的1秒放大到5秒,积分时间放到300秒以上,效果立刻改善。具体表现就是湿度波动幅度从±15%降到±5%以内。

3. 模拟量采集与结构体变量设计

3.1 模拟量标定:从原始值到工程值

S7-200 SMART模拟量输入的原始值不是直接显示成温度或湿度的,它是一个0~27648的数字量。配置成4-20mA输入时,4mA对应5530,20mA对应27648。很多初学的朋友直接用AIW的原始值当工程量去参与PID运算,结果就是程序逻辑看起来没问题,实际控制一团糟,因为量纲完全错了。

换算公式其实很简单:

工程值 =(AIW原始值 - 5530) × (工程量上限 - 工程量下限) ÷ (27648 - 5530) + 工程量下限

举个具体例子,温度变送器量程是-20~60℃,当前AIW读到的原始值是15000,那么实际温度:

(15000 - 5530) × 80 ÷ (27648 - 5530) - 20 ≈ 14.26℃

这个换算在程序里我用浮点指令来算,因为整数运算很容易溢出。S7-200 SMART的V区浮点数是32位,计算精度足够。

不过PID向导生成的PID块本身带有工程量转换功能,只要你把PID向导里的PV传感器上下限设成和变送器量程一致,向导会自动把原始值换算成工程值,并且提供PV_Value输出。我在这个项目里是把所有模拟量的原始值先统一读到V区,做标定换算后存成工程值,再交给PID块使用。这样做的好处是,触摸屏上显示的曲线、报警值、累计数据全部是工程单位,调试时一眼就能看出问题。

标定过程中有一个坑要提一下:4-20mA信号如果出现断线,AIW原始值会低于5530甚至接近0。程序里必须写一个断线检测逻辑,比如原始值小于5530且持续超过一定时间就判定传感器故障,同时把对应的PID回路切到手动,防止阀门前一次的开度被“假数据”带到危险位置。

3.2 用结构体变量组织控制回路数据

S7-200 SMART不像S7-1200那样原生支持UDT结构体类型,但可以通过连续规划V区来实现同样的效果。我在程序里给每一类设备定义了一套“模拟结构体”,把所有需要长期保存和在线修改的参数集中放到连续的V存储区。

以温度控制回路为例,我从VB2000开始规划地址段:

  • VD2000:温度主回路设定值(SP,浮点)
  • VD2004:温度主回路过程值(PV,浮点)
  • VD2008:温度主回路输出(OUT,浮点,0~100%)
  • VD2012:温度主回路比例增益(Kp,浮点)
  • VD2016:温度主回路积分时间(Ti,浮点)
  • VD2020:温度主回路微分时间(Td,浮点)
  • VB2024:手自动切换标志(字节)
  • VD2026:输出上限(浮点)
  • VD2030:输出下限(浮点)

这样在符号表里一一命名后,程序里只需要通过符号名操作,可读性比裸的V区地址好得多。更重要的是,调试时我用触摸屏把这些地址做成参数页面,业主的运维人员可以直接在线修改PID参数和上下限,不用重新下载程序。

湿度控制回路我用另一段连续地址,比如从VB2100开始。这样整个程序里各回路的“结构体”偏移是一致的,读代码时不会串。风机、阀门、手自动状态这些也做成了独立的结构体区域。

结构体变量带来的一个直接好处是回路复制容易。当时现场有两台同型号空调箱,我一台程序调试通过后,把整个结构体的偏移表复制到第二台,只换了I/O地址映射,控制逻辑几乎不用改动。这是靠零散变量写程序做不到的。

有人可能会问,S7-200 SMART的V区本来就只有几十KB,这样规划会不会不够用?实际上每一个模拟量结构体也就几十个字节,所有回路和设备结构体加起来不超过4KB,完全在安全范围内。我更担心的是程序写得乱,而不是V区不够用。

4. 关键控制逻辑与联锁保护

4.1 手自动无扰切换与积分饱和处理

空调箱控制柜上必须有手自动切换功能,这是业主要求,也是安全底线。切换时最怕什么?最怕输出跳变。操作员从自动切手动时,阀位突然从30%蹦到80%,这一下就会引起送风温度大幅波动,严重时直接触发报警停机。

S7-200 SMART的PID向导本身提供了Auto_Manual输入和ManualOutput输入。当Auto_Manual为0时,PID输出被强制等于ManualOutput,这属于基础的手动覆盖。但我在实际项目里做了一套更稳妥的“跟踪切换”逻辑:程序每个扫描周期都把当前的阀门控制量实时写入ManualOutput寄存器。这样操作员切手动时,PID输出和手动给定保持一致,阀门开度不会跳。

从手动切回自动的时候要处理积分饱和。如果手动状态下阀门一直开得很小,实际温度离设定值又很远,PID一旦切入自动,积分项会累计很快,直接把输出推到限幅值,导致阀门猛开,温度过冲。我的解决办法是切换前把积分项清零或者把设定值先“逼近”当前过程值,等系统稳定后再把设定值改回目标值。这个“逼近”动作我用一个子程序实现,每100ms把设定值向实际值靠拢2%,直到误差小于0.5℃再恢复到最终设定值。

串级PID还有另一层积分饱和风险。温度主回路输出的送风设定值,如果超出副回路能够实现的物理范围,比如冬季冷阀想再开大但盘管已经冰水不足,PID仍然会努力往上积分。我在程序里监视主回路输出,一旦超过副回路可接受范围,就停止主回路的积分动作,并给触摸屏弹出一个“冷阀能力不足”的提示。

4.2 除湿、加热与加湿的联动逻辑

温湿度控制最怕两个执行器打架。最常见的情况是夏天除湿时冷阀开大,送风温度降得很低,温度回路为了让房间温度达标又命令加热阀猛开,结果就是一边制冷一边加热,能耗高得离谱,阀门还来回振荡。

我在程序里做了一层“工位协调”逻辑。首先明确各阀门的主责任:

  • 冷冻水阀:夏季除湿的主要手段,由湿度回路控制
  • 加热阀:温度精细调节,由温度回路控制,但要受冷阀开度补偿
  • 蒸汽加湿阀:冬季加湿手段,由湿度回路控制

当湿度回路输出要求冷阀开度超过某个阈值(比如60%)时,程序自动降低温度主回路的输出上限,把送风温度的目标压低一点,而不是让加热阀无限补热。反过来,当温度回路输出接近上限但仍无法满足室温要求时,程序会检查湿度回路是否在正向除湿,如果是,说明冷阀带走了过多热量,此时把湿度主回路的机露点目标上调一小步,减少除湿强度,让温度得以恢复。

这个协调逻辑刚开始我觉得很复杂,后来想明白了一个原则:空调箱的所有执行器,最终都作用于空气的焓值。温度控制管显热,湿度控制管潜热,只要把送风露点温度和送风温度两个中间变量控制好,房间状态自然就稳了。程序里多做几个条件判断,远好过让两个PID在房间里互相打架。

冬季加湿也有联动问题。蒸汽加湿器一启动,大量水蒸气混入空气中,会带走一部分热量,送风温度瞬时下降,温度副回路如果不及时补偿,房间温度会掉下来。我在程序里把加湿器的启停信号和一个前馈补偿量做了关联:加湿器刚开启的3分钟内,加热阀在PID输出基础上额外增加5%的开度,之后逐步减少这个补偿量。实测下来,冬季加湿时送风温度波动从原来的±3℃收窄到±1℃以内。

联锁保护里还有一条很重要的逻辑:风机没有运行时,所有调节阀必须强制关闭并禁止PID自动投用。因为如果风机停着,表冷器仍然通冷水,盘管会被冻裂;加湿器仍然通蒸汽,容易造成局部凝水。程序里我除了用硬件继电器做风机与阀门的互锁之外,还在PLC内加了一道软件锁,只有风机运行反馈信号为1时PID回路才能切到自动。

5. 调试运行中的坑与经验

5.1 湿度振荡事件复盘

这套系统第一次试运行是在春天,室外温度不高,湿度中等。第一次送电后温度控制还算平稳,湿度却出现了明显的锯齿状波动:湿度从45%升到55%,加湿器开始动作,又降到42%,加湿器停止,如此反复。我用趋势图记录了整整一个下午,发现问题出在加湿回路的PID参数太激进。

湿度和温度的对象特性完全不同。温度是热惯性大,湿度在加湿器动作后变化却相对快,而且湿度传感器的安装位置在回风管上,距离加湿段有一定距离,存在明显传输滞后。PID只要增益稍大,就会反复越过目标。我把加湿回路的比例增益从2.0降到0.8,积分时间从120秒拉长到400秒,同时把PID执行周期从1秒改成5秒,再观察,曲线平直了很多。

后来我又发现一个隐患:湿度传感器安装在回风管的末端,探头直接暴露在气流中,冬天回风湿度低、风速大时,传感器读数会有小幅跳动。厂家建议装一个防风保护罩,我装上后信号确实稳定下来。这提醒我一件事:PID参数再调得好,传感器数据不真实,一切都是空谈。

5.2 冬季与夏季工况切换

空调箱从春天调试到冬天,工况变化让我对这套程序又做了好几轮修改。最大的一个问题,是控制系统必须在不停机的情况下,自动从夏季除湿模式切换到冬季加热加湿模式。

夏季模式的特征是冷阀长时间投入,加热阀只在送风温度太低时启用。冬季模式则完全不同,冷阀可能几天都不动作,主要靠预热段把新风的温度提上来,再用加热阀细调,加湿器频繁动作。中间还有过渡季,室外温度不高不低,新风可以直接利用,冷热阀都处于间歇工作状态。

我在程序里加了一个“工况判断”子程序,通过室外温湿度和回风温湿度计算当前的状态,分成夏季除湿模式、冬季加热加湿模式、过渡季自然能模式。切换时不是简单改几个标志位,而是把每个PID回路的输出上下限、积分参数、手自动状态整体切换。比如过渡季把冷阀输出上限限制在40%,防止意外除湿引起温度大幅下降;冬季把加湿回路的手动清零值可以赋到一个安全开度,避免频繁启停。

这个工况判断子程序当时没有做得很智能,只是基于室外温度、室外焓值、房间温度偏差做的分段判断。但对于这台设备的运行环境来说已经够用,业主操作员只需要在触摸屏上确认当前模式,不需要改任何底层参数。

5.3 上位机通讯与运维细节

S7-200 SMART的以太网口支持Modbus TCP和西门子自己的协议。这个项目触摸屏走的是Modbus TCP,上位机数据采集系统走的是Modbus TCP从站。由于空调箱要求长期记录温湿度曲线用于合规审查,PLC必须稳定地把温度、湿度、阀门开度、PID设定值这些数据送给上位机。

做Modbus映射时要注意地址偏移和数据类型。S7-200 SMART的Modbus库默认是从V区偏移开始映射,上位机读的保持寄存器地址和V区符号表里的地址差着一个固定的偏移量。我在项目里单独建了一个“通讯映射区”,把需要上报的数据全部集中复制到一段固定V区,这样无论程序怎么优化重构,上位机的点表都不用频繁改。

通讯中断是另一个容易遇到的问题。一开始上位机偶尔读不到数据,排查后发现是PLC侧的Modbus从站指令在某个扫描周期被其他中断程序抢占了太多时间。解决方法是把通讯保持功能放到一个低优先级的循环中,并在主程序里定期刷新,确保数据不陈旧。后来我还加了心跳寄存器,上位机如果超过30秒没收到心跳,就判定通讯故障并给出报警提示。

这个项目的运维交接也很重要。我在触摸屏上做了参数修改页面,但设了密码权限:操作员只能改设定值,维护工程师才能改PID参数。这样防止有人误调参数把系统搞乱。每一次参数修改都会记录时间戳和修改人,方便事后追溯。

这套程序从设计到最终稳定运行,中间改动了很多次。有一次改了下限判断逻辑就导致全系统停机,原因是我忘了把手动状态下的阀门限幅也统一修改。做过这个项目之后我有个很深的体会:PLC程序的可靠性,往往不取决于控制算法有多高级,而取决于你有没有把每一个异常情况都提前考虑到。串级PID、结构体变量都只是工具,真正值钱的是那些藏在边角里的保护逻辑和切换策略。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进