水泵变频恒压控制
1. 设备简介
水泵变频恒压供水是典型的 PID + 变频应用, 广泛应用于市政二次供水、建筑给排水、化工加压、消防稳压、冷却循环、农业灌溉, 是节能降碳改造最常见的场景之一。本案例以小区二次供水泵站 "2+1" 水泵组为对象 (3 台 5.5 kW 立式多级泵, 2 运 1 备, 24 小时轮换), 额定压力 4.0 bar ±0.1 bar, 单泵流量 30 m³/h。通过 PID 算法调节主泵变频器输出, 保持管网压力稳定, 低压时启副泵接力, 高压时硬联锁停机。相比工频恒压方案节能 30% 以上, 同时支持手机远程监控、故障微信推送、物业 SCADA 对接等现代化运维能力。
2. 项目模块组成
- 机械部分: 3 台 5.5 kW 立式多级泵 + 水箱 + 压力罐 + 主/备压力传感器 + 电磁流量计
- 电气部分: 研华工控机 + 汇川 4AD/1616END + 台达 MS300 变频器 × 3 + RS485 转换器
- 软件部分: OB35 PID 中断 + OB30 Modbus RTU 通讯 + OB1 主调度 + FB_PumpPIDCtrl/Scheduler/AlarmManager + DB_PumpStats
3. 机械装配架构
进水从市政水源进入水箱, 3 台水泵并联吸水, 通过汇管接压力罐再到用户管网。主/备压力变送器安装在汇管出口, 4~20 mA 信号接入 PLC。电磁流量计监测总流量用于判定是否需要启副泵。单向阀防止停泵时水倒流, 闸阀用于维护时隔离。
4. 程序架构
OB35 跑 PID 计算主泵频率, OB30 通过 Modbus RTU 对 3 台变频器读/写 (频率给定 / 反馈 / 电流 / 功率), OB1 维护 2+1 状态调度与轮换。报警/能耗等状态数据通过 OPC UA 上传到物业 SCADA 或手机 APP。
5. 硬件选型 BOM
| 品牌 | 型号 | 数量 | 单价 (¥) | 用途 |
|---|---|---|---|---|
| 研华 | MIO-5272 工控机 | 1 | 3,000 | 主控 |
| 汇川 | AM600-4AD (4AI) | 1 | 780 | 压力/流量采集 |
| 汇川 | AM600-1616END | 1 | 850 | DI/DO |
| 台达 | MS300 5.5 kW 变频 | 3 | 2,400 | 水泵变频 |
| 国产通用 | 压力变送器 4-20 mA 0~10 bar | 2 | 320 | 主 + 备 |
| 国产通用 | 电磁流量计 DN65 | 1 | 1,800 | 流量监测 |
| 国产通用 | ISW 立式多级泵 5.5 kW | 3 | 3,500 | 水泵本体 |
| 威纶通 | TK6071iP 7" | 1 | 1,100 | 本地 HMI |
| 研华 | RS485/USB 隔离转换器 | 1 | 180 | Modbus 总线 |
| 明纬 | LRS-150-24 | 1 | 180 | 24V |
6. IO 模块配置
6.1 选择 IO 模块
IDE 项目树 > IO 设备 > 右键 > 添加 IO 设备:
- 从站 1: 汇川 AM600-4AD (4AI 4~20 mA) — 压力/流量采集
- 从站 2: 汇川 AM600-1616END — 启停/运行反馈/水位/指示灯
变频器通过 通讯 > Modbus RTU 主站 添加, 选 RS485 隔离转换器对应 COM 口, 波特率 9600, 3 台变频器分别配置 SlaveId = 1/2/3。
6.2 IO 地址分配
| 地址 | 模块 | 信号 | 用途 |
|---|---|---|---|
| %IW100 | 从站 1 | AI_Press_Main | 主压力 (0~10 bar) |
| %IW102 | 从站 1 | AI_Press_Backup | 备压力 |
| %IW104 | 从站 1 | AI_Flow | 流量 (0~50 m³/h) |
| %IX0.0 | 从站 2 | SB_Start | 启动 |
| %IX0.1 | 从站 2 | SB_Stop | 停止 (常闭) |
| %IX0.2 | 从站 2 | SB_EStop | 急停 (常闭) |
| %IX0.3~0.5 | 从站 2 | Pump[0..2]_Run | 泵 1~3 运行反馈 |
| %IX0.6 | 从站 2 | Tank_LowLvl | 水箱低水位 |
| %QX0.0~0.2 | 从站 2 | Pump[0..2]_Enable | 泵 1~3 使能 |
| %QX0.3 | 从站 2 | HL_Run | 运行灯 |
| %QX0.4 | 从站 2 | HL_Fault | 故障灯 |
| %QX0.5 | 从站 2 | HL_HighPress | 超压灯 |
6.3 IO 用途分工
- PLC 主控: PID + 2+1 调度 + 24 小时轮换 + 能耗统计, 全部在 PLC 内完成
- 模拟量主备: 两路压力独立通道, 差值 > 1 bar 判主故障自动切备用
- Modbus 写入: 频率给定通过 Modbus RTU 写到变频器寄存器 0x2000
- Modbus 读取: 反馈频率/电流/功率/故障码从 0x2103~0x2108 读取
6.4 对接物业 SCADA (如适用)
在 通讯 > OPC UA 服务端 配置暴露点位清单, 物业 SCADA 作为 OPC UA 客户端订阅:
gPump.rPressure: 实时压力gPump.aPumps[0..2].rPower: 各泵瞬时功率gPump.rEnergyKWh: 累计能耗gPump.eState: 系统状态gPump.bHighPressTrip: 超压联锁
物业手机 APP 通过 OPC UA 或 HTTPS 直接读取, 无需二次开发。
7. 核心数据结构
TYPE UDT_Pump:
STRUCT
bEnable : BOOL;
bRunning : BOOL;
rFreq : REAL; // 给定频率 Hz
rFreqFb : REAL; // 反馈频率
rCurrent : REAL; // 电流 A
rPower : REAL; // 瞬时功率 kW
nRunHours : DINT; // 累计运行 (Retain)
nStartCount : DINT; // 启动次数 (Retain)
bFault : BOOL;
nFaultCode : INT;
END_STRUCT
END_TYPE
TYPE UDT_PumpStation:
STRUCT
aPumps : ARRAY[0..2] OF UDT_Pump;
rPressure : REAL;
rPressureSet : REAL := 4.0;
rFlow : REAL;
nMasterIdx : INT; // 主泵索引
nSlaveIdx : INT; // 副泵索引
eState : INT; // 0=idle 1=single 2=dual 3=fault
rEnergyKWh : REAL; // 累计能耗 (Retain)
bHighPressTrip : BOOL;
END_STRUCT
END_TYPE
VAR_GLOBAL RETAIN
gStation : UDT_PumpStation;
END_VAR
8. 核心程序代码
FB_PumpPIDCtrl — OB35 100 ms PID 恒压:
FUNCTION_BLOCK FB_PumpPIDCtrl
VAR
fbPID : PID_COMPACT;
rBak : REAL;
END_VAR
// 压力采集 + 主备冗余
gStation.rPressure := INT_TO_REAL(AI_Press_Main) / 27648.0 * 10.0;
rBak := INT_TO_REAL(AI_Press_Backup) / 27648.0 * 10.0;
IF ABS(gStation.rPressure - rBak) > 1.0 THEN
IF gStation.rPressure < 0.0 OR gStation.rPressure > 10.5 THEN
gStation.rPressure := rBak;
END_IF;
END_IF;
// 超压硬联锁
IF gStation.rPressure > 6.0 THEN
gStation.bHighPressTrip := TRUE;
gStation.eState := 3;
END_IF;
// PID 仅调节主泵
IF gStation.eState = 1 OR gStation.eState = 2 THEN
fbPID(
Setpoint := gStation.rPressureSet,
Input := gStation.rPressure,
Kp := 3.0, Ti := 5.0, Td := 0.5,
OutputMin := 20.0, OutputMax := 50.0
);
gStation.aPumps[gStation.nMasterIdx].rFreq := fbPID.Output;
END_IF;
FB_PumpScheduler — OB1 2+1 状态机:
FUNCTION_BLOCK FB_PumpScheduler
VAR
tonRotate, tonLowPress : TON;
i : INT;
END_VAR
CASE gStation.eState OF
0: // 空闲
IF SB_Start AND NOT gStation.bHighPressTrip AND NOT Tank_LowLvl THEN
gStation.eState := 1;
gStation.aPumps[gStation.nMasterIdx].bEnable := TRUE;
gStation.aPumps[gStation.nMasterIdx].nStartCount :=
gStation.aPumps[gStation.nMasterIdx].nStartCount + 1;
END_IF;
1: // 单泵运行
tonLowPress(IN := gStation.rPressure < 2.0, PT := T#10s);
IF tonLowPress.Q THEN
gStation.aPumps[gStation.nSlaveIdx].bEnable := TRUE;
gStation.eState := 2;
END_IF;
IF NOT SB_Stop THEN
gStation.eState := 0;
FOR i := 0 TO 2 DO gStation.aPumps[i].bEnable := FALSE; END_FOR;
END_IF;
2: // 双泵运行
IF gStation.rPressure > 4.5 AND gStation.rFlow < 20.0 THEN
gStation.aPumps[gStation.nSlaveIdx].bEnable := FALSE;
gStation.eState := 1;
END_IF;
IF NOT SB_Stop THEN
gStation.eState := 0;
FOR i := 0 TO 2 DO gStation.aPumps[i].bEnable := FALSE; END_FOR;
END_IF;
3: // 故障复位
FOR i := 0 TO 2 DO gStation.aPumps[i].bEnable := FALSE; END_FOR;
IF gStation.rPressure < 5.0 AND SB_EStop THEN
gStation.bHighPressTrip := FALSE;
gStation.eState := 0;
END_IF;
END_CASE;
// 24 小时轮换
tonRotate(IN := gStation.eState = 1, PT := T#24h);
IF tonRotate.Q THEN
gStation.nMasterIdx := (gStation.nMasterIdx + 1) MOD 3;
gStation.nSlaveIdx := (gStation.nMasterIdx + 1) MOD 3;
tonRotate(IN := FALSE);
END_IF;
Pump0_Enable := gStation.aPumps[0].bEnable;
Pump1_Enable := gStation.aPumps[1].bEnable;
Pump2_Enable := gStation.aPumps[2].bEnable;
FB_ModbusRTU — OB30 50 ms 写变频器频率 + 读反馈:
FUNCTION_BLOCK FB_ModbusRTU
VAR
fbWrite : MB_WriteSingle;
fbRead : MB_ReadHolding;
i : INT;
END_VAR
FOR i := 0 TO 2 DO
// 频率给定 (寄存器 0x2000, 单位 0.01 Hz)
fbWrite(Port := MB_PORT_1, SlaveId := i+1,
Register := 16#2000,
Value := REAL_TO_INT(gStation.aPumps[i].rFreq * 100));
// 读瞬时功率 (0x2103, kW × 100)
fbRead(Port := MB_PORT_1, SlaveId := i+1,
StartReg := 16#2103, Count := 1,
Target := gStation.aPumps[i].rPower);
END_FOR;
9. 运行与调试
- 仿真 Runtime 验证: 给
AI_Press_Main注入阶跃压力, 观察 PID 输出调整 - 下载到 Runtime: IDE "部署" → 选 Runtime IP → 下载
- 变频器通讯验证: 查看 OB30 日志, 确认 3 台变频器 Modbus 响应 OK
- 强制信号测试: 强制
Tank_LowLvl := TRUE, 验证全部泵立即停机 - 节能调参: 从 Kp=3 开始, 按管网响应微调; 夜间低流量时观察是否频繁启停
- 常见排查:
- 压力振荡 → Ti 太小 (积分过快)
- 长时间无法到达设定 → OutputMax 不够, 或泵出力不足
- 变频器失联 → 查 RS485 A/B 接线 + 波特率 + 终端电阻
10. 用到的 Darra 功能
| 功能模块 | 本案例用到的 | 说明 |
|---|---|---|
| PLC 编程 | SCL + 状态机 + PID_COMPACT + UDT + Retain | IEC 61131-3 |
| 工艺对象 | PID 内置 + 多泵调度 | 无需专用恒压控制器 |
| HMI | 压力趋势 + 泵组状态 + 手机 APP | 多端实时监控 |
| 通讯 | EtherCAT + Modbus RTU + OPC UA | 多协议内置 |
| 数据记录 | 能耗 kWh / 压力曲线 30 天 | 物业按电费核算 |
| 服务 | 终端设备监控 + 故障微信推送 | 物业手机报修 |
11. 项目总结
- 实测指标: 稳态压力 4.00 bar ±0.08 bar, 主备切换 < 1 秒, 能耗比工频方案降低 32%, 连续运行 60 天无意外停机
- 扩展方向:
- 升级双机热备 Runtime (主 PLC 故障自动切备份 PLC, 管网不中断)
- AI 预测性维护: 结合电流/振动趋势, 提前 7 天预警轴承磨损
- 多泵站联网 (物业 50+ 泵站统一调度), Darra Cloud 集中运维