3、风电场常用通信协议(上):Modbus RTU/TCP协议详解
各位同行,今天我们来聊聊风电场里最“老熟人”的通信协议——Modbus。说实话,我入行那会儿,第一个接触的工业协议就是它。别看它年纪大,在咱们风电行业,尤其是SCADA系统与风机PLC、测风塔、箱变之间的通信,Modbus RTU和TCP依然是绝对的主力。
为什么它这么能打?说白了,就三个字:简单、稳定、省钱。你想想看,一个风场几十台风机,如果每台都用复杂的协议,调试起来得多头疼?Modbus这种“轻量级”选手,正好适合现场总线级别的数据采集。
3.1 Modbus协议的前世今生
Modbus是1979年由Modicon公司(现在的施耐德)发明的。最初是为PLC通信设计的。嗯,这里要注意,它本质上是一个主从(Master/Slave)架构的协议。什么意思呢?就是整个通信链路里,只有一个“主站”(比如监控后台),其他都是“从站”(比如风机控制器)。主站问,从站答,从站之间不能直接说话。
我在项目中遇到过一个问题:有个现场工程师把两台风机控制器直接连在一起,想让他们互相传数据,结果死活不通。我过去一看,哭笑不得——Modbus从站不会主动发起通信,这是协议的铁律。
3.2 Modbus RTU vs Modbus TCP:到底选哪个?
很多刚入行的朋友会问:RTU和TCP有什么区别?我打个比方你就明白了:RTU是“寄信”,TCP是“打电话”。
RTU走的是串口(RS-232/RS-485),数据是一帧一帧发的,像寄信一样,有固定的格式和校验。而TCP走的是以太网,像打电话一样,建立连接后随时可以说话,而且有TCP/IP协议栈保证数据不丢包。
| 对比项 | Modbus RTU | Modbus TCP |
|---|---|---|
| 物理层 | RS-232 / RS-485 | 以太网(RJ45) |
| 传输距离 | RS-485可达1200米 | 100米(交换机可扩展) |
| 通信方式 | 半双工 | 全双工 |
| 校验方式 | CRC16(必须) | TCP/IP自带校验 |
| 典型应用 | 风机内部、箱变、测风塔 | 站控层、远程监控 |
我个人习惯是:风机内部走RTU,站控层走TCP。为什么?因为风机机舱里电磁干扰大,RS-485差分信号抗干扰能力强,而且成本低。而到了升压站或者集控中心,用TCP可以方便地接入网络,传输速度也快得多。
3.3 Modbus RTU 报文结构详解
咱们先看RTU的报文格式。一个完整的RTU报文长这样:
| 地址码 (1字节) | 功能码 (1字节) | 数据区 (N字节) | CRC校验 (2字节) |
举个例子,读取风机A相电压(假设寄存器地址为0x0100):
主站发送:01 03 01 00 00 01 85 F6
从站回复:01 03 02 02 1C B9 7A
我来拆解一下:
- 01:从站地址,表示1号风机
- 03:功能码,表示“读取保持寄存器”
- 01 00:起始寄存器地址(高字节在前)
- 00 01:读取1个寄存器
- 85 F6:CRC16校验码
从站回复的02 1C就是电压值,换算成十进制是540,再乘以系数(比如0.1),就是54.0V。嗯,这里要注意,不同厂家的系数可能不一样,我踩过这个坑——有一次现场显示电压异常,查了半天,原来是系数写错了。
3.4 Modbus TCP 报文结构详解
TCP版本就简单多了。它去掉了CRC校验(交给TCP/IP协议栈处理),加了一个MBAP报文头。格式如下:
| MBAP头 (7字节) | 功能码 (1字节) | 数据区 (N字节) |
MBAP头包含:
- 事务处理标识符(2字节):用于匹配请求和响应
- 协议标识符(2字节):固定为0x0000
- 长度(2字节):后续字节数
- 单元标识符(1字节):相当于RTU的地址码
同样的读取电压操作,TCP报文是这样的:
主站发送:00 01 00 00 00 06 01 03 01 00 00 01
从站回复:00 01 00 00 00 07 01 03 02 02 1C
你看,00 01是事务ID,00 00是协议ID,00 06表示后面还有6个字节。后面的01 03 01 00 00 01和RTU一模一样,只是去掉了CRC。
3.5 常用功能码速查
在风电场里,最常用的功能码就这几个,我列个表方便你查阅:
| 功能码 | 名称 | 用途 | 风场典型应用 |
|---|---|---|---|
| 01 | 读取线圈状态 | 读DO | 风机启停状态、断路器分合 |
| 02 | 读取离散输入 | 读DI | 急停按钮、限位开关 |
| 03 | 读取保持寄存器 | 读AO/AI | 电压、电流、功率、风速 |
| 04 | 读取输入寄存器 | 读AI | 温度、振动、压力 |
| 05 | 写单个线圈 | 写DO | 远程启机、复位 |
| 06 | 写单个寄存器 | 写AO | 设定功率限值、无功目标 |
| 15 | 写多个线圈 | 写DO | 批量控制 |
| 16 | 写多个寄存器 | 写AO | 下发参数表 |
我个人建议:03和06功能码一定要吃透。因为风场90%的数据交换都是通过保持寄存器完成的。比如风速、功率、桨距角这些模拟量,都是用03读、06写。
3.6 知识体系总览
下面这张图是我自己画的,把Modbus RTU和TCP的核心知识点串起来了。你看一眼,心里就有谱了。
3.7 实战中的几个坑
最后,我分享几个实战中容易踩的坑,都是真金白银换来的教训:
- 波特率不匹配:RTU通信时,主站和从站的波特率、数据位、停止位、校验位必须完全一致。我见过一个现场,主站设9600,从站设19200,结果数据全是乱码。
- 地址冲突:同一个RS-485总线上,不能有两个相同地址的从站。有一次调试,两台风机地址都设成了01,结果主站一问,两台同时回复,总线直接“打架”。
- TCP连接超时:TCP通信时,如果从站掉线,主站需要设置合理的超时时间。我建议设3-5秒,太短容易误判,太长影响响应速度。
- 寄存器地址偏移:不同厂家的寄存器地址定义可能不同。有的从0开始,有的从1开始。我曾经因为地址偏移了1,读回来的数据全是错的。
好了,关于Modbus RTU和TCP的核心内容,今天就聊到这儿。记住一句话:Modbus不难,但细节决定成败。下一节我们会讲Modbus的进阶应用,包括多寄存器读写、异常处理,以及如何在风场中做批量数据采集。咱们下期见。