基于S7-200 SMART的医药洁净室空调箱温湿度串级PID控制
做医药洁净室暖通自控的朋友应该没少被温湿度“打架”这件事折腾过。我之前处理某制药车间的净化空调系统控制平台用的是S7-200 SMART对象是一台典型的两管制空气处理机组涵盖混风、表冷、加热、加湿、送风机、过滤段这些常规工艺。项目本身不算复杂但自动模式一投问题就来了回风温度勉强能压住回风湿度却跟着温度上下震荡水阀一会儿全开一会儿全关车间值班室天天翻报警记录。后来我把温湿度控制策略改成串级PID用回风温湿度做主环、送风温湿度做副环把控制链拆成两层又把空调箱涉及的几十个模拟量通道、设定值、PID参数、报警状态全部用结构体变量重新组织。改完之后程序结构清爽很多现场调试速度和系统稳定性都明显上了一个台阶。这篇文章想把当时的控制方案和落地细节聊清楚尤其是S7-200 SMART这个平台上不太被细讲的实现部分。1. 洁净室空调箱的控制难点为什么单回路老被“打脸”1.1 温湿度强耦合看起来是两个回路实际是一条链医药洁净室之所以麻烦是因为温度和相对湿度并不是两个独立变量。空气温度一变相对湿度立刻跟着变。车间回风温度稍微升高1℃相对湿度可能掉3%~5%。如果温度和湿度各自搭一个单回路PID温度回路让表冷水阀关小一点湿度回路马上就感觉到湿度升高赶紧去开加湿阀加湿阀一开空气带进水汽后温度又掉一点温度回路又去开加热阀。两个回路就像两个人拔河最后谁也稳不住阀门还频繁折腾。洁净室的特殊之处在于送风量很大很多剂型要求换气次数15次/小时以上这意味空调箱承担的热湿负荷变化快、惯性也大。从表冷段、加热段、加湿段的阀门动作到回风温度传感器感受到变化中间往往隔着十几米风管、过滤器和房间空间一两分钟的滞后是常态。这个滞后对单回路PID相当不友好增益给大了就振荡给小了回风温度半天回不到设定值湿度更是在加湿和除湿之间来回摆。我在现场见过不少项目单回路PID参数已经缩得很保守结果湿度的动态偏差还是能到±15%。1.2 空调箱的典型工艺段与执行器配置先给刚接触净化空调的朋友补个背景。医药洁净室空调箱一般由混风段、初效过滤段、表冷器段、加热段、加湿段、风机段、中效过滤段组成。表冷段通常走7~12℃冷水用来降温和除湿加热段走热水或者用电加热负责把除湿后的冷风再热到送风温度加湿段一般用纯蒸汽加湿负责冬季或低湿工况加湿。执行器就是水管路上的比例积分调节阀4~20mA或者0~10V信号控制阀位开度时按行程缓慢动作。这套配置决定了温度和湿度控制并不是各管各的。表冷器的冷水阀关小了送风温度升高、除湿量下降再热阀开大了送风温度上升但绝对含湿量基本不变加湿阀开启相对湿度上升同时因为蒸汽温度比较高也会轻微改变送风温度。这些耦合关系决定了简单并联控制很难同时把温度和湿度都稳定在医药行业常见的指标里。医药洁净区通常要求温度20~24℃、相对湿度45%~60%看起来范围挺宽但药监检查要的是稳定性和记录波动太大连验证都过不了。1.3 为什么串级PID更适合这个场景串级控制的本质是“把环套起来”外环负责慢变量也就是回风温湿度代表房间真实状态内环负责快变量也就是送风温湿度直接反映空调箱出口状态。外环的输出作为内环的设定值内环直接驱动执行器。因为内环比外环快得多新风温湿度变化、水阀扰动这类干扰首先被内环压住外环面对的其实是一个已经被内环稳定过的对象滞后大大缩短外环PID参数也能给得更从容。我之前见过一个很贴切的类比单回路PID就像让老板直接去操作生产线上每一个旋钮老板看到最终结果不对了再拧一下反应慢还容易拧过头串级PID则是老板定目标现场班长看到送风状态稍有波动立刻微调老板只管盯着车间最终指标。医药空调箱这种大滞后、强耦合对象明显需要后一种结构。2. 温湿度串级控制策略主环副环定谁执行器怎么分工2.1 主环副环的选择原则串级结构里最关键的问题是温湿度串级到底哪个环控制哪个执行器很多人一上来把两个回路接到同一个水阀上逻辑必然打架。我最后采用的做法是按执行器的物理作用来分湿度主回路控制除湿用的表冷水阀开度夏季湿度高时通过它把空气温度压到露点以下完成深度除湿。温度主回路控制加热/再热段阀门补偿表冷除湿带来的冷风感把送风温度拉回目标。加湿阀单独由湿度回路的反向动作控制冬季干燥时开启夏季除湿工况下强制关闭。这个策略能成立的原因在于“除湿再热”是一条经典解耦链。表冷水阀开大必然让送风温度降低但送风温度又是温度副环的控制对象副环会迅速用再热阀把温度拉回来。再热不改变空气绝对含湿量所以湿度靠表冷除湿来压温度靠再热来顶两个量在这一条链上被拆开了。实际运行中夏季典型的控制动作就是湿度偏高→冷阀开大→送风温度下降→温度副环感知到→热阀开大→送风温度恢复。当然要分季节和工况夏季湿度高冷阀是湿度的主要执行器热阀归温度管冬季湿度低加湿阀作为湿度执行器冷阀和热阀一起负责温度。这些工况切换可以做成手动方式也可以根据回风温湿度自动判断我实际项目里是先在触摸屏上给了“夏季/冬季/过渡季”三个手切位逻辑跑顺之后才做的自动判段。2.2 主环输出到副环设定值的量程变换这一步在S7-200 SMART上最容易翻车。PID运算内部使用的是归一化后的0~1.0标幺值主回路的PID输出也是0~1.0的量。如果你直接把主环输出接到副回路PID的设定值输入副回路会把送风温度设定值当成0~1来处理实际想要的16℃、22℃全都对不上。我的一般做法是做一次线性变换副回路SP SP_MIN 主环PID输出 × (SP_MAX - SP_MIN)比如送风温度副环设定值范围设成10℃~30℃主环输出0.5时副环SP 10 0.5×(30-10) 20℃。湿度主环输出映射到送风湿度设定范围比如30%~70%RH。这样主环和副环才能正确“对话”。这里特别提醒一句主环输出和副环SP的上下限要跟PID向导里设定的过程变量上下限保持一致否则同一个工程值会被两套量程算成不同的归一化结果。2.3 串级PID参数初值怎么给串级PID参数没有绝对标准但给初值是有套路的。我这次调试的经验数据大致如下回路比例增益P建议范围积分时间TI建议微分TD说明温度副环送风温度1.0~3.030~120秒0或很小先整定这个阀门行程慢时TI取大温度主环回风温度0.3~1.0180~600秒0滞后大积分要放慢湿度副环送风湿度0.8~2.530~90秒0湿度传感器噪声较大湿度主环回风湿度0.2~0.8300~900秒0湿度波动比温度慢得多整定顺序永远是从副环到主环。副环先把送风温湿度稳定在固定SP附近主环再关环。主环的积分时间至少是副环积分时间的2倍以上否则两个环会同频共振产生一种周期十几分钟的低频振荡比单回路还难调。微分在温湿度控制里我一般不用因为湿度传感器信号本身噪声不小微分容易把阀门指令放大成毛刺。2.4 分程控制冷阀、热阀、加湿阀别打架空调箱里冷阀、热阀、加湿阀如果都由不同PID回路独立输出很容易出现冷热同开、能量对冲的情况。我在程序里用了分程控制思想让同一套PID输出按区间分配到不同执行器PID输出区间动作对象说明0% ~ 40%热阀由全关到全开低温需要再热时动作40%~60%死区防止冷热阀频繁切换60%~100%冷阀由全关到全开高温需要降温/除湿时动作湿度回路类似输出低位段控制加湿阀高位段控制除湿冷阀中间留死区。分程的好处是只有一套PID输出信号不存在两个调节阀抢同一个被调量的问题。死区宽度要结合执行器行程时间设置一般5%~10%就够太大会导致温湿度对设定值存在静差。3. 用结构体变量把空调箱程序做干净3.1 没有结构体时项目会乱成什么样很多人在S7-200 SMART上写空调箱程序习惯一个点一个点地定义符号结果项目后期符号表里密密麻麻全是“送风温度”“回风湿度”“冷阀反馈”“热阀反馈”这种名字。一台机组还好两台、三台机组时每个人命名习惯不一样有的叫AI0、有的叫AHU1_T、有的叫T_SEND程序里查一个地址要把交叉引用翻半天。最怕的是复制粘贴后改错地址调试时查几天都查不到。所以我在这个项目里坚持用结构体变量来做信息建模。S7-200 SMART的编程环境虽然没有高端平台那么完善的UDT生态但新版Micro/WIN SMART是支持用户自定义数据类型UDT的。UDT就是自己拼出来的一种变量模板写成一次就可以批量实例化成多台机组的数据结构。可以说一台空调箱需要关注的所有信号和参数都在同一个结构体里程序自然干净。3.2 UDT成员怎么规划我的习惯是按功能段划分一台空调箱一个结构体实例。下面是一个简化后的成员设计实际命名按Micro/WIN SMART允许的规则来INPUT_ZONE // 输入区 AIT_SEND REAL // 送风温度工程量 AIH_SEND REAL // 送风湿度工程量 AIT_RTN REAL // 回风温度工程量 AIH_RTN REAL // 回风湿度工程量 DI_FAN_RUN BOOL // 风机运行反馈 DI_FAN_FAULT BOOL // 风机故障 DI_FILTER_ALM BOOL // 过滤器压差高 OUTPUT_ZONE // 输出区 AO_COLD REAL // 冷阀指令 AO_HOT REAL // 热阀指令 AO_HUMI REAL // 加湿阀指令 AO_FAN_FREQ REAL // 风机变频频率 DO_FAN_START BOOL // 风机启动指令 SET_ZONE // 设定区 SP_TEMP REAL // 回风温度目标 SP_HUMI REAL // 回风湿度目标 SP_SEND_TEMP REAL // 送风温度目标副环SP SP_SEND_HUMI REAL // 送风湿度目标副环SP PID_ZONE // PID参数区 KP_T, TI_T, TD_T REAL KP_H, TI_H, TD_H REAL STATUS_ZONE // 状态区 MODE_AUTO BOOL // 自动模式 ALM_WORD WORD // 报警字 RUN_TIME DWORD // 累计运行时间这个结构体示意不代表能直接编译但思路是通用的。设计时要特别注意类型对齐REAL占4字节、BOOL按位、WORD占2字节条件允许就把同类型成员放在一起减少后期地址偏移计算的麻烦。结构体实例多了以后每一次地址偏移都要根据软件里自动生成的结果来核对不能凭脑子硬算。3.3 从模拟量通道到结构体全局变量表的关键一步结构体实例在全局符号表里定义之后程序里可以直接看到类似“AHU1.SP_TEMP”这样的符号路径。但模拟量模块的通道地址是AIW0、AIW2、AIW4这样的顺序排列它不会自动进入结构体的输入区必须手动做一次一一映射。我通常把模拟量转换做成一个独立子程序每台空调箱调用一次把一个或者若干个AIW通道地址读出来经过滤波、量程变换、断线判断之后写入结构体对应的REAL成员。这一步不建议偷懒直接让PID指令的PV去读AIW地址。因为我前面吃过亏换了模拟量模块或者调整了通道顺序所有和地址绑定的逻辑全都要翻一遍改成统一映射之后后面换模块、改量程、增加传感器只需要动开头那一段转换程序PID回路完全不受影响。3.4 多台机组和V区规划S7-200 SMART的V区是共享存储区容量和具体CPU型号有关。一个UDT实例如果成员比较多比如几十个REAL加几十个BOOL一个实例大概占一两百字节带十台空调箱也就两K字节左右V区容量基本不是瓶颈。真正紧张的是模拟量通道数量和PID回路数量而不是结构体本身。用结构体做多台机组还有一个好处可以规划一块连续的V区把每台空调箱的输入区和状态区排在一起。这样后续做Modbus通讯时从站寄存器地址可以按偏移量批量计算上位机组态只需要按同一张布局表一次性读取不需要一个点一个点去对地址。我在这个项目里就把AHU1到AHU5的状态区连续放在同一段V区里触摸屏和中控读取都省了很多功夫。4. S7-200 SMART上的程序实现PID向导与串级联动细节4.1 PID向导生成多个单回路S7-200 SMART的编程环境里PID功能主要是靠“向导”生成的没有像更高端平台那种直接拖一个“串级PID”功能块的现成东西。实现串级的思路就是用它生成多个单回路PID子程序然后在主程序里把它们按顺序串联起来。我在项目树里打开PID向导一共生成了四个回路回路0做回风温度主环回路1做送风温度副环回路2做回风湿度主环回路3做送风湿度副环。每个回路会生成一个类似PIDx_INIT的子程序调用时指定过程变量、设定值、手动/自动切换、手动输出等参数。向导里要填写好过程变量上下限、输出类型、采样时间、PID参数这些数值后续都可以通过修改向导再重新生成。要注意的是向导生成子程序的输入输出接口默认涉及的是归一化后的工程百分比值。而我们在结构体里用的是20.0℃、60.0%RH这样的工程量两者之间必须有明确的归一化和反归一化环节。这部分我没有放在向导里硬填而是在程序中写了一个统一的换算逻辑先把结构体里的工程量折算成0~1.0给到PID子程序再把PID输出折算回工程量或者直接分程给阀门指令。4.2 主环输出到副环SP连续赋值还是带安全跟踪串级联动在程序里其实不复杂关键是要想清楚主环输出什么时候允许更新副环SP。我实际写的逻辑是每个扫描周期先读回风温度工程量归一化后送入主环PID子程序主环PID计算得到的输出先做0.02~0.98的限幅再通过线性变换映射成送风温度副环的设定值副环PID再读这个设定值和自己的送风温度PV一起计算输出最后经过分程逻辑分给冷阀和热阀。湿度回路同理。这里有个容易踩的坑系统刚启动或者送风机还没运行时主环的输出是没有意义的。如果不做保护主环可能会在开机前一直朝某个方向积分等风机一启动副环SP已经被推到量程上限送风温度一下就冲上去。所以我在主环输出到副环SP之间加了一个“运行允许”位只有送风机运行且空调箱处于自动模式时主环输出才允许更新到副环SP其他情况下副环SP保持一个安全值比如送风温度固定20℃、送风湿度固定55%同时主环切到手动保持状态不让它盲目积分。4.3 手自动切换与无扰逻辑无扰切换是医药项目验收时经常被盯着检查的功能。S7-200 SMART的PID向导子程序一般带有自动/手动切换输入端子手动模式下可以直接把外部给定的手动输出值送到子程序接口。我在触摸屏上做了每个阀门的单独手自动切换手动模式下PID的输出通道被切断当前阀门开度完全由操作员给定。从手动切回自动前要把当前阀位反馈折算成PID的0~1.0输出作为手动值先注入一次再做切换。这样保证切自动的瞬间阀门开度保持原样然后由PID慢慢接管。串级结构下还要多加一层配合副环切手动时主环也强制切到手动保持主环切手动时副环可以继续自动但SP不再跟随主环而是使用安全值。这样就不会出现副环已经手动去动阀门主环还闷头对着回风温度积分的情况。4.4 报警与联锁PID算法之外的安全网空调箱程序不能只有PID医药洁净室对传感器断线、风机故障、温湿度超限非常敏感。我在结构体的状态区里规划了几个报警字并把报警逻辑和PID逻辑完全分开处理报警条件判定方式动作策略温度传感器断线4~20mA输入信号低于4mA对应原始值对应PID切手动阀位保持报警提示湿度传感器断线同上对应PID切手动阀位保持报警提示风机运行反馈丢失运行指令发出后10秒无反馈禁止冷阀/热阀/加湿阀自动输出防止无送风时水阀大开过滤器压差高压差开关闭合只报警提醒更换滤网不停机回风温湿度超限超出设定范围并持续一段时间报警记录超限时间联动上位机界面提示这些逻辑单独写起来不难但很容易被忽略。现场调试时第三方验证经常会专门测传感器断线、风机反馈丢失这些边界情况如果程序里没有对应保护PID可能会对着错误信号猛推阀门把空调箱弄得更糟。安全逻辑和PID逻辑解耦是我在这个项目里坚持的程序结构原则。5. 现场调试串级PID不是调完参数就完事5.1 先内环后外环顺序千万别反串级PID调试顺序是固定的先把内环拆开来调稳再合上外环。内环调试阶段主环输出固定在一个中间值副环SP手动设定一个固定温度比如20℃观察送风温度能否稳定在设定值附近、阀门动作是否频繁。内环稳定了再让主环闭环从很小的外环P开始慢慢加。我当时踩过一个坑觉得串级高级直接两个环同时投结果回风温度出现周期五分钟的大幅振荡整个车间的空调像是在“呼吸”。后来拆开一测发现副环的PID在阀门行程超过两分钟的场景下积分时间给得太短副环自己就在振荡。先把副环P降到1.2、积分时间升到三分钟振荡才消掉。所以别跳步骤内环不稳外环一定炸。5.2 阀门执行器响应慢引发的“假振荡”比例积分调节阀的执行器行程时间一般在30秒到3分钟不等。程序扫描周期是几十毫秒如果PID输出0.1%的微小变化执行器根本来不及响应但PID觉得“阀没动”于是继续积分。等执行器终于走完这0.1%阀位可能已经过头了温度一下子冲过设定值形成一种频率很低但振幅很大的假振荡。这个问题单靠PID参数很难完全解决。我后来在程序里加了两层处理一是PID输出变化率限制两个扫描周期之间输出变化超过某个阈值才更新阀门指令二是给PID输出加了一阶惯性滤波时间常数按执行器行程时间的五分之一左右设置。这样PID就不会对着一个慢吞吞执行器猛追猛打。这个方法虽然牺牲了一点响应速度但换来了稳定医药空调场景完全值得。5.3 传感器安装位置会直接决定串级效果回风温湿度传感器的安装位置如果太靠近门、回风口或者直吹空调箱回风柱数据会带明显的局部波动主环就会跟着乱动。送风温湿度传感器要放在风机均流段之后、送风管道足够长的直管段上不能紧贴加湿段出口否则蒸汽还没混合均匀湿度传感器读数会剧烈跳动。有一次调试送风湿度曲线高频毛刺特别明显PID输出也跟着抖。我一开始还以为是PID参数问题后来到现场一看湿度传感器就装在加湿段后面不到一米的地方蒸汽喷出来直接打在探头上。把传感器挪到均流段后两米左右的直管段曲线马上平了。所以调试时我习惯先连续记录一个小时的回风、送风温湿度曲线看看有没有明显毛刺有就先把传感器和安装位置的问题解决再谈PID参数。6. 方案扩展值班模式、Modbus通讯与平台升级6.1 夜间值班模式与变设定值串级PID搭好之后扩展节能逻辑会方便很多。医药厂房夜间不生产时洁净室不一定完全关机一般切到值班模式保持正压和基础洁净度。我在结构体的设定区里做了两套设定值正常生产设定值和值班设定值再通过时间表自动切换。切换时主环SP会变化副环自动跟踪不需要改任何PID接线。操作员在触摸屏上还能手动微调值班值用起来很顺手。这套做法本质上是把串级控制的设定值“变成变量”而不是把PID参数改来改去。只要主副环参数整定合理变设定值不会引起大的波动这也是串级结构相对单回路的一大优势。6.2 Modbus把结构体数据送给上位机S7-200 SMART本身支持Modbus RTU和Modbus TCP库。用结构体变量规划的好处在这里体现得很明显我可以把AHU1到AHU5的所有输入区、状态区、报警区连续放在一段V区里Modbus从站地址表按偏移量生成上位机组态只要按同一张偏移表一次性读取不需要一个点一个点去对地址。这里要提醒结构体成员的偏移不是想当然的连续字节不同类型存在对齐规则。我在做Modbus地址表时一定要先在软件里查看交叉引用生成的变量地址再回填到上位机组态里。有的是因为想当然算偏移结果某一位对不齐整块数据都读乱。这个习惯算是从这个问题里养成的。6.3 向S7-1200/1500迁移的思路如果项目后续要扩容点数超过200 SMART的能力或者需要使用更专业的PID功能块把这里的控制思路迁移过去并不难。高端平台的PID功能支持直接填工程值、自带手自动无扰切换串级结构在程序里也更容易组织。结构体变量迁移过去就是更成熟的UDT加全局数据块使用体验比在200 SMART上顺畅得多。迁移之前建议先把控制策略部分整理成一份文档包括主环副环对应关系、量程变换公式、分程死区、手自动切换条件。换平台最大的坑不是语法而是控制逻辑没有固定下来。先文档后编码永远是这种迁移项目最稳的做法。最后分享一个自己常用的习惯每次调完一遍串级PID我都会把回风温度、送风温度、回风湿度、送风湿度的历史曲线导出保存同时在结构体里留一块PID参数备份区。后面环境变化导致控制不稳定时不用从头盲目试参直接把备份参数调出来对比往往几分钟就能判断是参数漂了还是执行机构出了问题。串级PID和结构体变量都不是新技术但在S7-200 SMART这个平台上把它们用好医药空调箱的稳定性问题真能解决大半。