第二章:数据采集基础——OPC DA/UA协议解析、Modbus TCP/RTU通信、数据点(Tag)的定义与管理、采集频率与数据质量
各位同学,欢迎来到第二章。这一章,咱们要啃的可是SCADA系统的“硬骨头”——数据采集。
你想想看,一个SCADA系统,如果数据采不上来,或者采上来的数据是错的,那后面所有的报表、分析、报警,全成了空中楼阁。我见过太多项目,前期设计得天花乱坠,最后栽在数据采集这个环节上。所以,这一章的内容,值得你反复琢磨。
2.1 OPC DA与OPC UA:两代协议的恩怨情仇
说到工业通信协议,OPC绝对是个绕不开的名字。它就像工业界的“普通话”,让不同厂商的设备能互相听懂。
但OPC也分两代:DA和UA。很多新手搞不清区别,我简单给你捋一捋。
2.1.1 OPC DA:老当益壮,但问题不少
OPC DA,全称是OPC Data Access。它诞生于上世纪90年代,专门用来解决实时数据交换的问题。说白了,就是让上位机软件能快速读到PLC、DCS里的数据。
它的核心是基于COM/DCOM技术。嗯,这里要注意,DCOM这东西,在局域网里用着还行,一旦跨网段、跨防火墙,配置起来能让你怀疑人生。我记得有一次,给一个客户做项目,光是配置DCOM的权限和用户认证,就折腾了两天。最后发现,是Windows防火墙把端口给堵了。
OPC DA的另一个特点是,它只传输“值”、“质量戳”、“时间戳”这三个属性。简单,但也局限。它没有数据模型的概念,你读到的就是一个裸数据,至于这个数据代表什么含义,它不管。
2.1.2 OPC UA:新一代的王者
OPC UA(Unified Architecture)的出现,就是为了解决DA的痛点。它不再依赖COM/DCOM,而是基于TCP/IP,甚至支持HTTP、HTTPS。这意味着,你可以轻松地通过互联网访问数据,防火墙配置也变得简单多了。
我个人习惯,新项目一律推荐OPC UA。为什么?因为它自带安全机制(加密、认证),而且支持数据建模。你可以把设备、变量、方法都定义成一个对象,层次结构清晰得很。
举个例子,在OPC DA里,你读到的可能只是一个“温度”值。但在OPC UA里,你可以读到“1号反应器/温度/当前值”,还能知道这个温度的单位是摄氏度,量程是0-100,甚至还能调用一个“复位”方法。这感觉,就像从“电报”升级到了“微信”。
| 特性 | OPC DA | OPC UA |
|---|---|---|
| 底层技术 | COM/DCOM | TCP/IP, HTTP |
| 跨平台 | 仅Windows | Windows, Linux, 嵌入式 |
| 安全性 | 弱(依赖DCOM) | 强(加密、认证) |
| 数据建模 | 无 | 有(面向对象) |
| 适用场景 | 局域网、老旧系统 | 跨网络、新系统、物联网 |
2.2 Modbus TCP与RTU:工控界的“通用语言”
如果说OPC是“普通话”,那Modbus就是“方言”。它简单、可靠、成本低,几乎所有PLC、仪表、传感器都支持。你想想看,一个协议能活40多年,还在广泛使用,这本身就说明了一切。
2.2.1 Modbus RTU:串口上的“老黄牛”
Modbus RTU运行在RS-232或RS-485串口上。它的数据格式是二进制的,所以传输效率高。但缺点也很明显:速度慢(通常9600bps或19200bps),而且只能一对一(RS-232)或一对多(RS-485,但总线上最多32个节点)。
我在项目中遇到过一个问题:一个现场用了Modbus RTU,总线上挂了20多个仪表,结果采集周期长达5秒。后来发现,是波特率设置太低,而且有些仪表响应时间太长。我建议,如果节点超过10个,最好用Modbus TCP,或者把总线分成几段。
2.2.2 Modbus TCP:以太网上的“快枪手”
Modbus TCP就是把Modbus报文封装在TCP/IP包里。它去掉了RTU的CRC校验(因为TCP本身有校验),增加了MBAP报文头。说白了,就是跑在以太网上的Modbus。
它的优势很明显:速度快(100Mbps甚至更高),支持更多节点(理论上无限制),而且可以跨交换机、路由器。现在的新项目,我基本都用Modbus TCP。
这里有个关键点:Modbus TCP的端口号是502。很多IT管理员会封掉这个端口,所以部署前一定要跟网络部门沟通好。
# Python示例:用pymodbus库读取Modbus TCP数据
from pymodbus.client import ModbusTcpClient
# 连接到PLC
client = ModbusTcpClient('192.168.1.100', port=502)
client.connect()
# 读取保持寄存器,从地址0开始,读10个
result = client.read_holding_registers(0, 10, unit=1)
if not result.isError():
print(f"寄存器值: {result.registers}")
else:
print("读取失败")
client.close()
2.3 数据点(Tag)的定义与管理:给数据一个“身份证”
数据采集上来,不能直接扔给数据库。你得给每个数据一个“身份”——这就是Tag(数据点)。
一个完整的Tag定义,至少包含以下信息:
- Tag名称:唯一标识,比如“TIC_101_PV”
- 描述:中文说明,比如“1号反应器温度”
- 数据类型:Float、Integer、Boolean等
- 数据源:来自哪个设备、哪个寄存器
- 量程上下限:用于工程单位转换
- 工程单位:℃、MPa、m³/h等
我个人习惯,在项目一开始就建立一个Tag清单,用Excel或者数据库管理。每个Tag的命名要规范,比如“区域_设备_参数_属性”。这样后期维护起来,一眼就能看懂。
2.4 采集频率与数据质量:快与准的平衡
数据采集不是越快越好。你想想看,一个温度传感器,每秒采100次,有意义吗?温度变化没那么快,反而会浪费带宽和存储。
采集频率的设置,要遵循“按需采集”原则:
- 快速变化信号(如振动、电流):100ms - 1s
- 一般过程信号(如压力、流量):1s - 5s
- 缓慢变化信号(如温度、液位):5s - 60s
数据质量,是另一个容易被忽视的点。OPC和Modbus都提供了“质量戳”,用来标识数据是否有效。常见的质量状态有:
- Good:数据正常
- Bad:数据无效(比如设备断线、通信超时)
- Uncertain:数据可疑(比如超出量程、传感器故障)
我曾经遇到一个案例:现场数据显示一切正常,但报表算出来的产量总是对不上。后来一查,发现有个流量计的信号线接触不良,数据时好时坏,但质量戳一直是“Good”。从那以后,我要求所有采集程序必须检查质量戳,质量不好的数据一律不存。
好了,这一章的内容就到这里。数据采集是SCADA系统的“地基”,地基不牢,地动山摇。下一章,咱们聊聊数据存储——怎么把海量数据管起来。