简介:基于WinCC与西门子PLC DP通讯开发的污水处理系统组态源码,面向工控领域的初学者及有一定开发经验的工程师。资源定位于帮助读者快速掌握WinCC组态设计、DP通讯配置及污水处理流程监控的实现方法,包含完整可运行的源代码、界面文件与详细注释,适合作为项目参考或学习模板。压缩包共含728个文件,大小约956KB,涵盖dbf/mdx/dbt数据库文件、pg/pro/s7p组态工程文件、s7h/xdb通讯与硬件配置文件,以及txt/log说明与日志文件,各部分划分清晰,便于按需查阅。目前已有237人学习下载。通过学习这份源码,使用者可以获得从PLC底层数据采集到上位机界面展示的完整链路,理解DP通讯参数配置、数据库表结构组织、画面布局与脚本逻辑等关键技术点,为自主开发类似工业监控系统提供扎实的参考。
1. 污水处理项目为什么离不开 WinCC 和西门子 PLC 的 DP 通讯组态
污水处理厂中控室常有这样的画面:大屏上显示进水流量、溶解氧、泵启停状态,操作员在中控室远程启停鼓风机。支撑这些画面的往往不是以太网,而是 PROFIBUS DP 总线。标题里的"基于 WinCC 和西门子 PLC DP 通讯的污水处理系统组态源码.zip",指的是一套完整工程:STEP 7 硬件组态、WinCC 变量表、画面脚本,以及让两者通过 DP 总线数据打通的通讯配置。
这个问题很具体:污水处理现场电磁环境差、测点分散,DP 通讯比普通仪表电缆可靠。适合刚接手污水厂自控项目的新人、维护老 DP 从站的工程师,以及想拿组态结构做二次开发的人。很多人觉得 DP 过时,但真正处理过工程包的人都知道,DP 的站地址、诊断和变量映射才是组态里最耗时间的部分。
2. 先立骨架:WinCC 与 S7-300/400 的 PROFIBUS DP 通讯组态原理
2.1 PROFIBUS DP 主从机制与 WinCC 变量寻址的对应关系
PROFIBUS DP 是主从轮询式总线。主站一般是带 DP 口的 CPU 或 CP 通讯卡,从站则是 ET200、变频器、智能仪表或另一个 PLC。主站按固定周期循环读取从站输入区,并写入输出区;WinCC 并不直接读懂总线报文,而是通过 STEP 7 组态时分配给从站的 I/O 地址或 PLC 程序里的 DB 块来读取数据。所以拿到一个组态源码包,最先要看的不是画面漂不漂亮,而是 STEP 7 硬件组态里给每个 DP 从站分配的输入输出地址段。
这里最常见的方式是:在 STEP 7 硬件组态里插入从站,系统自动分配 I/O 地址,比如输入从 IW72 开始,输出从 QW80 开始;WinCC 中添加 S7 PROTOCOL SUITE 驱动,选 PROFIBUS 通道,新建连接后,变量地址填 IW72、QW80,连接就能读到数值。很多新手会把外设字节 PIW 和过程映像 IW 搞混。WinCC 的 S7 驱动默认访问过程映像区,也就是不带 P 的 I/Q 地址;如果硬件组态中启用了完全访问或某些通讯卡直接用外设寻址,就要在变量地址里加 P,否则读到的始终是 0。
DP 的参数还要注意站地址、波特率和单段距离。站地址范围是 0 到 126,0 和 1 通常预留给编程器,实际从站一般用 3 到 99。波特率由主站 DP 参数决定,从站自动跟随;波特率越高,单段线长越短。下面是一张在污水厂现场常用的对应表:
| 波特率 | 最大单段长度 | 典型使用位置 |
|---|---|---|
| 9.6~187.5 kbps | 1000 m | 进水提升泵房、厂外泵站 |
| 500 kbps | 400 m | 生化池远程 IO 分站 |
| 1.5 Mbps | 200 m | 鼓风机房到中控室 |
| 12 Mbps | 100 m | 中控室柜内设备互连 |
提示:距离不够时优先加 RS-485 中继器,不要一味降波特率。污水厂中变频器电缆与 DP 线同沟走线是干扰主要来源,屏蔽层必须单端接地,并尽量远离动力电缆。
2.2 STEP 7 硬件组态里的 DP 从站配置步骤和关键参数
在 STEP 7 中配置 DP 从站的常规流程是:打开硬件组态 HW Config,在 PROFIBUS DP 目录下找到从站 GSD,拖到 DP 总线上;然后分配站地址和 I/O 起始地址;编译检查无冲突后下载。以 ET200M 从站为例,I/O 地址输入起始 72、输出起始 80,那么 WinCC 后续变量就填 IW72 和 QW80。GSD 文件必须和从站硬件版本匹配,很多老改造项目里的从站是 V1.0,而新装的 GSD 是 V2.0,两者报文长度不一致会导致从站报错。
对于有模拟量、看起来很复杂的从站,关键在一致性设置。DP 从站的输入输出区可以按字节、字或整个模块定义一致性;当 WinCC 要读取一个 32 位浮点数或一个完整的 ABB 变频器 PZD 报文时,必须把这个数据区设置为整体一致,否则一次轮询可能读到半个字,数值会跳变。ABB 变频器与西门子 PLC 通过 DP 通讯时,PPO 类型选择会直接决定 PZD 字的排列,WinCC 地址必须和 PZD 的偏移严格对应。
如果现场是 3 台变频器做三段速控制,组态思路也类似:每台变频器是一个 DP 从站,控制字、速度给定值、状态字分别在 PZD 区固定偏移。PLC 侧把这些字搬运到 DB,WinCC 再访问 DB。这样做的目的不是省事,而是把总线变量和工艺变量解耦,后续如果要换成以太网,只需要替换搬运程序,画面和变量表几乎不用动。
2.3 WinCC 侧 PROFIBUS 通道的驱动选型与连接参数
WinCC 访问 S7-300/400 的 DP 通讯,常见有三种方式:WinCC 工控机装 CP 5611/CP5621 卡,用 S7 PROTOCOL SUITE 里的 PROFIBUS 通道直接连;通过 PC Station 和 OPC 转发;或者用 WinCC 的 TCP/IP 通道经以太网模块间接访问。污水处理系统里,老项目用 CP 卡直接连 DP 总线最常见,因为延迟低、变量刷新快。源码包里变量管理器的 SIMATIC S7 PROTOCOL SUITE 下的 PROFIBUS 分支里,每个连接对应一个 DP 主站地址和插槽号。
连接参数里有几个容易错的点:站地址填 CPU 的 MPI/DP 地址,机架号默认 0,插槽号默认 2,S7-300 CPU 安装在插槽 2。发送/接收原始数据块不要勾选,除非你在 PLC 里用了 AG_SEND/AG_RECV。WinCC 的 PROFIBUS 通道还要求通讯卡驱动和 STEP 7 版本一致,CP 卡固件不一致时,连接状态会反复显示正在建立。
如果不想让 WinCC 直接挂 DP 总线,也可以用 WinCC 做 OPC UA 服务器,把 DP 数据通过 OPC UA 对外发布。这个做法常用于厂级数据平台,但配置时要额外注意 OPC UA 的端口和用户账号,且 WinCC Runtime 必须启动后 OPC UA 服务器才可用。需要说明的是,标题里的组态源码通常不会把 OPC UA 作为主通讯,它更多是作为上位机监控的备选接口。
3. 把 DP 报文变成 WinCC 变量:污水处理组态源码里的地址映射方式
3.1 DB 块直接映射,比 I/O 区更稳的变量组织
在污水处理项目里,我倾向于让 WinCC 访问 DB 块而不是直接访问 I/Q 区。具体做法是:PLC 程序中把各 DP 从站的输入区复制到固定的 DB 块,WinCC 变量统一指向 DB 块。这样从站地址如果因现场改造变化,只需要修改 PLC 程序里的搬运逻辑,不用在 WinCC 里逐条改变量地址。DB 块还有利于做量程转换、坏值判断和故障字汇总。
WinCC 变量地址的写法是DB块号,DBD偏移,例如DB11,DBD4表示 DB11 中偏移 4 字节开始的双字,数据类型选浮点数。如果从站上传的是两个 16 位整数组成的长字,WinCC 地址同样用 DBD,而不是 DBW。位变量则写成DB11,DBX0.0。偏移量的计算是常见错误源:DBD 每步长 4 字节,DBW 每步长 2 字节,连续排布时错一位就会读到错误的压力值。污水厂工艺上,进水流量和出水流量往往是累积值,最好在 PLC 中用双整数累加后再给 WinCC,避免 WinCC 重连时从 0 重新累积。
模拟量的量程转换也可以在 WinCC 侧做:变量连接原始值,然后在画面脚本里用(Raw / 27648) * (HiLimit - LoLimit) + LoLimit换算工程值。但我不建议这么做,因为在报表和历史归档里,WinCC 归档的是原始值,后期做统计分析还要再做一次转换;直接在 PLC 中把 0~27648 转成 0~1000 m³/h,WinCC 读到的就是工程值,归档和报表都省事。
3.2 用 VBS 脚本批量生成变量表和模拟量处理
源码包里真正省时间的是变量自动生成脚本。做水厂项目时,点位表可能有两三百个模拟量和数字量,如果用手工在 WinCC 变量管理器中逐条建立,既慢又容易漏。常见做法是:用 Excel 维护点位表,列分别是变量名、数据类型、WinCC 地址;导出为 CSV 后,在 WinCC 全局脚本中运行 VBS 批量创建变量。下面是一个最小编程示例:
Dim objCtr, fso, f, line, fields Set objCtr = HMIRuntime.Tags Set fso = CreateObject("Scripting.FileSystemObject") Set f = fso.OpenTextFile("D:\tag_list.csv", 1, False, -1) Do While f.AtEndOfStream <> True line = f.ReadLine fields = Split(line, ",") Dim newTag Set newTag = objCtr.Add(fields(0), fields(1)) If fields(2) <> "" Then newTag.SetPropertyValue("Addr", fields(2)) End If newTag.Link(True) Loop f.Close逻辑说明:第一列是变量名,第二列是 WinCC 数据类型字符串,第三列是变量地址。Tags.Add创建变量,SetPropertyValue("Addr", ...)设置驱动地址,Link(True)把变量连接到驱动连接。运行脚本前需要把 CSV 编码保存为 ANSI,否则 WinCC 的 VBS 读出来中文会乱码;如果用户权限不够,脚本会卡在CreateObject,需要给运行用户授予本地文件读取权限。运行后如果变量状态灰色,优先检查连接名和变量地址里有没有写错驱动连接。
模拟量处理还有一类问题:DP 从站上传的模拟量是整数,但工艺值需要带两位小数。不要用 WinCC 的输出格式小数位数硬显示,因为归档数据还是整数。应该在 PLC 中乘上精度系数,或使用 WinCC 内部变量做缩放。这个取舍组态源码里一般能看出来:凡是在画面脚本堆积大量转换代码的项目,后期维护都很痛苦。
3.3 位变量与报警消息:泵阀联锁的 DP 信号处理
污水处理系统里数字量点比模拟量更麻烦。泵和阀门的反馈、故障、手自动状态通常是由从站以一个 16 位状态字上传的,每个 bit 对应一个含义。WinCC 里为了把这些 bit 显示成报警,不需要建一堆布尔变量,而是建一个字变量作为报警源,再在报警记录中使用位消息。
WinCC 报警记录中新增位消息时,在消息变量处选择状态字变量,然后填入位号。当该位从 0 变为 1,WinCC 自动触发消息;从 1 变为 0 时自动消除。这个机制对污水厂的设备联锁提示很合适,因为操作员需要看到的是哪台泵故障,而不是故障字的第几位是 1。但前提是 PLC 和 WinCC 对位定义一致,最常见的错误是 PLC 中从第 0 位开始用,WinCC 报警里也从 Bit0 开始,结果变频器说明书倒是从 Bit1 开始的,全部错位。更稳妥的做法是在 PLC 中先把所有 DI 信号拆成单独位存到 DB,再聚合一个状态字;WinCC 直接读单个位变量作为报警源,虽然变量多一点,但排错很直观。
如果需要在 WinCC 中快速调试状态字,可以用一段 VBS 脚本循环判位:
Dim tagF, val, i, msg Set tagF = HMIRuntime.Tags("DP_Word1") val = tagF.Read For i = 0 To 15 If (val And (2 ^ i)) <> 0 Then msg = "Bit" & CStr(i) & " is set" HMIRuntime.Trace msg End If Next说明:val And (2 ^ i)是使用按位与运算来逐位检查。这段脚本放在某个画面的按钮事件里,可以快速确认从站上传的 16 位状态字每一位的实际变化,尤其适合现场信号与画面不匹配时定位问题。注意HMIRuntime.Trace输出到 WinCC 诊断窗口,生产环境不建议频繁运行,否则会拖慢项目运行。
4. 从组态到运行:DP 通讯排错和 WinCC 连接检查的硬核参数
4.1 站地址、总线终端和波特率的检查顺序
即使源码正确,DP 通讯也会出现间歇断开。现场第一道坎是物理层。PROFIBUS 总线段两端必须接终端电阻,中间设备分支线不能过长,屏蔽层在柜内单端接地。WinCC 诊断只能看到从站无响应,不能定位是接线、地址还是参数问题。我的检查顺序是:总线终端是否拨对、从站 DP 地址是否和硬件组态一致、主站 HSA 是否大于所有从站地址。
HSA 即 Highest Station Address,在 STEP 7 硬件组态中双击 DP 主站,参数标签页里可以设置,默认值是 31。如果现场从站地址是 42,而 HSA 仍是 31,主站轮询根本不会扫描到那个从站,WinCC 中该从站变量永远保持初始值。这个问题在污水厂改造项目里经常出现,因为老程序里从站少,新接入的加药间从站地址设得偏高,却忘了同步修改 HSA。修改后重新编译下载硬件组态即可。
波特率与线缆长度也需要一起查。如果波特率设成 12 Mbps,但某段线缆超过 100 米,会出现偶发 CRC 错误,现象是 WinCC 画面上的数值每隔几分钟跳变一次。这时不要急着换 PLC,先用万用表测量 DP 线 A/B 之间的终端电阻,标准是在端头量到约 220 欧姆。偏大说明终端电阻缺失,偏小说明有额外并联分支。
4.2 用 WinCC 内置诊断确认从站 DP 状态
WinCC 中有两个诊断手段:图形控件 PN/DP Diagnostics 可以直接连上去看从站状态;另一种是在 PLC 中调用 SFC13DPNRM_DIAG,把诊断数据写到 DB,WinCC 再读取。对于组态源码来说,我更推荐后者,因为诊断数据可以做成页面变量,发生故障时操作员能在画面上直接看到哪个从站离线,而不是让维护人员去数据库翻内部变量。
DPNRM_DIAG的调用参数里,LADDR 填从站在硬件组态中的诊断地址。诊断缓冲区 DIAG_BUF 是一个字节数组,第 5 个字节是从站状态,其中第 0 位为 1 表示从站正常,第 3 位为 1 表示参数化错误。如果看到第 3 位置位,要回到 STEP 7 检查 GSD 文件和从站实际固件是否匹配,常见的是旧 ET200M 模块已经更换成新一代 IM153-4,但组态里还保留旧的 IM153-2。
WinCC 侧为了显示诊断状态,可以建立一个字符串变量,用全局脚本读取诊断 DB。需要注意的是,SFC13 的返回状态是瞬时的,如果 DB 里只是缓存了最后一次调用结果,那么在掉线瞬间看到的数值可能还是正常。正确的做法是让 PLC 用 OB82 或 OB86 在中断里刷新一个从站故障字,而不是依赖 WinCC 周期去读。
4.3 掉线重连:连接状态变量和变量值保持的处理
DP 通讯断线后,WinCC 变量保留最后读到的值。如果操作员没有注意到通讯状态,就可能对这组数值做错误判断。源码包里常见的方案是使用 WinCC 自动生成的连接状态变量,例如@Connect_1@。当连接正常时为 1,断开时为 0。在画面总貌页放一个矩形,用变量颜色属性关联连接状态,红色表示离线。这个做法几分钟就能做完,但对现场很有意义。
除了显示,还可以在全局脚本中用连接状态控制操作按钮,避免离线时误操作:
Sub OnDPDisconnect() Dim conn Set conn = HMIRuntime.Tags("@Connect_1@") If conn.Read = 0 Then HMIRuntime.Tags("Pump1_Enable").Write 0 End If End Sub说明:脚本检测到连接离线时,把泵的手动允许值写成 0。这里要注意:直接对 PLC 变量写 0 虽然可以禁用远程操作,但真正的安全联锁应放在 PLC 程序中,WinCC 的写值断开后会恢复为不可控状态。掉线恢复时,WinCC 自动重连,不过重连后的首次刷新可能会读到从站的中间状态。更可靠的方式是让 PLC 在从站恢复后先执行一次数据同步,把从站输出全部重写一遍,再置位数据有效标志,WinCC 画面根据有效标志变化颜色。这个逻辑虽然不是组态源码必须包含的部分,但在污水厂这类不允许误动的场景下很重要。
5. 把组态源码用起来:变量归档、SQL 报表与画面脚本的复用配置
5.1 WinCC 报表的基础:SQL 数据库的建立与连接
污水处理的日报表需要记录进水流量、药品消耗、泵累计运行时间。WinCC 的变量归档可以写入 SQL Server 数据库,报表编辑器和外部程序都能读取。建立数据库的常见步骤是:在 SQL Server 管理工具里新建数据库,比如SewageReport,然后建表TagHistory。示例 SQL:
IF OBJECT_ID('dbo.TagHistory') IS NULL CREATE TABLE dbo.TagHistory ( SampleTime datetime, VarName nvarchar(50), VarValue real ); INSERT INTO dbo.TagHistory (SampleTime, VarName, VarValue) VALUES (GETDATE(), N'进水流量', 123.4);在实际项目里,不会让 WinCC 的每个变量都直接写 SQL 表,而是由 PLC 汇总好关键指标,再由 WinCC 周期脚本统一写库。real类型对应 WinCC 的浮点数;nvarchar以便保存中文变量名。连接 SQL Server 时,要使用本机 Windows 集成身份验证,避免在脚本里暴露数据库密码。
5.2 WinCC 画面中做循环脚本:按时间周期写入历史表
在 WinCC 中实现周期写入,可以在全局脚本里建一个动作,触发器设置为周期 300 秒,然后写 VBS 连接数据库。常见写法:
Dim conn, sql Set conn = CreateObject("ADODB.Connection") conn.Open "Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=SewageReport;Integrated Security=SSPI" sql = "INSERT INTO dbo.TagHistory (SampleTime, VarName, VarValue) VALUES (GETDATE(), N'进水流量', " & CSng(HMIRuntime.Tags("WaterIn").Read) & ")" conn.Execute sql conn.Close说明:CSng将 WinCC 读取到的 Variant 转为单精度浮点,避免因类型不匹配写入失败。每 300 秒执行一次会产生少量连接开销,一天只有 288 次,对工控机压力不大。如果点位数很多,建议把多个变量放在同一条 SQL 语句里插入,减少连接次数。WinCC 画面中做循环脚本还有另一种需求,是让文本框的显示值每秒钟刷新,那种循环不要用数据库连接,直接用画面动态属性加内部变量即可。
5.3 趋势图 VBS 脚本:在线趋势与历史曲线共用一份数据
WinCC 趋势图脚本是报表和监控的常用结合点。源码包里的常见问题是趋势控件时间轴刷新时 CPU 占用过高。更稳妥的写法是让趋势控件直接绑定变量归档,脚本只修改时间范围。例如:
Dim objTrend Set objTrend = ScreenItems("Trend1") objTrend.TimeRange = 3600 objTrend.TrendIndex = 0 objTrend.ReadData()说明:TimeRange单位是秒,3600 表示显示最近一小时;ReadData是让控件从归档数据库重新取数。这段脚本放在画面打开事件里,运行后操作员可以通过控件自带的时间轴缩放查看历史。趋势图的数值源必须和 5.1 节中的 SQL 报表共用同一份归档数据,否则画面上看到的趋势和打印出来的日报对不上。要做到这一点,WinCC 变量归档周期和 SQL 写库周期要一致,至少保证 SQL 表中的SampleTime与 WinCC 归档时间戳对齐。
本文还有配套的精品资源,点击获取