ARTICLE · INTELLIGENCE

战地情报 · 详情页

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

箱式无负压供水系统PLC控制与工程调试全解析

箱式无负压供水系统PLC控制与工程调试全解析 做供水系统调试这些年我经手过不少二次供水设备箱式无负压供水系统是里面比较特别的一类。它既要“叠压”利用市政管网余压又得靠水箱兜底控制逻辑比普通的恒压变频供水复杂一个量级。很多工程师第一次接触时容易混淆它到底算无负压设备还是算带水箱的变频供水代码层面又该怎么把“无负压保护”和“泵组调度”落到PLC里这篇文章我打算从原理讲到具体代码实现最后把我在现场踩过的、见过别人踩的坑一并说出来给准备做这类项目或正在被这套系统折磨的朋友一个完整参考。整篇文章会覆盖四块内容无负压技术的本质、设备硬件信号链路、PLC控制逻辑代码、Python仿真调参。最后单独花一节聊工程落地的注意点。代码部分同时给了IEC 61131-3结构化文本ST和Python两种写法前者用于实际控制器后者用于离线仿真和PID调参验证。1. 为什么“无负压”不是一种压力而是一种控制目标先澄清一个最常见的误解很多人以为“无负压”是指管网里永远没有负压或者设备能把负压完全消除。实际情况不是这样。市政管网在供水末端本来就有可能因为用水高峰、管道检修、上游泵站波动而出现压力跌落甚至负压无负压供水设备的任务是在用户侧继续正常供水的同时保证设备进水口处的压力不低于某个安全限值从而不把负压传递回市政管网。1.1 市政管网直供的极限与二次供水的必要性市政自来水的出厂压力通常在0.3MPa到0.5MPa之间但经过长距离输送、楼层叠加消耗到用户楼栋前往往只剩下0.15MPa到0.25MPa。我国《民用建筑节水设计标准》和各地二次供水技术规程里普遍要求用户最不利用水点处的供水压力不能低于0.1MPa到0.15MPa。一旦建筑物超过6到8层市政压力就很难满足末端水压需求必须做二次加压这就给箱式无负压以及其他二次供水设备留出了用武之地。如果直接采用“水箱加变频泵组”的传统方案水泵从水箱取水市政管网只负责给水箱补水这套方案虽然非常稳妥但有一个天然缺陷市政管网的余压被完全浪费了。一吨水从市政管网进入水箱再从水箱加压送到用户等于把原本可以免费利用的0.2MPa压力全部归零再重新做功。按水泵轴功率公式P与扬程H成正比粗略估算一个日供水500立方米的小区每天多消耗的电费可能达到30到50度积年累月是个不小的数字。1.2 叠压供水的本质压力和流量的双重叠加无负压设备的核心思路是“叠压”也就是把市政管网剩余压力叠加到水泵增压值上。比如市政进水压力是0.2MPa用户需求压力是0.5MPa那么水泵只需要额外提供0.3MPa的压力即可而不是从零加压到0.5MPa。这个0.2MPa的基压被免掉了水泵功率大约能下降40%左右节能逻辑非常简单清晰。但“叠压”有一个前提条件进水压力必须足够稳定且不允许出现负压抽吸。所以无负压设备会在进水总管上装压力变送器实时监测进水压力控制器根据进水压力动态调整水泵转速和出水压力设定值。当进水压力降到某个阈值以下时设备会降频运行、减少取水流量甚至切到水箱供水这就是“无负压保护控制”的使命所在。这里要特别注意真正的无负压设备并不是靠机械结构“绝对防止”负压发生而是通过快速感知进水压力变化并调整水泵工况把进水口压力维持在一个允许范围内。负压是否出现取决于控制器的响应速度和执行机构的动作速度。所以说无负压是一种动态控制目标不是静态的结构属性。1.3 箱式无负压什么时候该选它什么时候不该选市场上常把无负压设备分成罐式无负压和箱式无负压两种。罐式无负压内部有一个不锈钢稳流罐也叫补偿罐罐体上部装有真空抑制器利用罐内的水量和气压变化来缓冲负压冲击。箱式无负压则是“稳流罐水箱”的组合体它增加了一个体积更大的常压水箱用于在市政管网长时间停水或严重欠压时维持一段时间的供水。箱式方案的适用场景我想了想主要有三类市政管网供水能力波动大虽然多数时段压力够但早晚高峰期会出现短时欠压甚至停水建筑内有消防储水需求或用户有条件利用夜间低谷进水蓄水需要水箱作为调节容积当地供水主管部门要求二次供水必须配置一定储水容积单纯罐式设备无法通过验收。但箱式也有一个绕不开的缺点水箱水质管理。水箱的定期清洗、消毒、溢流报警、水位控制每一项都会增加运维成本。如果项目所在地的物业管理水平跟不上箱式设备反而可能成为水质投诉的重灾区。所以我一般建议如果市政管网条件真的很好优先选罐式无负压只有管网条件确实恶劣或者当地有明确验收要求时才选箱式方案。2. 设备侧发生的事情从泵组到传感器的信号链要说清楚代码先得把设备硬件链路捋一遍。我见过不少程序员接手无负压控制程序时连进水压力变送器装在哪儿都没搞清楚就去改PID逻辑结果控制效果一塌糊涂。代码只是最后落地的那一层信号采集的可靠性和物理位置其实更重要。2.1 核心硬件组成和信号走向一台典型箱式无负压供水设备主要包含以下部件进水总管市政来水入口依次安装蝶阀、Y型过滤器、倒流防止器、电磁阀或电动阀、进水压力变送器稳流罐补偿罐罐体上部接真空抑制器罐体下部接进水压力变送器或罐体压力变送器罐体侧面一般还接一个电接点压力表用于硬保护水箱带液位计投入式液位计或浮球液位开关水箱进水口由补水电动阀控制泵组通常配置2到4台立式多级离心泵每台泵出口装止回阀和检修阀泵组出水总管上装出水压力变送器流量计装在出水总管上常用电磁流量计或超声波流量计控制柜内含PLC、变频器、接触器、热继电器、断路器、中间继电器、浪涌保护器等人机交互触摸屏HMI负责显示参数、报警、设定压力、修改PID参数远程通信4G DTU或以太网模块用于把设备数据上传到云平台。信号走向大概是压力变送器和液位计输出4-20mA信号给PLC的模拟量输入模块PLC经过量程换算得到实际工程值再通过PID和状态机逻辑计算出频率给定值输出0-10V或4-20mA信号给变频器变频器驱动电机同时PLC通过开关量输出控制接触器、电动阀通过RS485接口读取流量计、变频器数据。2.2 一次调试时最容易忽略的接线问题我在现场见过最典型的接线错误有两种。第一种是进水压力变送器和出水压力变送器的量程弄反或者两路信号接反导致控制器把进水和出水压力认反一启动就出现逻辑混乱。第二种是模拟量信号线没有用屏蔽电缆或者屏蔽层没有单端接地变频器一运行压力信号就在4-20mA范围内剧烈跳动产生每秒0.2MPa以上的虚假波动。这种问题会让PID控制器误判为真实压力波动导致频率一直在上下抖动水泵频繁加减速。信号标定也一样关键。PLC的模拟量输入模块通常把4-20mA信号转换成一个整数比如西门子S7-200 SMART对应0到27648三菱FX系列对应0到4000汇川、台达等国产PLC也有各自的数值范围。如果组态里量程上限设置错了比如压力变送器量程是0-1.6MPa模块转换后的最大值对应的是4000但你错误地设置成0-1000那么压力实测值就会放大4倍系统一开机就以为超压反复报警停机。这不是控制逻辑写得不好而是最基础的工程换算出了错。2.3 运行状态机的整体设计框架无负压控制系统看起来是一个连续调节过程但真正的工程实现通常是“状态机调节回路”的组合。要把各种工况处理得井井有条先得定义设备运行状态。我常用的状态划分如下状态编号状态名称进入条件主要动作S0待机/停机手动停机、保护触发所有泵停止、进水电磁阀根据水位开关S1启动准备满足启动条件、水箱水位OK开启补水电动阀、检测压力信号正常S2建压启动信号有效启动1号泵、变频软启动升频S3自动恒压出水压力在设定范围内PID调节、泵组加减泵S4进水欠压保护进水压力低于保护阈值降频、切水箱水源、记录报警S5水箱供水进水长期欠压/停水水泵从水箱取水、关闭进水阀S6故障/报警超压、缺水、泵故障、传感器断线声光报警、按故障等级停机状态机的好处是逻辑清晰不会出现“既在PID调节又在水箱供水”这种互相矛盾的执行状态。后面讲代码时会把这个状态机落到ST语言里。3. 核心控制逻辑的代码实现代码部分我采用IEC 61131-3结构化文本来写这套语法在西门子、倍福、Codesys平台以及不少国产PLC里通用思路也可以迁移到梯形图或者C语言里。由于实际控制器品牌不同模块命名会略有差异我尽量把逻辑本身写清楚你可以直接参照着改。3.1 主状态机的ST代码实现状态机的代码结构并不复杂关键是执行顺序和状态切换条件要严格。下面的代码是主程序段(* 主状态机执行 *) CASE runState OF STATE_IDLE: (* S0 *) // 待机状态下所有泵频率给定为0 freqRef : 0; pumpEnable : FALSE; // 如果满足启动条件切换到建压准备 IF startCommand AND NOT faultPresent THEN runState : STATE_PREPARE; END_IF STATE_PREPARE: (* S1 *) // 检查水箱水位和进水压力 IF tankLevel TANK_LOW_LEVEL THEN inletValve : TRUE; // 打开进水电磁阀 IF inletPressure START_MIN_PRESSURE THEN runState : STATE_PRIME; // 满足条件开始建压 END_IF ELSE alarmCode : 10; // 水箱水位过低 END_IF STATE_PRIME: (* S2 *) // 启动1号泵频率从0逐步上升 pumpEnable : TRUE; activePump : 1; IF freqRef PRIME_FREQ_LIMIT THEN freqRef : freqRef PRIME_RAMP_SPEED; ELSE runState : STATE_AUTO_RUN; END_IF STATE_AUTO_RUN: (* S3 *) // 恒压运行见下面的PID和泵切换逻辑 pumpEnable : TRUE; Call_PID_Control(); Call_NoNegativePressureProtect(); Call_PumpSwitchLogic(); STATE_TANK_SUPPLY: (* S5 *) // 水箱供水状态水泵进水来自水箱 inletValve : FALSE; pumpEnable : TRUE; Call_PID_Control(); STATE_FAULT: (* S6 *) freqRef : 0; pumpEnable : FALSE; inletValve : FALSE; END_CASE;这段代码里有个容易被忽视的细节建压阶段STATE_PRIME不能让PID立刻投入。因为系统刚启动时出水总管里是空的压力几乎为零PID会认为误差极大给出一个大频率给定水泵一下子冲到工频管路瞬间增压不仅容易水锤还可能让压力超调到0.8MPa以上。所以要先以固定速率开频当压力接近设定值后再切换到闭环PID调节。这个“开环建压”的时长取决于管路容积和泵组流量一般10到30秒。3.2 防负压保护子程序这是箱式无负压设备与普通变频供水最核心的区别。保护逻辑需要做到实时监测进水压力当进水压力低于“无负压保护压力”时最小化取水流量并迅速切换水源。(* 防无负压保护子程序 *) PROCEDURE Call_NoNegativePressureProtect // 进水压力低于保护阈值立即降频限流 IF inletPressure NEGATIVE_PRESSURE_LIMIT THEN negativePressureFlag : TRUE; // 频率给定快速下降到下限 IF freqRef FREQ_LOWER_LIMIT THEN freqRef : freqRef - FREQ_RAPID_DROP; ELSE freqRef : FREQ_LOWER_LIMIT; END_IF // 如果进水压力继续下跌进入水箱供水状态 IF inletPressure NEGATIVE_PRESSURE_STOP THEN runState : STATE_TANK_SUPPLY; alarmCode : 20; negativePressureCount : negativePressureCount 1; END_IF ELSE // 恢复正常后延时退出保护防止反复切换 IF negativePressureFlag THEN recoveryTimer : recoveryTimer 1; IF recoveryTimer RECOVERY_DELAY THEN negativePressureFlag : FALSE; recoveryTimer : 0; END_IF END_IF END_IF END_PROCEDURE代码里有两个关键参数NEGATIVE_PRESSURE_LIMIT是保护动作阈值一般取0.05MPa到0.1MPaNEGATIVE_PRESSURE_STOP是切换水箱供水的阈值可能更低比如0.02MPa。为什么需要两档因为市政管网瞬时压力波动很常见如果只要有一点压力降低就切水箱设备会在“正常供水和水箱供水”之间频繁切换水质和水压都会受影响。两档保护给控制留出了缓冲区间进水压降到一档时先降频限流大部分情况下管网压力会自行恢复只有降到二档说明市政进水真的撑不住了才切到水箱。3.3 泵组加减泵和休眠轮换逻辑泵组调度逻辑要解决两个问题一是多台泵之间如何切换二是夜间小流量时如何休眠节能。我的做法是把一台泵设为变频泵VVVF其余为工频泵或辅助变频泵。当变频泵已经运行到50Hz且出水压力仍低于设定值0.03MPa左右持续一段时间就把当前泵转为工频运行同时启动下一台泵。这个“延时触发”非常重要不能变频泵一满频就加泵因为压力是缓变的满频状态下压力也许几秒后就达标了加泵会造成过大的流量冲击。泵轮换逻辑则用来避免某台泵长期运行、其他泵长期停泵导致的机械密封粘连和轴承锈蚀。常见做法是按运行时间排序累计运行时间最短的泵优先作为下一台变频泵。(* 泵切换逻辑判断是否需要加泵 *) IF freqRef 49.5 AND activePumpRunning THEN demandUpTimer : demandUpTimer 1; IF demandUpTimer ADD_PUMP_DELAY THEN // 将当前变频泵切为工频启动下一台泵 SwitchCurrentPumpToFixed(); IF activePumpCount MAX_PUMP_COUNT THEN StartNextPump(); activePump : activePump 1; END_IF demandUpTimer : 0; END_IF ELSE demandUpTimer : 0; END_IF夜间小流量休眠是这类设备的“省电法宝”。当出水压力一直稳定在设定值附近且流量持续低于0.5立方米/小时可设置延时5到10分钟系统就停掉所有泵利用气压罐保压。休眠期间压力跌到设定值以下0.05MPa左右再启动一台泵补压。这个功能能省很多电但对气压罐的容积有一定要求后面工程环节会专门讲。4. Python仿真把压力闭环和PID调参跑通PLC程序的调试很麻烦尤其是PID参数没整定时直接在现场试凑既危险又浪费时间。我的习惯是先用Python搭一个简化的供水系统模型把控制逻辑和PID参数仿真跑通再移植到PLC里。下面这套仿真脚本虽然不是工业级精度但用来验证逻辑和初步调参完全够用。4.1 供水过程的简化仿真模型供水系统可以抽象成一个一阶惯性环节水泵流量改变后管网压力不会瞬间变化而是以近似指数方式慢慢逼近稳定值。这个惯性时间常数跟管网容积、管道长度、水压有关小型住宅小区通常3到15秒。我建立了这样的模型import numpy as np import matplotlib.pyplot as plt # 系统参数 dt 0.1 # 仿真步长秒 t_total 300 # 仿真总时长秒 t np.arange(0, t_total, dt) # 用户用水流量模拟0-60秒小流量120-180秒大流量240-300秒恢复 demand_flow np.ones_like(t) * 0.6 demand_flow[(t 120) (t 180)] 3.0 demand_flow[(t 60) (t 120)] 1.5 # 压力模型参数 p_set 0.45 # 目标压力 MPa p_span 0.25 # 无供水时的压力系统内部残压MPa K_pump 0.02 # 频率到压力增益 T_pipe 8.0 # 管网惯性时间常数 freq 0.0 # 初始频率 Hz p_out 0.25 # 初始出水压力 MPa我不打算把水力和水泵曲线推导得太复杂关键是仿真出“用水量变化时压力的趋势”。模型核心公式是# 压力动态方程一阶惯性 p_out ((p_span K_pump * freq) - p_out) / T_pipe * dt这里把水泵加变频器看成一个“可调压力源”频率越高稳定压力越高。用户的用水流量会改变系统的等效负载表现为对压力的干扰用水量越大同样频率下压力越低。所以我在模型里加了一个干扰项p_out - demand_flow[i] * K_demand * dt / T_pipeK_demand是流量对压力的影响系数。这个模型虽然简陋但能有效反映PID控制中的核心矛盾用水波动导致压力波动控制器需要快速补偿。4.2 PID控制器的代码实现与整定流程我实现了一个标准的增量式PIDPLC里用位置式还是增量式取决于平台习惯。增量式的好处是输出是频率修正量不容易产生积分饱和导致的超调冲击。class PIDController: def __init__(self, kp, ki, kd, out_min0.0, out_max50.0): self.kp kp self.ki ki self.kd kd self.out_min out_min self.out_max out_max self.integral 0.0 self.prev_error 0.0 self.prev_output 0.0 def update(self, setpoint, actual, dt): error setpoint - actual self.integral error * dt # 抗积分饱和积分输出限制在[-5, 5]Hz范围内 self.integral max(-5.0, min(5.0, self.integral)) derivative (error - self.prev_error) / dt if dt 0 else 0.0 output self.kp * error self.ki * self.integral self.kd * derivative # 增量限制防止频率突变 delta output - self.prev_output delta max(-0.5, min(0.5, delta)) output self.prev_output delta self.prev_error error self.prev_output output return max(self.out_min, min(self.out_max, output))关于PID整定我用的是改进版“临界比例度法”。先把ki和kd设为0只留kp逐渐增大kp直到系统出现等幅震荡记下此时的增益Ku和震荡周期Tu。然后按经典经验公式初设Kp0.45KuTi0.83TuTd≈0.1Tu再在仿真里细调。实际经验是供水系统的kp一般在1.0到3.0之间ki在0.02到0.1之间kd反而用得很少有时干脆不用因为压力传感器的噪声会被微分项放大。4.3 场景模拟用水高峰、停水、瞬时大流量我在仿真里跑了一个典型场景前期小流量60秒后用水量缓慢上升到1.5立方米每小时120秒到180秒进入大流量高峰180秒后恢复小流量。观察压力曲线即可验证PID能否把出水压力维持在0.45MPa附近。仿真结果的关键观察点有三个小流量时压力平稳频率基本恒定大流量冲击瞬间压力会有一个跌落PID需要1到3秒内把频率提上去压力的最大偏差不应超过0.04MPa流量回落后压力可能短暂超调超调量不应超过0.03MPa并且不能在设定值附近反复震荡。这套仿真脚本还能用来测极限工况把进水压力设成0触发防负压逻辑观察系统是否能在短时间内切到水箱供水状态。把这套逻辑在仿真里验证稳定了再下到PLC现场调试时间能缩短一半以上。5. 工程落地最容易翻车的几个环节代码和仿真只是开始。供水设备最终要装到泵房长期连续运行安装在工程上踩坑的概率远高于软件层面。我把这几年遇到过的问题集中说一下希望能帮你少走弯路。5.1 传感器安装位置不当会让所有逻辑失效进水压力变送器如果装在稳流罐之前还是之后得到的数值含义完全不一样。装在罐前测的是市政直接压力装在罐后测的是罐体压力可能会受到罐内气体缓冲的影响反应滞后。我的建议是在进水总管上装一个压力变送器用于控制逻辑在稳流罐罐体或者罐后装另一个作为低压力硬保护两个信号同时进PLC。出水压力变送器也有讲究应该装在泵组出水总管上最好离水泵出口有一段距离并且装在压力表缓冲管或者阻尼器后面避免水泵的脉动压力直接打在传感器膜片上。如果现场只有瞬时压力没有平均压力PID的输出频率会跟着脉动压力一起抖。流量计前后直管段的问题也常被忽视。电磁流量计的安装要求是上游5倍管径、下游2倍管径的距离内不要有阀门、弯头、变径。很多泵房空间紧凑流量计紧贴止回阀安装测量数据严重偏差导致加泵判断失误——明明实际流量已经很大了流量计显示却很低系统迟迟不加泵压力一直掉。这种问题不是改代码能解决的只能改管道位置。5.2 真空抑制器和气压罐的配合逻辑稳流罐上方安装的真空抑制器本质上是一个机械式空气阀。当罐内压力低于大气压时它自动打开补入空气破坏真空当压力大于大气压时阀瓣关闭防止漏水。它的动作速度直接影响无负压保护是否可靠所以选型时不要贪便宜选那些阀瓣动作迟缓的劣质产品。气压罐则负责两件事一是吸收瞬间的流量冲击二是让夜间小流量休眠成为可能。气压罐的有效容积计算有个简易公式V Q * t / (4 * (P1 0.1) / (P2 0.1) - 4)其中Q是水泵流量立方米每小时t是休眠时间小时P1是启动压力MPaP2是停泵压力MPa。我建议休眠时间不要设计得太长10分钟就够因为气压罐里的水如果长时间不流动水质也很难保证。另外气压罐需要每年检查一次预充氮气压力一般预充压力在0.15MPa到0.25MPa之间低于这个值气囊就会反复变形寿命明显缩短。5.3 验收调试顺序和常见返工原因设备安装完成后不要急着用自动模式。我见过不少施工队一送电就打到自动结果不是超压就是泵损坏。正常的调试顺序是先做单机试运行手动控制每台泵启停确认转向正确然后做管路冲洗把管道里的焊渣、麻丝、泥砂冲干净这一步非常重要我见过有过滤器堵死导致水泵抽空损坏的案例再手动调速检查水泵在低频、工频下的压力和电流是否在正常范围接下来切换到PID自动模式用PI参数从松到紧逐步整定最后才投入无负压保护逻辑和远程监控。一个常见的返工原因是进水电动阀与水泵启动的时序问题。正确的时序应该是先开进水电磁阀和补水电动阀等到稳流罐和水箱液位都达到启动条件后再启动水泵。如果水泵先启动而进水阀还没打开稳流罐里的水会被迅速抽空产生剧烈负压真空抑制器还没来得及打开管道可能已经发生气蚀。这个时序在PLC程序里必须明确写清楚不能依赖操作工手动操作。另外一个返工原因是倒流防止器的安装方向装反。倒流防止器有严格的水流方向指示装反后不仅起不到防止回流的作用还会因为内部弹簧和阀瓣的结构导致过流能力大幅下降流量一大就在此处憋压进水压力表读数虚高控制系统误以为市政压力充足实际流量却供应不足。这类机械安装问题往往比软件Bug更难排查。写在最后我的一点实际体会箱式无负压供水系统是一个典型的机电一体化项目原理上不复杂但要做到长时间稳定运行光靠会写几段代码是不够的。我自己最大的体会是先把物理过程想明白再去写逻辑。进水压力、出水压力、流量、液位、频率这几个变量之间的关系是什么它们的动态响应时间常数分别有多大这些搞清楚了代码只是把这层理解表达出来而已。反过来如果只盯着状态图和PID公式很容易做出一个“纸面上很完美、现场三天两头出问题”的控制系统。真要给后来者一条最务实的建议那就是仿真和现场永远有距离。Python仿真调好的PID参数到了现场很可能要改一版因为现场管道、阀门、滤网的真实阻尼和模型里差异很大。所以务必要在HMI上把PID参数开放给调试人员不要写死在程序里否则每次调参都要重新下载程序既危险又低效。把这套逻辑和流程走通之后再看市面上的箱式无负压产品基本都能一眼看穿它的设计意图了。
RELATED READING

延伸阅读

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