PLC污水处理自动化实战:从工艺拆解到组态王画面开发 我接触PLC污水处理这个方向最早是因为一个关于小型污水处理站的自动化改造项目。当时客户提的需求很明确工艺上要能自动运行监控上位机要用组态王做动画界面交付物要包含PLC源代码、组态王源代码、电气图纸和完整的IO地址分配表。这几乎就是把一套可落地的方案摊开在你面前。后来这个项目做下来我最大的感受是技术难点其实不集中在某一个环节而在整条链条——从工艺逻辑拆解到IO点表设计再到程序结构和组态画面的联动每一环都容易踩坑。今天这篇文章我打算把自己做这套系统的完整思路复盘一遍包括工艺流程怎么拆、PLC选型怎么定、IO地址怎么分配才能方便后续维护、程序逻辑里哪些联锁必须做、组态王画面怎么设计才有“仿真感”以及在调试阶段遇到的几个真实问题和排查过程。无论你是做污水自控项目刚起步的工程师还是准备拿类似课题做毕业设计或竞赛作品的学生这篇内容应该都能直接用得上。1. 污水处理工艺与控制需求拆解做任何一套控制系统第一件事不是打开编程软件而是先把工艺吃透。组态王和PLC都只是工具真正决定程序怎么写的是这套污水系统到底怎么运转、哪些设备需要联动、哪些参数需要参与闭环控制。1.1 这套系统的工艺主干我们当时做的是一个小规模的市政污水提升与生化处理单元工艺路线大致是集水井提升泵 → 格栅渠粗格栅 → 调节池 → A/O生化池 → 二沉池 → 消毒接触池 → 达标排放。此外还有污泥回流和剩余污泥排放两条辅助管路。设备清单包括提升泵、粗格栅除污机、潜水搅拌器、鼓风机给好氧池供氧、污泥回流泵、剩余污泥泵、加药计量泵用于除磷或消毒、电动阀门若干以及液位计、pH计、溶解氧DO探头、电磁流量计等仪表设备。这套流程放在PLC控制里可以简化成几个控制单元1.2 控制任务清单集水井泵站控制根据集水井液位自动启停提升泵高液位启动、低液位停止防止泵空转或溢流格栅控制根据格栅前后液位差或定时时间自动运行除污机无人值守时以时间为准是更省心的方式生化池供氧控制根据好氧区溶解氧浓度对鼓风机进行启停或台数控制如果要求再高一些可以做变频调速但这里用异步电机多台启停控制就够了污泥回流控制回流泵按运行时间和设定的启停周期循环切换防止污泥沉积加药控制按流量比例或定时定量投加药剂涉及流量计读数参与计算消毒控制紫外线消毒设备随系统出水阀联动投入。我习惯在动手设计PLC程序之前先画一张表把设备和对应的控制条件列清楚。比如提升泵控制条件动作说明集水井液位 ≥ 高液位 2.5m启动1#提升泵液位信号来自静压式液位计集水井液位 ≤ 低液位 0.8m停止1#提升泵带低位保护防止空转1#泵故障自动投入2#泵两台泵互为备用2#泵故障且1#泵未投报警并停止进水防止集水井溢流这种控制表写清楚之后后面写PLC程序、做组态王变量、画电气图纸就都有依据了。不要嫌这一步麻烦我在调试时见过太多项目因为前期逻辑没理清程序写了两版甚至三版返工成本远高于前期梳理成本。1.3 手自动三种模式怎么设计才实用很多初学PLC的朋友喜欢把程序直接写成纯自动逻辑但实际项目里运维人员非常依赖手动模式。我们的系统在每个设备上设置了“本地/远程”硬切换在PLC内部还做了“手动/自动”软切换本地模式设备由现场控制箱按钮直接控制PLC不做任何干预电气检修时用远程手动模式设备由中控室组态王画面点按钮操作PLC只负责执行命令并反馈状态适合调试阶段或异常工况下人工干预远程自动模式设备完全由程序依据液位、时间等条件自动控制运行稳定后交给这个模式。这个设计的核心原则是设备的启停控制权限在同一时刻只能掌握在一处必须通过硬编码的互锁逻辑来保证而不是只靠组态王脚本。这是安全底线。2. 硬件选型与IO地址分配硬件选型听起来好像很简单——按点数估一个PLC就行。但实际做下来IO地址分配才是影响后面所有工作程序、组态、图纸、接线的核心。地址分配得合理程序写起来顺手查线也轻松分配得乱调试时能从上午找到晚上。2.1 PLC选型背后的逻辑我当时的选型思路是这样的先列IO需求表再反推CPU和模块配置。从工艺清单来看开关量输入DI液位开关高/低报警、各设备的运行反馈、故障反馈、手自动切换信号、远程就地切换信号、电动阀开到位/关到位反馈等粗算约20点开关量输出DO各电机启停接触器、电动阀开门/关门指令、指示灯/蜂鸣器输出等约16点模拟量输入AI集水井液位、调节池液位、pH、溶解氧DO、进水流量、出水流量、消毒池余氯等约6路模拟量输出AO加药泵频率给定、鼓风机变频给定等按需求预留2路。核心计算原则是CPU的I/O能力要预留20%-30%的余量模拟量模块要按实际通道数选型并预留备用通道。综合下来选用了一款中小型PLC搭配两块DI模块、一块DO模块、一块8通道AI模块再选一个通信扩展接口用于连接组态王。提示确定PLC型号时多问自己一个问题——后期要扩展的IO多不多如果大概率要加设备就选CPU本体扩展槽位多一些的型号别在这个地方省成本。2.2 IO地址表格怎么排才算“会排”IO地址分配这门手艺说实话很多文章都不细讲但实际项目里它是让大家最头疼的。我分享一个自己的习惯按“信号类型工艺单元”两个维度来分组。常见的错误做法是拿到点表就从I0.0按序列下去设备之间毫无逻辑可言。这样的结果是到现场查故障时你得对着图纸翻半天才能定位一个中间继电器。而我推荐的方式是同一工艺单元的设备连续编组例如集水井的提升泵1#、2#放在一组格栅除污机单成一组鼓风机这两台放一起泵类设备的DO运行指令对应的DI运行反馈尽量放在相邻地址程序阅读时一目了然模拟量通道按仪表所在工艺位置顺序分配例如AI0.0接集水井液位AI0.1接调节池液位AI0.2接pH计……每个通道在下线槽里挂标签明示避免接线错误。以提升泵为例我们实际的分配片段地址名称信号类型接线图端子说明I0.0集水井液位高位开关DIX1-01高液位报警输入I0.1集水井液位低位开关DIX1-02低液位停泵保护I0.21#提升泵运行反馈DIX1-03接触器辅助触点I0.31#提升泵故障反馈DIX1-04热继电器信号I0.42#提升泵运行反馈DIX1-05接触器辅助触点Q0.01#提升泵启动指令DOY0-01中间继电器→接触器Q0.12#提升泵启动指令DOY0-02中间继电器→接触器AIW0集水井液位4-20mAAI模拟量输入卡0通道量程0-5m注意DI反馈类型要区分是“运行反馈”还是“故障反馈”这两者在PLC程序中的处理方式完全不同。运行反馈用于状态显示和设备保护故障反馈则是硬报警信息通常还要在组态王画面里做闪烁和声光提示。2.3 出图时容易忽略的三个细节电气图纸是整个交付包里的另一条腿。这边的图纸通常包含三部分主回路图电机的电源回路、接触器、热继电器、控制回路图PLC输出点→中间继电器→接触器线圈、端子接线图PLC模块端子与现场设备的对应关系。画图时有三个细节非常值得留意每个PLC数字量输出点都要经过中间继电器中转绝不能直接用PLC输出点驱动接触器线圈因为接触器线圈的浪涌电流容易冲击PLC输出晶体管或继电器触点缩短模块寿命模拟量信号必须注明信号类型和量程范围如4-20mA对应0-5m这样不仅接线的师傅不会接错组态王里变量的原始值范围也有据可依接地端子的标注不能省模拟量仪表电缆的屏蔽层必须单端接地图纸上要能体现。这三条看着不起眼却是实际调试中排查问题的关键线索。我在现场见过不少项目因为忽略中间继电器导致PLC输出模块反复烧坏的情况排查到最后发现是端子排上少画了一个续流二极管。3. PLC程序核心逻辑设计附源程序思路PLC程序是整套系统的大脑。下面我把程序结构从上往下拆开讲这也基本就是源代码的架构骨架。有PLC基础的朋友可以直接照这个思路搭出第一版程序。3.1 程序整体框架我把程序划分为三个主程序段加若干子程序初始化程序上电后复位所有输出状态、把组态王远程指令标志位清零、装载初始设定参数定时器时间、液位联锁门限模式切换与手自动控制程序处理远程/本地切换、手动指令的执行与锁定自动联锁程序处理液位、溶解氧、时间相关的判断逻辑输出到设备启停变量报警处理与通信数据区刷新程序把各类报警汇总输出到组态王可读的数据区同时周期刷新设备状态。实际上很多工程师习惯把所有逻辑写在一个主程序里程序短的时候没问题但系统一复杂就会变得难以维护。结构化编程的好处是故障定位快——假如风机不启动你先去查“自动联锁程序”中风机那一段的条件再去查“模式切换”中是不是处于自动状态很快就能定位。3.2 自动联锁逻辑的核心写法以提升泵两台自动切换为例源代码的核心逻辑可以这样描述// 提升泵自动控制逻辑 IF 集水井液位 高液位 THEN 当无泵运行且无故障时启动当前工作泵 END_IF IF 集水井液位 低液位 THEN 停止所有在运行的提升泵 END_IF IF 当前泵故障 THEN 停止该泵启动备用泵 END_IF这里有一个很多初写程序的人容易犯的错误直接用一个通电延时定时器做泵的轮换而没有考虑“故障在泵启动瞬间是否已经存在”这种边界条件。由于电机启动电流大接触器冲击如果反馈信号取的是接触器辅助触点那么启动瞬间会出现短暂的“运行反馈为0”状态程序必须加一个“启动延时确认”的扫描窗口而不是一看到反馈为0就立刻判故障。这个窗口通常设置3-5秒。另外高液位和低液位的判断建议用模拟量加比较指令而不要只依赖液位开关数字量。原因在于模拟量可以做中间死区处理避免液位波动导致泵频繁启停而液位开关只有ON/OFF两种状态在临界点附近可能会反复抖动。3.3 模拟量工程量转换公式模拟量通道采集到的原始值是一个数字量例如S7-200 SMART系列的AIW是0-27648组态王能直接读取变量但要想显示真实液位还是要做一次工程量转换。转换公式是工程量 (原始值 - 偏移量) ÷ 量程数字量跨度 × 物理量程范围 物理下限以4-20mA对应0-5m液位为例假设原始值范围0-27648对应4-20mA液位 (AIW原始值 - 5530) / (27648 - 5530) × 5.0为什么要强调5530这个数因为很多模拟量模块在4mA时读到的原始值并不是0而是在满量程的约20%处。如果直接用“原始值÷27648×5”零点就会偏很多显示值虚高。这段转换我倾向于放在PLC程序里做一次然后把运算结果真实工程值放到组态王变量的连接区而不是让组态王去做二次计算。这样组的变量更直观调试时也能在PLC侧监控判断仪表本身准不准。3.4 设备互锁与保护逻辑设备互锁是最能体现工程经验的地方。比如鼓风机启动前必须确认对应好氧池的潜水搅拌器已在运行避免局部曝气不均加药泵只有在其对应的进水调节阀打开后、且有流量信号的情况下才允许启动防止药剂投加到干管道里。还有一条关于电动阀的逻辑开阀和关阀两个输出必须做互锁严禁在程序逻辑中同时输出开和关两个指令。我在接线图上为每个阀加了单独的中间继电器在PLC程序里再写了一道软互锁双重保护。这属于“用不到的时候感觉多余、一旦误操作就救命”的设计。4. 组态王动画仿真画面开发组态王KingView这部分可能是很多人觉得“最难”的地方——因为画图容易画“会动”的画面才是核心难点。这里我按数据词典、画面组织、动画连接、命令语言四个层次来拆。4.1 数据词典是画面的“变量中枢”组态王的数据词典里需要定义两类变量IO变量与PLC通信交换数据变量名要和PLC侧一致。比如在PLC程序中设定VW100为提升泵运行状态字那么在组态王数据词典中就要新建一个整数变量“提升泵状态字”对应设备地址VW100。组态王会通过通信驱动周期性读写这个地址内存变量仅保存在组态王内部不参与PLC通信。这类变量多用作画面内部的切换标志位、变量颜色变化中间量等。有一点必须提醒数据词典变量的寄存器地址一旦确定不要随意改动。因为PLC程序、组态画面、报警设置、趋势曲线全都依赖这个变量名。当然如果非要改最稳妥的方式是在PLC程序里用“传输变量区”做二次映射这样上位机变量地址可以保持稳定而PLC内部逻辑调整时不会影响组态画面。4.2 几个核心动画效果怎么做组态王画面里最常用到的几种动画效果我逐一说明实现方式水池液位动态变化画一个水池轮廓用矩形填充动画连接选择“模拟值”对应液位变量设置好数值范围和填充方向从底部向上填充。难点在于填充量的百分比要与液位量程对齐否则画面显示比例和实际液位不符。我的做法是专门在数据词典里建一个“液位百分比”内存整数变量由单片机逻辑或组态脚本计算好百分比后再填到动画连接里管道液体流动效果组态王支持线条的颜色或可见性动画。你可以在管道线上绘制一系列小线段通过一个0-100的“流动偏移量”变量来控制这些小线段的可见性顺序变化视觉上就像水在流动。这个效果不复杂但很出彩泵/风机旋转动画用一个圆形齿轮图片动画连接“旋转角度”。如果PLC或脚本每周期给角度变量叠加一个固定增量画面里的齿轮就会转起来。要控制转速只需要调控增量和画面刷新周期报警闪烁用“可见性”连接报警变量同时配合一个周期变化的内存变量控制颜色闪烁。报警发生时红色亮起变量在0/1间周期性切换画面就会一闪一闪的非常醒目。我在搭这套画面时发现一个细节组态王画面分辨率和运行时的桌面分辨率如果不匹配动画位置会整体偏移。所以工程里可以给画面底图设置固定大小并开启“画面缩放”功能或者干脆按目标显示器分辨率去设计底图尺寸。4.3 命令语言脚本与仿真演示组态王的命令语言脚本是实现交互的关键。比如在画面中添加“自动/手动”切换按钮// 切换按钮的命令语言左键按下时触发 自动模式标志 1 - 自动模式标志 // 置反标志位当画面处于仿真演示模式没有连接真实PLC时还可以写一个“模拟液位源”脚本用随机数或正弦函数模拟液位缓慢上升和泵抽水下降的过程。这样整个画面就“活”起来了。但这里要强调仿真脚本只用于演示完整状态不要影响真实IO变量的写操作。具体做法是把模拟状态和真实状态通过一个“仿真使能”内部变量分开互不干扰。4.4 画面之间跳转与变量传递一套完整的组态王画面通常不止一页。我会把它们组织成总览画面全厂工艺概览一眼看见所有设备状态泵站细览画面集水井、提升泵机组、液位曲线生化单元画面曝气池DO值、风机运行组态报警历史画面与实时趋势曲线窗口画面之间的跳转用“画面切换”按钮实现按钮的命令语言是ShowPicture(泵站细览);变量名和画面名要保持规范否则画面调用时找不到对象。另一个常见问题是画面从A跳到B再跳回A时A上的一些动画不见了——这是因为画面画面被关闭再打开后变量重新初始化连接关系没有完美恢复。解决办法是尽量避免频繁切换画面多使用“窗口叠加显示”的功能或者在每个画面打开命令中重新初始化需要的变量。5. 调试现场记录的四个真实坑点这一部分是我最想在文章里分享的内容。调试过程是项目中最耗时也最涨经验的环节遇到的所有问题基本都在通信、干扰、逻辑边界和画面连接这几个类别里。5.1 组态王与PLC通信不上先从这里查刚做完画面打算连PLC时组态王显示“通信失败”这是我们第一次调试遇到的第一个挡路石。我的排查顺序是检查PLC通信端口参数波特率、数据位、停止位、校验位是否与组态王设备配置完全一致组态王默认是9600,8,1无校验PLC侧如果默认是19200或者偶校验必然连不上检查COM口号是否被其他程序占用组态王和老版PLC编程软件同时开着COM口冲突是常见问题检查PLC驱动选择是否正确——组态王里有专门的PLC驱动列表选择“Modbus TCP”和选择“某品牌专用驱动”虽然最终可能都能通信但数据地址的偏移规则可能不同地址对不上也会通信失败。这里建议上位机与PLC的通信参数做成一张表挂在项目文件夹里避免三个月后再看项目时忘了当初设的是什么。5.2 液位波动导致泵频繁启停加了死区才解决这个问题的现象是调试期间提升泵在几分钟内频繁启停接触器不断吸放。原因是集水井液位信号在临界点附近小幅抖动导致液位值反复跨过高/低阈值。解决办法是典型的“死区控制”思路和原来的单一启泵阈值不同改为启泵“高液位”阈值设为2.5m停泵“低液位”阈值设为0.8m两个阈值之间保持1.7m的死区带液位只要不超过高阈值即使在这个区间内波动也不会触发启动类比来说这就像空调温度控制器的“±1℃温差”没有死区控制系统就会一直抖。有条件的还可以在程序里做模拟量滤波取多次采样平均或采用一阶惯性滤波但这里提醒一下滤波时间常数不能太大否则液位快速上升时泵启动会严重延迟可能造成溢流风险。我们在现场最终采用“滑动平均滤波取样周期1秒、取5次平均”效果最稳。5.3 组态王变量类型不匹配造成的显示异常组态王画面连好变量后液位显示是负数、设备状态怎么都不亮这类问题多半是变量的数据类型或标准格式没对齐。比如PLC里用VW存储的液位是带小数点两位的浮点值用两个字表示32位浮点数而组态王数据词典里定义的却是一个16位整数变量结果必然错乱。又比如PLC输出的是16位二进制位串设备状态包组态王却把它当成整数显示是无法直接判断设备是否运行的。我的建议是建立上位机变量表时明确标注每个变量的类型Bool/Byte/Int/Real、读写属性只读/只写/读写、数据长度和量程范围。组态侧的每个IO变量都要和这张表一一对应。5.4 模拟量信号受干扰屏蔽接地解决还有一次在调试中发现pH读数周期性跳变怀疑是仪表故障但就地pH变送器显示正常。后来用万用表测PLC模拟量输入端的信号发现在2mA左右的波动才确定是信号传输环节的干扰。排查下来原因有两处现场信号电缆的屏蔽层在PLC端和设备端都接了地造成“两端接地”反而形成地环路仪表电缆和动力电缆在同一根线槽内并行走线干扰直接从动力侧耦合过来。处理方式是屏蔽层改为PLC侧单端接地仪表侧屏蔽层悬空同时把仪表信号电缆尽量移出动力电缆槽或者加装金属隔离板。干扰问题处理完以后pH信号稳定在了0.1以内。这类问题在污水处理现场非常常见因为现场的变频器、电机启停对模拟量回路干扰很大。6. 把这一整套交付物变成可复用的项目经验这套系统做完之后交付物包括了PLC源程序、组态王源程序、电气图纸、IO地址分配表和多版调试记录。回头复盘最大的收获不是哪一个函数写得漂亮而是整个项目形成了一个可以复用的“模板”。后续再做同类项目时我从工艺拆解到地址分配再到画面开发可以直接沿用这套框架省掉大量重复沟通和设计的时间。6.1 文档比代码更值钱项目交付时我最花心思整理的反而不是程序本身而是三份文档IO地址分配总表把地址、设备名称、信号类型、线号、仪表量程、组态变量名全部列在一张Excel里这是现场查线和后续维护的唯一“地图”控制逻辑说明每一条联锁条件、定时时间、模拟量转换公式都写成文字不依赖代码注释调试记录把每一次异常现象、排查步骤、修改措施按时间记录成表既是对业主的交代也是自己下次做项目的参考。这组文档里能看出工程师的做事习惯。很多项目最终程序能跑通但半年后运维人员想改一个定时时间根本无从下手这才是项目失败的一半。6.2 后续可以往哪些方向扩展这套系统如果后面要做功能升级优先考虑的方向有三个一是增加变频器控制鼓风机从“启停控制”升级为“按DO浓度自动调节转速”节能效果立竿见影二是把模拟量点位扩展为多因子自动加药闭环靠pH和流量信号实时调整加药泵频率三是做远程监控把PLC通过网关接入物联网平台在中控室之外用手机App查看实时运行状态和报警信息。无论往哪个方向扩展底层的IO分配、程序框架和组态变量结构都不用推翻重来这就是前期设计阶段花时间把地基打牢的回报。最后分享一个小技巧整个项目做完我习惯把组态王工程每人一个备份压缩包放在项目文件夹里命名为“日期_版本号”。调试过程中每改一次画面或程序就另存一个版本。这个习惯救了我很多次——有一次画面联动怎么都调不好翻回三天前的版本一对比立刻发现是一处脚本变量被后来加的功能误改了。版本控制对单人开发也同样重要因为你的记忆永远没有磁盘记录可靠。