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 响应超时时间
⚠️ 注意: 不同品牌的变频器,参数代码可能不一样。比如西门子的参数号是P2010、P2011这种。拿到变频器先翻手册,找到通信参数组。我曾经在项目现场,因为没仔细看手册,把三菱变频器的站地址设成了0,结果怎么都连不上——Modbus规定地址0是广播地址,不能用作从站地址。

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。

💡 小技巧: 我习惯在调试助手里面,把接收到的数据直接复制到计算器里换算。或者写个简单的Python脚本,自动解析报文。现场调试时,时间就是金钱。

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反转。一定要看手册里的通信控制字定义。

🔧 实战经验: 我曾经在一个项目里,把西门子G120的启停命令写成了0x047E(这是标准PROFIdrive的控制字),结果变频器没反应。后来发现,G120的Modbus控制字是0x047F。就差一个bit,折腾了我半天。所以,拿到变频器第一件事,就是找到控制字定义表,截图保存到手机里。

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 过载 电机长时间超负荷运行
⚠️ 注意: 读故障代码之前,最好先确认变频器当前是否处于故障状态。有些变频器在正常运行时,故障代码寄存器返回的是0。如果返回非0值,说明有故障。另外,读完后记得用故障复位命令清除故障,否则变频器无法重新启动。

2.5 多台变频器轮询

现场通常不止一台变频器。比如一条流水线上,可能有5台、10台变频器同时工作。这时候就需要轮询——主机依次给每台变频器发指令,收响应,再发下一条。

轮询的逻辑其实很简单:

  1. 给1号变频器发读频率指令
  2. 等待响应,超时则跳过
  3. 处理响应数据
  4. 给2号变频器发指令
  5. 重复以上步骤

但实际做起来,有几个坑:

  • 超时时间要合理:我一般设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);
}
💡 优化建议: 如果变频器数量多(比如20台以上),轮询周期会变长。我一般把读频率读故障码分开轮询。频率数据变化慢,可以2秒轮询一次;故障码需要实时监控,500ms轮询一次。这样既保证了实时性,又减轻了总线负担。

2.6 避坑指南与总结

最后,把我这些年踩过的坑总结一下:

  • RS485的A/B线不要接反:A接A,B接B。接反了也能通,但通信不稳定。我见过有人接反了,10次通信能成功3次,查了半天。
  • 终端电阻要加上:总线两端各加一个120Ω电阻。不加的话,信号反射会导致数据错乱。特别是线长超过100米的时候。
  • 地线要共地:RS485虽然差分传输,但各个设备的地电位不能差太多。否则共模电压超了,通信芯片会烧。我建议用带隔离的RS485转换器,省心。
  • CRC校验一定要做:有些调试助手不校验CRC,但正式程序里必须校验。否则收到错误数据都不知道。

好了,这一章的内容就到这里。读频率、写启停、读故障码、多台轮询——这四个操作你掌握了,Modbus RTU控制变频器就算入门了。下一章,我们聊聊Modbus TCP,看看以太网环境下怎么玩。

记住,通信协议这东西,多动手,少看理论。拿个变频器,接上线,发几条指令,比看十遍书都管用。