2. Modbus RTU实战:读取变频器运行频率、写入变频器启停命令、读取变频器故障代码、多台变频器轮询
好,咱们直接进入正题。上一章我们把Modbus RTU的协议帧结构、寄存器映射这些基础概念捋了一遍。这一章,咱们要真刀真枪地干一场——用Modbus RTU去控制变频器。
我个人的习惯是,学通信协议一定要动手。光看报文格式,看三天也记不住。你拿个串口调试助手,对着变频器发几条指令,立马就通了。这一章,我们就围绕四个最常用的场景展开:读频率、写启停、读故障码、多台轮询。这四个场景,基本覆盖了90%的现场调试工作。
2.1 准备工作:硬件与参数设置
动手之前,先把家伙事儿备齐。你需要:
- 一台支持Modbus RTU的变频器(我用的是台达VFD-M系列,其他品牌大同小异)
- USB转RS485转换器(注意要带隔离的,我吃过亏,后面说)
- 串口调试助手(推荐Modbus Poll或串口猎人)
- 双绞屏蔽线(RS485通信线,别用普通电线凑合)
变频器这边,有几个关键参数必须设对:
| 参数代码 | 参数名称 | 设定值 | 说明 |
|---|---|---|---|
| P00 | 通信协议 | 01 | Modbus RTU模式 |
| P01 | 通信地址 | 01 | 从站地址,第一台设为1 |
| P02 | 通信波特率 | 03 | 9600bps,稳定可靠 |
| P03 | 数据格式 | 03 | 8N1(8数据位,无校验,1停止位) |
| P04 | 通信超时 | 0.5s | 响应超时时间 |
2.2 读取变频器运行频率
这是最常用的操作。你想知道电机现在跑多快,就得读频率寄存器。
变频器内部,运行频率通常保存在保持寄存器(Holding Register)中。以台达VFD-M为例,运行频率的寄存器地址是0x2102(十进制8450)。注意,Modbus协议里,地址是从0开始的,但有些软件显示的是从1开始的,这个坑要小心。
读频率的报文是这样的:
请求:01 03 21 02 00 01 XX XX
响应:01 03 02 13 88 XX XX
拆开来看:
01:从站地址,变频器1号03:功能码,读保持寄存器21 02:寄存器起始地址,高字节在前00 01:读取1个寄存器XX XX:CRC校验,低字节在前
响应报文里,13 88是十六进制,换算成十进制是5000。那频率是多少?这要看变频器的分辨率。台达VFD-M的分辨率是0.01Hz,所以实际频率 = 5000 × 0.01 = 50.00Hz。
2.3 写入变频器启停命令
读频率只是看看,能写启停才算真正控制了变频器。启停命令通常写在控制寄存器里,台达VFD-M的地址是0x2000。
写入命令用功能码06(写单个寄存器)。启动变频器的报文:
请求:01 06 20 00 00 01 XX XX
这里00 01是写入的数据,代表启动命令。停止的话,写入00 00。
响应报文是请求的完全回显,表示写入成功:
响应:01 06 20 00 00 01 XX XX
嗯,这里要注意一点:启停命令的数值不是随便写的。不同变频器定义不同。有的用0x0001启动、0x0008停止;有的用0x0001正转、0x0002反转。一定要看手册里的通信控制字定义。
2.4 读取变频器故障代码
变频器报故障了,怎么知道是什么问题?读故障代码寄存器。台达VFD-M的故障代码寄存器地址是0x2100。
读取报文:
请求:01 03 21 00 00 01 XX XX
假设响应返回01 03 02 00 0F XX XX,那00 0F就是故障代码,十进制15。对照手册,故障代码15代表「过电流」。嗯,这下就知道该查电机负载还是变频器IGBT了。
常见故障代码对照表(以台达VFD-M为例):
| 故障代码 | 含义 | 常见原因 |
|---|---|---|
| 0x0001 | 过电流 | 电机堵转、负载突变 |
| 0x0002 | 过电压 | 制动能量回馈、电网电压过高 |
| 0x0003 | 欠电压 | 电网电压过低、缺相 |
| 0x0004 | 过热 | 散热不良、风扇故障 |
| 0x000F | 过载 | 电机长时间超负荷运行 |
2.5 多台变频器轮询
现场通常不止一台变频器。比如一条流水线上,可能有5台、10台变频器同时工作。这时候就需要轮询——主机依次给每台变频器发指令,收响应,再发下一条。
轮询的逻辑其实很简单:
- 给1号变频器发读频率指令
- 等待响应,超时则跳过
- 处理响应数据
- 给2号变频器发指令
- 重复以上步骤
但实际做起来,有几个坑:
- 超时时间要合理:我一般设50ms~100ms。太短了容易误判超时,太长了轮询周期变慢。
- 响应帧间隔:变频器处理完指令后,需要3.5个字符时间的间隔才能发下一条指令。9600波特率下,大约是3.5ms。这个时间不能省。
- 地址不能重复:这个不用多说,重复了就会冲突。
下面是一个简单的轮询流程伪代码:
// 伪代码:多台变频器轮询
for (addr = 1; addr <= 5; addr++) {
// 发送读频率请求
send_request(addr, 0x03, 0x2102, 1);
// 等待响应,超时50ms
response = wait_response(50);
if (response != NULL) {
// 解析频率值
frequency = parse_frequency(response);
printf("变频器%d 频率: %.2f Hz\n", addr, frequency);
} else {
printf("变频器%d 无响应\n", addr);
}
// 帧间隔,至少3.5ms
delay(5);
}
2.6 避坑指南与总结
最后,把我这些年踩过的坑总结一下:
- RS485的A/B线不要接反:A接A,B接B。接反了也能通,但通信不稳定。我见过有人接反了,10次通信能成功3次,查了半天。
- 终端电阻要加上:总线两端各加一个120Ω电阻。不加的话,信号反射会导致数据错乱。特别是线长超过100米的时候。
- 地线要共地:RS485虽然差分传输,但各个设备的地电位不能差太多。否则共模电压超了,通信芯片会烧。我建议用带隔离的RS485转换器,省心。
- CRC校验一定要做:有些调试助手不校验CRC,但正式程序里必须校验。否则收到错误数据都不知道。
好了,这一章的内容就到这里。读频率、写启停、读故障码、多台轮询——这四个操作你掌握了,Modbus RTU控制变频器就算入门了。下一章,我们聊聊Modbus TCP,看看以太网环境下怎么玩。
记住,通信协议这东西,多动手,少看理论。拿个变频器,接上线,发几条指令,比看十遍书都管用。