第4章 Modbus与伺服驱动器对接:读写参数、控制启停、读取状态

各位同行,今天咱们聊聊Modbus和伺服驱动器的对接。说实话,这个组合在工业现场太常见了。我最早接触这个,是在一个包装机械项目上。当时客户要求用PLC通过Modbus控制三台伺服,实现同步追剪。嗯,那会儿踩了不少坑,今天把这些经验分享给你。

4.1 为什么选Modbus控制伺服?

你可能会问:现在都流行EtherCAT、Profinet了,干嘛还用Modbus?

原因其实很简单:成本低、兼容性好、调试方便

  • 很多国产伺服驱动器,标配就是Modbus RTU
  • 老设备改造,PLC可能只有串口,Modbus是唯一选择
  • 调试时用USB转485,笔记本直接连,不用额外工具

我在一个纺织项目里,就是用Modbus控制20多台伺服做张力控制。虽然速度比不上总线,但稳定性和成本控制得很好。

4.2 伺服驱动器的Modbus寄存器映射

每个伺服厂家的寄存器地址都不一样。但万变不离其宗,核心功能就这几类:

功能分类 寄存器地址(举例) 说明
控制命令 0x2000 启停、急停、复位
目标速度 0x2002 单位:rpm 或 0.1Hz
目标位置 0x2004-0x2005 32位,低16位+高16位
状态读取 0x2100 运行中、报警、到位等
当前位置 0x2102-0x2103 32位编码器位置
参数读写 0x3000-0x3FFF PID参数、加减速时间等
注意:不同厂家的寄存器地址差异很大。我遇到过最坑的一次,是某品牌伺服把控制命令放在0x1000,但手册写的是0x2000。后来发现是固件版本不同。所以,拿到驱动器后第一件事:读手册,确认寄存器映射表

4.3 通过Modbus读写伺服参数

参数读写,说白了就是读/写保持寄存器(功能码03和06)。

举个例子,我要修改伺服驱动器的电子齿轮比:

// 假设电子齿轮比分子在0x3000,分母在0x3001
// 使用Modbus功能码06写单个寄存器

// 写分子:设为10000
发送:01 06 30 00 27 10 [CRC]
// 01: 从站地址
// 06: 写单个寄存器
// 30 00: 寄存器地址0x3000
// 27 10: 数据10000 (0x2710)

// 写分母:设为1000
发送:01 06 30 01 03 E8 [CRC]

// 读回来验证
发送:01 03 30 00 00 02 [CRC]
// 返回:01 03 04 27 10 03 E8 [CRC]
// 分子0x2710=10000,分母0x03E8=1000,正确
我的习惯:写参数前,先读一次当前值。万一写错了,还能恢复。我曾经在调试时手滑写了个0到速度上限寄存器,伺服直接飞车...还好有急停。

4.4 控制伺服启停

控制启停,通常用功能码06写控制命令寄存器。常见的控制字定义:

控制字值 含义
0x0000 停止/急停
0x0001 正转启动
0x0002 反转启动
0x0004 故障复位
0x0008 点动模式

实际项目中,我一般这样写控制逻辑:

// 启动伺服(正转)
发送:01 06 20 00 00 01 [CRC]

// 停止伺服
发送:01 06 20 00 00 00 [CRC]

// 故障复位
发送:01 06 20 00 00 04 [CRC]
关键点:启停命令之间要加延时。我见过有人连续发启动和停止,结果伺服根本没反应。为什么?因为驱动器处理需要时间。一般建议:两次命令间隔至少20ms

4.5 读取伺服状态

状态读取用功能码03。我通常会一次性读多个寄存器,减少通信次数。

// 读取状态寄存器0x2100-0x2103(共4个寄存器)
发送:01 03 21 00 00 04 [CRC]

// 返回示例
// 01 03 08 [状态字] [当前位置低16] [当前位置高16] [报警码] [CRC]
// 比如:01 03 08 00 01 12 34 56 78 00 00 [CRC]

// 解析:
// 状态字 0x0001:运行中
// 当前位置:0x56781234(编码器脉冲数)
// 报警码 0x0000:无报警

状态字每一位的含义,不同厂家定义不同。但常见的位定义:

  • Bit0: 伺服准备好
  • Bit1: 运行中
  • Bit2: 报警
  • Bit3: 到位信号
  • Bit4: 速度到达
避坑指南:我曾经在读取状态时,只读了一个寄存器。结果发现状态更新不及时。后来改成一次读4个寄存器,包括位置和报警码,这样一次通信就能拿到所有关键信息。通信效率提升了不少。

4.6 完整通信流程示例

下面是一个完整的启停+读取状态流程:

// 1. 先读参数确认配置
发送:01 03 30 00 00 02 [CRC]
返回:01 03 04 27 10 03 E8 [CRC]  // 电子齿轮比10000:1000

// 2. 设置目标速度(假设速度寄存器0x2002,单位rpm)
发送:01 06 20 02 03 E8 [CRC]  // 设置速度为1000rpm

// 3. 启动伺服
发送:01 06 20 00 00 01 [CRC]

// 4. 延时20ms

// 5. 读取状态确认运行
发送:01 03 21 00 00 04 [CRC]
返回:01 03 08 00 01 12 34 56 78 00 00 [CRC]
// 状态字0x0001:运行中,无报警

// 6. 停止伺服
发送:01 06 20 00 00 00 [CRC]

// 7. 再次读取状态确认停止
发送:01 03 21 00 00 01 [CRC]
返回:01 03 02 00 00 [CRC]  // 状态字0x0000:停止

4.7 常见问题与解决方案

做Modbus对接伺服,我总结了几条血泪教训:

  1. 通信超时问题:伺服驱动器处理Modbus命令需要时间。我一般设置超时500ms,重试3次。
  2. 波特率匹配:PLC和伺服必须一致。我习惯用115200,速度快且稳定。
  3. 终端电阻:485总线两端必须加120Ω电阻。不加的话,长距离通信会丢包。
  4. 地址冲突:多台伺服时,地址不能重复。我习惯用拨码开关设置,方便现场更换。

核心要点总结:

  • 先读手册,确认寄存器映射
  • 写参数前先读,防止误写
  • 启停命令间加延时
  • 一次多读几个寄存器,提高效率
  • 485通信注意终端电阻和波特率

好了,Modbus对接伺服的基本操作就这些。说白了,就是读读写写,注意时序和参数匹配。你在项目中遇到什么问题,欢迎交流。

Modbus与伺服驱动器对接核心流程 PLC/上位机 Modbus RTU/ASCII协议 RS-485物理层 伺服驱动器 读写参数(03/06) 控制启停(06) 读取状态(03)

公众号:蓝海资料掘金营,微信deep3321