3. 搭建PLC仿真与采集实验环境
在正式连接矿山现场PLC之前,先在本地搭建一套可重复、可回滚的仿真采集环境,是降低调试风险最有效的手段。本节的目标不是"跑通一个软件",而是构造一个信号可控、地址明确、读写可验证的最小闭环:由仿真端产生矿山设备信号,由采集端按协议读取,再通过写入回环确认链路双向可用。只有这个闭环稳定,后续接入InfluxDB的时序写入才有可信的数据源。
一、先确定仿真对象与信号清单
矿山PLC采集的典型信号可分为三类:开关量(设备启停、跑偏、急停、闸门到位)、模拟量(皮带电机电流、泵站压力、风机振动、料仓料位)和累计量(班产量、运行小时数)。搭建仿真环境时,不必一次覆盖全部点位,建议先选一条皮带运输线作为最小对象,把信号清单固化为地址表,后续所有配置都以该表为准。
| 信号名 | 类型 | 仿真地址 | 量程/取值 | 用途 |
|---|---|---|---|---|
| 皮带运行状态 | BOOL | M0.0 | 0/1 | 启停判断 |
| 急停信号 | BOOL | M0.1 | 0/1 | 安全联锁 |
| 皮带电机电流 | INT | MW10 | 0~500 A(×10) | 负载监测 |
| 泵站压力 | INT | MW12 | 0~100(×0.01 MPa) | 液压系统 |
| 料仓料位 | INT | MW14 | 0~100 % | 库存管理 |
| 班产量累计 | DINT | MD20 | 0~999999 t | 产量统计 |
表中量程采用"整数放大"约定:电流实际值 = 寄存器值 ÷ 10,压力实际值 = 寄存器值 × 0.01。这一约定必须在采集端解析时保持一致,否则后续InfluxDB中存储的字段值会出现10倍或100倍偏差,且难以追溯。
二、两条仿真路线及其选择
若后续采集走S7协议(S7-1200/1500),优先使用 PLCSIM Advanced。它提供虚拟网卡与真实IP,支持S7通信和PUT/GET,采集程序无需改动即可指向仿真实例。关键配置是:在实例创建时选择"Virtual Eth. Adapter",为虚拟PLC分配与采集主机同网段的IP(例如采集机 192.168.0.10/24,虚拟PLC 192.168.0.20/24),并在TIA Portal中把该实例设为下载目标,将包含上述M区的程序块下载进去。
若现场设备以Modbus RTU/TCP为主,或只需验证寄存器读写逻辑,则使用 Modbus Slave 更轻量。它把PC模拟为从站,直接编辑保持寄存器与线圈的值。配置要点:连接方式选 Modbus TCP,监听端口 502;Slave ID 设为 1;在寄存器表格中按地址表建立 40001 起(对应MW10)、40003 起(MW12)等映射,并把显示格式设为 Signed。注意 Modbus 的寄存器地址是"1 基"的,而多数采集库使用"0 基"偏移,配置时需确认偏移量,避免整体错位一个寄存器。
三、网络与采集端配置
网络配置的核心是"三段可达":采集主机能 ping 通仿真PLC;仿真PLC的防火墙或保护设置允许该协议访问;采集程序使用的端口未被占用。对 PLCSIM Advanced,还需在虚拟网卡上确认已获取IP,并在 TIA Portal 中关闭"仅允许PUT/GET通信访问"的阻止选项(若使用PUT/GET)。对 Modbus Slave,确认 502 端口处于监听状态,可用 netstat -an | findstr 502 检查。
采集端建议先用最小脚本验证,而不是直接上完整采集服务。以 Python 的 snap7 读取 S7 为例:
import snap7
plc = snap7.client.Client()
plc.connect('192.168.0.20', 0, 1) # IP, rack, slot
print(plc.get_connected())
db = plc.read_area(snap7.types.Areas.MK, 0, 0, 24) # 读M区前24字节
print(list(db))
plc.write_area(snap7.types.Areas.MK, 0, 0, bytes([1])) # M0.0 置1
plc.disconnect()
Modbus TCP 侧可用 pymodbus 读取保持寄存器:
from pymodbus.client import ModbusTcpClient
c = ModbusTcpClient('127.0.0.1', port=502)
c.connect()
r = c.read_holding_registers(address=9, count=3, slave=1) # MW10起3个寄存器
print(r.registers) # 例:[3200, 4520, 68]
c.write_register(address=9, value=3500, slave=1)
c.close()
示例返回值 [3200, 4520, 68] 为假设数据,按前述约定解析即电流 320.0 A、压力 45.20 MPa、料位 68%。这一步的意义在于:先确认"读到的数"与"仿真端设定的数"一致,再谈存储。
四、读写回环验证与结果判读
验证应覆盖三个层次:连通性(能否建立会话)、读一致性(读值与仿真设定一致)、写回环(写入后能在仿真端观察到变化,再读回确认)。写回环尤其重要,它证明链路是双向的,也验证了地址偏移与数据类型没有错位。下图给出该实验环境的信号链与验证路径。
判读时重点关注三类异常。其一是地址偏移错位:读到的电流值恰好等于压力设定值,说明整体偏移了一个寄存器,应检查 0 基/1 基换算。其二是数据类型不符:INT 被按无符号解析,负值或大值会变成异常大数,需在采集端显式声明 Signed。其三是字节序问题:DINT 累计量出现高低字颠倒,读出的产量远大于设定,应在解析时做字交换。这三类问题在仿真环境中暴露成本极低,一旦带到现场则往往需要停机排查。