简介:面向水厂自动化监控场景的西门子WinCC项目工程包,适用于需要快速搭建蓄水池与水井集中监控画面的工程师和技术人员。项目围绕两个蓄水池和六个水井展开,包含水位、压力、PH值等关键参数的动态显示、趋势记录和报警提示逻辑,可直接导入WinCC查看并复用。
资源包共470个文件,压缩包约191.32MB。除核心的33个PDL画面文件外,还包含rpl、sav、mdf/ldf、csv、cfg/dat等工程运行所需的记录、归档与配置文件,整体结构完整,便于理解WinCC工程的组成和运行机制。已有1768人学习下载,适合工业HMI开发入门及供水行业项目参考。
内容上涵盖蓄水池和水井的监控画面组态、模拟量显示与脚本联动处理,例如低水位自动启动补水泵、高水压关阀等自动化逻辑,同时包含WinCC_OnlineTrendCtrl趋势记录及与PLC通信的相关配置,能够帮助读者掌握从画面绘制、变量连接到报警设置、历史数据归档的完整流程。压缩包内20191023HMI文件名对应项目目录,可对照学习。
1. 水厂的WinCC画面:先别急着画图,先想清楚它在监控系统里到底干什么
打开任何一家水厂的中控室,能看到的那一整墙监控画面,大概率就是WinCC做的。水厂制作的WinCC画面,本质上不是“画图”,而是把现场仪表、泵阀、工艺管线、报警状态完整地“翻译”到中控室的屏幕上,让运行人员不看现场也能知道哪台泵在转、哪个池子液位偏高、哪台加药泵频率掉了。很多新手拿到水厂项目的第一反应是打开图形编辑器拖几个泵、拉几条管线,调颜色调得兴高采烈,结果现场调试时发现变量连不上、设备启停没反应、切换画面卡顿,整晚都在找原因。真正决定画面死活的是变量管理和脚本逻辑,画面外观只是皮。这篇文章我按自己做水厂监控项目的经验,把从工艺理解、工程搭建、脚本设计到现场避坑的完整路径讲清楚,适合正在做水厂自动化集成的工程师、维护老旧水厂监控系统的运维人员,以及想用WinCC做水厂课题的学生参考。
2. 做水厂画面先懂水厂:从工艺段反推画面结构
2.1 水厂工艺流程拆出的四类监控场景
WinCC画面服务于工艺,不懂工艺就画不出能用的画面。常规市政水厂的流程大致是:取水→加药→絮凝沉淀→过滤→消毒→清水池→送水泵房→管网。按监控对象可以拆成几类场景。
第一类是泵组监控,分布在取水泵房和送水泵房。取水泵房关注吸水井液位、水泵启停状态、运行电流、出口流量;送水泵房关注出厂压力、瞬时流量、变频器频率。这类画面的核心是“启停操作 + 状态反馈 + 运行参数显示”,画面结构最标准。
第二类是加药系统。次氯酸钠、聚合氯化铝这类药剂通过计量泵投加,监控点包括药罐液位、计量泵运行状态、投加速度(频率)、余氯值。加药间往往是水厂事故高发区,液位报警和泵故障状态必须做得显眼且可靠。
第三类是池体与滤池系统。沉淀池关注排泥阀、刮泥机运行状态、出水浊度;滤池关注反冲洗流程,一套完整反洗包含气冲、水冲、停冲多个阶段,每一步都有阀门组合状态,容易出错。
第四类是水质与清水池参数。余氯、浊度、pH、清水池液位,这些值不参与频繁操作,但要显示在总览画面和报表中,并且要写成历史趋势供运行人员复盘。
2.2 画面分组与页面层级:总览、单体、设备三级结构
做过两三个水厂项目后,我一般固定使用三级页面结构,这也是大部分集成商的通行做法。
第一级是厂区总览:一张全厂流程图,把取水、加药、沉淀、过滤、送水几个工艺段串成一条流程线,每个工艺段用一个区域框起来,显示该区域最关键的三四个参数,比如流量、液位、出口压力。点击区域框可以跳到对应工艺段画面。
第二级是工艺单体画面:每个单体工序一张画面,显示该工序内所有设备和仪表。比如“沉淀池及滤池”画面里画两座沉淀池、四组滤池,每个池体的阀门、刮泥机、浊度仪都放在对应位置。这一级画面是操作最频繁的,双击设备可以弹出单体控制面板。
第三级是设备详情:这个在WinCC里通常做成弹出窗口或子画面,针对单台泵或单台阀门显示启停按钮、状态、电流、频率,有时还带一小段实时趋势。没必要每个设备都单独占一张大画面,一层层点下去效率太低,弹出面板的方式更符合运行习惯。
2.3 在动手前先整理的一张点位表
很多新手的翻车现场是从“先画图、后补变量”开始的。画完一张漂亮的工艺图,然后对着图一个个补Tag,补到一半发现某个变送器的量程不知道、某个阀门的反馈地址跟PLC侧对不上,返工量非常大。
我的习惯是先做点位表,再动画面。点位表不一定要很正式,Excel里按下面结构列清楚:位号名称(WinCC里的变量名)、对应PLC地址(DB号.字节.位或DB号.字偏移)、数据类型、量程下限、量程上限、工程单位、显示用小数位、是否参与报警、是否参与趋势。
| 位号名称 | PLC地址 | 数据类型 | 量程下限 | 量程上限 | 单位 | 报警 | 趋势 |
|---|---|---|---|---|---|---|---|
| FIC_101_取水瞬时流量 | DB20.DBD4 | 浮点数 | 0 | 5000 | m3/h | 否 | 是 |
| LIA_201_清水池液位 | DB21.DBD12 | 浮点数 | 0 | 6.5 | m | 高/低 | 是 |
| M_102_取水泵运行状态 | DB30.DBX0.0 | 二进制 | — | — | — | 否 | 否 |
| AIC_301_出厂余氯 | DB22.DBD0 | 浮点数 | 0 | 5 | mg/L | 低 | 是 |
这张表整理完,有几个好处:后续建变量时可以按这个表批量导入,而不是一个个手动敲;交给PLC调试人员核对地址时一目了然;画面上每个显示控件引用哪个变量不会犹豫。点位表里的“报警”列和“趋势”列一定要在项目初期就填好,不要等到画面做完再补,否则报警限值、归档周期后期改起来非常费劲。表里的名称建议全部用大写字母和下划线,避免WinCC脚本里出现大小写混用的小毛病。
3. WinCC工程搭建与画面绘制:把工艺级架构落进工程
3.1 新建工程与连接设置:先定变量管理再谈画
打开WinCC项目管理器,新建一个单站项目或者多用户项目,这取决于水厂中控室有几台操作员站。多数中小水厂是单站或双站冗余,单站项目就够用,双站建议直接做多用户项目并把归档数据库放到服务器上。
第一步是配置通信通道。在变量管理里添加一个连接,选对应PLC的驱动,例如S7协议族的TCP/IP通道,填入PLC的IP地址、机架号和槽号。这里有一个重要的经验:如果后期可能改地址,每个PLC单独建一个连接,变量全部挂在连接下面,将来改IP只改连接属性里的IP地址一个点,所有变量自动跟着走。不要为了省事把几个PLC的数据混挂在一个连接下,出问题时会让你怀疑人生。
做水厂项目时,我习惯在变量管理里按工艺段建变量组:Pump_Set(取水泵区)、Chemical(加药区)、Filter(滤池区)、ClearWater(清水池区)、SendWater(送水泵区)。每组下面放对应的变量,这样不仅结构清晰,批量导入变量时也方便。
如果是新项目,可以先在空工程里用导出的变量模板整理好Excel,再一次性导入。CSV结构大概长这样:
# WinCC变量导入模板(示意,列顺序以本机导出的模板为准) # 变量名, 变量组, 数据类型, 连接名称, 地址 FIC_101_取水瞬时流量, Pump_Set, 浮点数变量, PLC_1, DB20.DBD4 LIA_201_清水池液位, ClearWater, 浮点数变量, PLC_1, DB21.DBD12 M_102_取水泵运行状态, Pump_Set, 二进制变量, PLC_1, DB30.DBX0.0 P_301_出厂压力, SendWater, 浮点数变量, PLC_1, DB22.DBD4这个文件要注意几点:列顺序不能自己定义,WinCC的导入向导会按它自己的约定解析,所以务必先在空工程里导出一份模板,照模板的列结构填;地址列里的DB号必须以DB开头,布尔量要写DBX,字和浮点数写DBD;连接名称必须和工程里已经建立的连接名完全一致。导入完成后不要马上画图,打开变量管理抽查十几个变量的地址和数据类型,确认无误再进图形编辑器。
3.2 用标准库对象而不是每个画面手绘
WinCC的画面编辑器里自带一套对象库和面板库,但很多初学者不知道用的重要性。水厂画面里的泵、阀门、电机、液位罐、管道,如果都从多边形、矩形开始手绘,画一张工艺图要一两天,而且风格不一致,后期修改一个符号要改几十处。
常见做法是先把常用设备做成“模板对象”。泵可以做成一个包含“圆+文字标签”的组合对象:运行时状态用颜色区分——绿色运行、红色停止、黄色故障、灰色无通讯;阀门用两个三角+方块组合,开状态显示绿色、关状态灰色。把这些组合对象加进库,后续所有画面从库里拖出来改标题和连接变量即可。
水厂画面里大量出现重复设备,比如四组滤池、五台送水泵,强烈建议把单个设备做成一个面板类型(Faceplate类型),预留一个“结构变量”接口。用面板类型的好处非常多:改量程、改颜色逻辑、加报警闪烁,只动模板本身,所有引用此模板的画面自动更新。我在V7.x项目里用这种办法,后期画面上甲方要求的改动基本能在半天内完成——这点后面章节会单独展开。
还有一个细节:画面上不要用大面积的渐变色背景,更不要用高分辨率位图当底图。工业组态画面要求简洁清晰,运行人员在中控室看一天屏幕,花哨的背景除了让画面加载变慢、让视觉疲劳加重之外没有别的好处。管线用粗线加不同颜色区分介质,水线用蓝色、药线用绿色、排污管线用褐色,图例固定放画面角落。
3.3 写画面组态的过程管理约定
一个水厂WinCC项目通常有几十张画面,如果不做命名约定,后期找画面能找崩溃。我的画面命名规范是:总览画面命名为Overview_Plant,工艺单体画面用“数字_工艺段名_Page”这种格式,例如20_TakeWater_Page、30_Chemical_Page、40_Filter_Page,弹出窗口用Popup_开头。命名与变量管理里的变量组编号对应,任何人接手都能快速定位。
画面之间跳转用画面窗口,而不是直接切页。这个经验很关键:直接在“画面编辑器”里切换整个桌面画面,WinCC会销毁旧画面并重建新画面,过程中的闪烁和加载延迟在水厂这种设备密集的流程画面上特别明显。用画面窗口时,主画面只放一个大的PictureWindow控件,通过SetPictureName函数切换内部画面,这样可以实现平滑过渡,也方便做返回上一级的导航。导航条建议放在画面顶部或左侧固定区域,包含“工艺总览、取水加药、沉淀过滤、清水池送水”几个常用页签,运行人员点一次鼠标就能到达任意工艺段。
画面做完后,还要做一次静态自检:打开图形编辑器里每个画面的“对象列表”,看看是否有对象引用了不存在的变量名。WinCC的变量引用在编译时偶尔会漏报,这类问题只能靠逐个检查或直接在画面上放一个变量状态测试窗口来验证。
4. 水厂画面的关键逻辑:从显示到能用的脚本设计
4.1 设备启停与状态反馈:别把“命令”和“反馈”画成一个点
水厂画面上的泵和阀,按钮和状态反馈是两回事,这一点很多新手会混淆。画面上一个泵既显示“运行”又让操作员可以在上面点击启停,那就等于把命令和反馈连成了一个点,出错时根本分不清是设备没响应还是画面没刷新。
我的做法是:泵或阀的图形对象只显示状态,用颜色区分运行/停止/故障,不绑定任何鼠标操作;旁边单独放一个“操作面板”按钮,点击后弹出一个小弹出窗口,上面才是启停按钮、模式切换和当前状态文字。这样运行人员操作意图明确,画面逻辑也清晰。
按钮启停脚本老生常谈,但我要强调:画面侧只负责“发出命令”,不要做“命令自复位”。常见做法是按钮的“鼠标点击”事件里只把启动位或停止位置为1,至于这个位什么时候复位,交给PLC程序处理。WinCC的C脚本如下:
#include "ap_defs.h" void OnClick(char* lpszPictureName, char* lpszObjectName, char* lpszPropertyName) { // 启动指令:只置位,不复位 if (GetTagBit("M_102_取水泵运行状态") == FALSE) { SetTagBit("M_102_取水泵启动命令", TRUE); } }这段脚本的逻辑说明:先读取“运行状态”是FALSE时,才把启动命令置TRUE,避免在泵已运行时再次误发启动指令。注意SetTagBit的参数是变量名字符串,第二个参数用TRUE或FALSE。WinCC的脚本运行在画面进程里,它跟PLC的通讯通过变量管理后台完成,不存在“按钮按下瞬间”和“PLC扫描到”同步的问题,因此用户比较容易忽视脉冲竞争风险。所以我坚持一个约定:画面只置1,PLC里用这个位做上升沿,然后在PLC侧做一个定时自复位段。如果不需要泵频繁启停,也可以直接在PLC程序里用一个“置位→延时2秒→复位”的脉冲电路,现场跑起来既稳定又不会发生WinCC和PLC同时写一个位导致的冲突。
4.2 备用泵切换与联动:用C脚本做条件判断
水厂常用一用一备或两用一备的泵组配置。备用泵的自动切换,常规思路是放在PLC里做硬逻辑,但有时候甲方要求在中控室也可以切换“手动优先/自动联锁”模式,或者仿真环境里没有真实PLC,需要靠WinCC侧脚本模拟。给一个简单实用的备用泵自动切换脚本,放在全局脚本的“动作”里,设为周期执行。
#include "ap_defs.h" void AutoSwitchPump() { BOOL bPump1Run = GetTagBit("M_101_1号泵运行"); BOOL bPump1Fault = GetTagBit("M_101_1号泵故障"); BOOL bPump2Run = GetTagBit("M_102_2号泵运行"); BOOL bAutoMode = GetTagBit("M_100_泵组自动模式"); BOOL bSpareStart = GetTagBit("M_102_2号泵启动命令"); if (bAutoMode && !bPump1Run && bPump1Fault && !bPump2Run) { SetTagBit("M_102_2号泵启动命令", TRUE); } if (bAutoMode && !bPump1Fault && bPump1Run && bPump2Run) { SetTagBit("M_102_2号泵停止命令", TRUE); } }参数说明:GetTagBit返回布尔值,TRUE表示位为1。这个脚本的逻辑是“1号泵故障且2号泵未运行”时,发出2号泵启动命令;当1号泵恢复运行后,为避免双泵同时运行,自动停2号泵。两个if之间不加else,因为两个条件可能在同一周期内满足。使用这种脚本前要想清楚:WinCC作为上位机,它的周期执行时间通常设500ms到2000ms,比PLC扫描周期慢得多,做这种联锁存在响应延迟,所以凡是涉及人身安全或设备保护的联动,一律放PLC里做,画面脚本只做辅助性切换、故障提示和运行模式展示。仿真演示或实验环境里用这个脚本足够,真实项目里我会把它作为“软后备”,并且明确告知甲方它不替代PLC逻辑。
4.3 实时趋势与报表留给运行人员的入口
水厂每天交接班要看流量、余氯、浊度、液位的变化,WinCC的在线趋势控件是标配。建趋势时要注意:不要直接在每一张画面上放一个趋势窗口查询历史,那样归档数据和查询压力都很大。做法是单独做一张“趋势总览”画面,用两个趋势控件:一个显示实时数据,刷新周期取1秒或2秒;另一个通过WinCC的在线表格控件查历史归档数据,时间范围让运行人员自己选。
为了减少画面加载负担,实时趋势控件里的曲线数控制在6条以内,曲线多了运行人员也看不清,反而影响判断。每一条曲线要设置独立的颜色、线宽和量程,比如余氯用蓝色、浊度用褐色、清水池液位用绿色。量程设置要匹配传感器量程,否则曲线被压缩成一条直线,毫无可读性。
脚本方面,给运行人员留一个下拉框选择“查询时间范围:1小时/8小时/24小时”,这个功能用VBS脚本做比对C脚本更方便操作对象的属性:
Dim objTrend Set objTrend = ScreenItems("TrendControl1") objTrend.TimeRange = 8 * 60 * 60 * 1000 ' 8小时,单位毫秒这段VBS的逻辑是把趋势控件的TimeRange属性设为2880000毫秒。注意ScreenItems引用的控件名称要在图形编辑器里跟趋势控件“对象名称”保持一致,名称写错不会报编译错误,只会在运行时提示找不到对象。VBS脚本在WinCC里运行时如果属性名或单位不对,最常见的表现就是趋势控件毫无反应,这一点避坑章节还会再提。
5. 水厂WinCC画面避坑:调试期最容易翻车的5个问题
5.1 画面打开慢、卡顿到无法操作
现象:在操作员站上切换工艺画面,转圈转好几秒才显示出来,切换到设备密集的滤池画面时鼠标操作有明显的迟滞感。
原因:一是背景图用了未经压缩的大尺寸位图,WinCC渲染时要对整张图做逐像素绘制;二是画面上的对象数量过多,特别是把每一段管线都做成了带阴影的三维立体对象,系统需要不断重新计算绘制;三是画面里放了太多“可见性动态属性”,每帧都在计算每个对象是否可见。
解决:第一,背景图统一转换成PNG格式,长宽控制在1920x1080以内,文件大小尽量压到1MB以下;第二,管线对象不要加立体效果,工艺画面用平面线条即可;第三,减少可见性动画数量,能用颜色变化表达的状态就不要用“显示/隐藏”两个对象切换;第四,把设备密集的画面拆成多个画面窗口,进入时只加载当前工艺段,不要整张大图一次加载全部子画面。做完这四步,画面打开时间基本能控制在1秒以内。
5.2 改PLC的IP后,整站变量全部断连
现象:现场调试时网络调整,PLC的IP网段从192.168.0.x改成192.168.10.x,WinCC里所有变量都变成灰色,运行画面上的数据全部显示为0或者“#####”。
原因:变量在建立时绑定了通信连接,每个变量的地址表述里包含“连接名称.变量名”,而连接本身存有IP地址。大部分情况下改IP只改连接属性就能解决,但有些项目里做画面的人图省事,直接在变量的地址里写死了绝对地址字符串,改连接后变量地址并没有刷新。
解决:这个问题的正确处理方式是在变量管理里找到对应的连接,右键“连接参数”,把IP地址改成新网段,确认后变量会自动恢复。如果变量绑定的是“绝对寻址”而不是“符号寻址”,需要把所有变量重新指向新地址,工作量大很多。所以做项目第一天就要用“连接+变量名”的结构,不要用绝对寻址。
5.3 切换画面时设备状态闪烁一下才正常
现象:从总览画面切到“送水泵房”画面,泵的状态图标先是全部显示为灰色或停止,过了两三秒才变成正确的运行颜色,每一帧都闪得很明显。
原因:画面打开时,WinCC先绘制所有对象,然后才开始刷新变量的实时值。在第一次刷新到达之前,画面对象用的还是默认值或初始值。如果画面里的状态脚本写在“画面打开”事件里,执行顺序和变量刷新时序不一致也会造成闪烁。
解决:最有效的办法是不直接切整幅画面,改用画面窗口嵌套显示。把工艺画面全部放到PictureWindow里,切换时用SetPictureName替换窗口内的画面,主窗口始终保持不动。另一个辅助手段是给状态颜色属性设置“初始值”,让泵的默认颜色是灰色而不是绿色,至少颜色闪动不至于误导操作员。注意:不要指望用“画面打开”事件里加延时脚本去解决,WinCC的画面生命周期和变量刷新机制决定了这种延时脚本只会让问题更隐蔽。
5.4 脚本写错但不报错,泵启停死活没反应
现象:按钮点击了,变量管理里监控到“启动命令”位一直是0,但脚本检查了一遍没发现语法问题;或者某个脚本在别的项目里是好用的,拷到当前项目就失灵。
原因:WinCC的C脚本编译非常宽松,变量名写错不会被编译器拦下来——SetTagBit(“不存在的变量名”, TRUE)不会报错,它只是在运行时找不到变量,默默返回FALSE。VBS脚本里对象名引错也是一样的情况。还有一种是变量类型不匹配,布尔型变量被当成浮点数写入,值写不进去。
解决:这类问题排查起来像玄学,但实际上有规律。第一,每次写完脚本,先在图形编辑器里点“编译”按钮,编译通过不代表正确,但没有语法错误才能继续排查。第二,打开变量管理器,展开对应变量组,确认脚本里的变量名每个字符都一致。第三,用脚本返回值和弹出提示做快速验证:
#include "ap_defs.h" void OnClick(char* lpszPictureName, char* lpszObjectName, char* lpszPropertyName) { BOOL bResult; bResult = SetTagBit("M_102_2号泵启动命令", TRUE); if (bResult == FALSE) { // 返回值FALSE:变量不存在或写入失败 SetTagText("txt_DebugMsg" , "启动命令写入失败,检查变量名"); } }这段脚本逻辑是把SetTagBit的返回值赋给bResult,写失败时在画面里放一个文本对象“txt_DebugMsg”显示提示信息。调试完成后把这段提示脚本删除,避免交付后运行人员看到调试文本。WinCC运行时有一个“消息队列”视图,里面能看到脚本运行时的部分错误描述,但它记录得很粗糙,不能作为唯一依据。
5.5 最坑的一类问题:脉冲宽度不够,指令发不出去
现象:在画面上点了泵启动,现场设备完全没有动作;检查PLC监控,发现启动命令位确实变化过,但PLC程序里就是没抓到上升沿,或者抓到后动作只持续几毫秒就消失。
原因:这就是前面讲到的脉冲宽度问题。如果PLC侧没做自复位脉逻辑,而画面脚本逻辑是“点一下置1,再点一下置0”,那么操作员点击后,命令位可能保持1的时间极短,恰好在PLC两个扫描周期之间就被其他逻辑复位了。更常见的是画面上有两个脚本同时写同一个变量:一个置位、一个在周期执行里不断写0,后一个脚本把前一个脉冲瞬间吞掉。
解决:把脉冲生成挪到PLC侧。画面只负责把启动信号置位,PLC程序里立即用一个定时器生成2秒自复位脉冲,定时器时间要大于PLC的扫描周期,画面侧不要再去写复位。如果现场工控机因为某些特殊原因必须由WinCC直接保持输出脉冲,那就把置位后的延迟复位也放到同一个脚本动作里,用一个循环语句延时,但这种方法不推荐,因为WinCC的脚本刷新间隔和PLC扫描周期无法严格同步。
6. 交付前的自检清单与一个值得长期投入的优化习惯
画面做完不是终点,交付调试前我一定会做一遍自检。检查项固定就这么几条:第一,每个画面上的位号跟点位表对一遍,特别是报警限值和量程,余氯的低报限、清水池液位的高报限是水厂最敏感的参数,出错了会被运行人员骂几年。第二,操作权限:中控室操作员账号不能有修改画面和变量归档的权限,只给启停操作权限;工程师账号要做密码隔离,密码别写在交接文档里就完事,要由项目负责人单独保管。第三,趋势曲线的时间范围和归档周期:归档存储天数要与项目要求匹配,水厂一般要求保存至少30天,归档空间不够时WinCC会自动覆盖最早数据,这个要提前估算硬盘容量。第四,把画面切换方式统一成画面窗口模式,确认没有直接切换整个桌面的画面跳转残留。
长期值得投入的一件事,是把所有画面里的泵、阀、仪表统一改成面板类型,并且把每个设备对应的结构变量定义在变量管理里。这个过程投入的时间和精力在项目后期会加倍补回来:甲方提出“把全厂泵的运行颜色改成蓝色闪烁”、或者“所有压力显示加一位小数”时,你只需要改一个模板,全厂几十个同类型对象瞬间全部更新。这个习惯我是在被一个项目折磨过后才养成的——临时改颜色改了十几个画面,改了整整一天,第二天甲方又说还是用回绿色,那种感觉比加班还累。用模板做的话,这类返工控制在半小时以内。希望帮到你。
本文还有配套的精品资源,点击获取