Skip to content

Modbus RTU 协议 ​

Modbus RTU 在 COM1 应答,部分型号的 COM2 也应答,从站 ID 相同。是否提供 Modbus 以型号接口为准。

使用前准备 ​

通信前先完成下面七件事:

  1. 确认型号提供 Modbus。 对照适用产品;能通信时,读版本信息寄存器得到型号名,不确定时向技术支持确认。
  2. 关闭周期输出。 带 RS-485 接口的型号出厂不主动输出,无需关闭;其他型号见下方警告。
  3. 确认串口参数和从站 ID。 串口格式为 8N1,PLC 侧按此设置。出厂值见出厂默认配置;改过参数的,以记录的当前值为准,不确定时见失联恢复。
  4. 设置主机超时。 读取数据很快。写配置类寄存器要擦写 Flash,应答可能需要数十毫秒,偶尔接近 1 s。主机超时设为 1 s 以上。
  5. 整帧连续发送。 同一帧内字节之间不停顿。USB 转 RS-485 转换器有字节间延时选项时,请关闭。
  6. 只向具体的从站 ID 发请求,不用地址 0。 地址 0 是广播,总线上所有从站都会执行写请求,有的设备还会应答,造成总线冲突。
  7. 写后回读,配置只在需要时写。 Modbus 的回显只说明模块收到了请求,关键参数写入后读回确认,通则见配置流程与保存。配置完成后向寄存器 0x0000(CTRL)写 0x0000 保存。写配置寄存器可能触发 Flash 擦写,所以不要周期性写入。

警告

作 Modbus 从站前,先用 ASCII 命令关闭周期输出:LOG HI91 ONTIME 0,再执行 SAVECONFIG。已开启的其他周期帧同样要关闭。否则数据帧与应答混在一起,主机会解析出错误数据,且没有任何报错。

帧格式 ​

寄存器为 16 位,大端(高字节在前)。校验为标准 Modbus CRC-16(初值 0xFFFF,多项式 0xA001),低字节在前。使用以下两个功能码:

功能码作用限制
0x03读保持寄存器单次读 1–125 个寄存器
0x06写单个寄存器每次写一个 16 位寄存器

PLC 中选择“读保持寄存器(FC03)”,不要选“读输入寄存器(FC04)”。本手册未介绍的功能码请不要使用。

读寄存器(0x03):请求 ID 03 ADDR_H ADDR_L CNT_H CNT_L CRC_L CRC_H,其中 ID 为从站 ID,ADDR 为起始寄存器地址,CNT 为读取的寄存器个数。应答 ID 03 N DATA… CRC_L CRC_H,N 为数据字节数。

写寄存器(0x06):请求 ID 06 ADDR_H ADDR_L DATA_H DATA_L CRC_L CRC_H,正常应答与请求相同(回显)。

注意

  • 应答功能码的最高位为 1,表示模块拒绝了请求。请先改正请求,不要原样重发。
  • 读取未定义、只写或已取消的寄存器不会报错,只返回 0,因此读取成功不能说明寄存器存在。

CRC 计算(C),算出的 crc 低字节先发送:

c
uint16_t modbus_crc16(const uint8_t *p, size_t n)   /* init 0xFFFF, poly 0xA001 */
{
    uint16_t crc = 0xFFFF;
    while (n--) {
        crc ^= *p++;
        for (int b = 0; b < 8; b++)
            crc = (crc & 1) ? (crc >> 1) ^ 0xA001 : crc >> 1;
    }
    return crc;
}

主机侧完整实现见官方 SDK 的 Python 版:modbus.py(读写寄存器)和 modbus_multinode.py(一条总线上轮询多台模块)。

寄存器列表 ​

寄存器地址以十六进制表示。生效方式分两种:立即表示写入后马上生效;重启表示写入后先保存(向寄存器 0x0000 写 0x0000),再重启(写 0x00FF),重启后才生效。重启生效的项,写入后读回的已是新值,但尚未生效,以重启后的实际行为为准。

表中地址是报文里的协议地址,从 0 起。PLC 软件按 4xxxx 编号时,把地址换成十进制再加 1,例如 0x0034 = 52,对应 40053。

控制与配置寄存器 ​

寄存器地址名称类型R/W取值与说明生效
0x0000CTRLu16W写 0x0000 保存配置;写 0x0001 恢复出厂(见恢复出厂);写 0x00FF 重启立即
0x0004UART1_BAUDu16R/W串口波特率档位,见改波特率重启
0x0005MD_IDu16R/WModbus 从站 ID,1–247,出厂 80(0x50);-I2C 型号同时是 I2C 设备地址,范围 0x08–0x77立即
0x0006PROFILEu16R/W工作模式:0 = 6 轴、1 = 9 轴、4 = 人形机器人、5 = 室内低速机器人、7 = 低动态 / 倾角仪,见工作模式重启
0x0007COORDu16R/W输出数据轴向:0 = 右-前-上(默认)、4 = ROS(REP-103),见输出数据轴向重启
0x0008MCAL_STARTu16W启动地磁校准:1 = 3D、2 = 2D立即
0x0009MAIN_STATUSu16R状态字,见 MAIN_STATUS 状态字。只解析该表中定义的位,其余位屏蔽后再判断—
0x000AMCAL_STATUSu16R地磁校准状态:0 空闲、1 校准中、3 成功、4 失败—
0x000BMCAL_PROGRESSu16R校准进度(%):校准中 0–99,成功后 100—
0x00A5ATT_RSTu16W姿态零点,取值与含义同 CONFIG ATT RST:0 全部归零、1 航向临时清零、2 相对零点、3 自动校平、5 取消校平;0 / 2 / 3 / 5 写后保存。见姿态零点与校平立即
0x00A6URFRu16R/W安装方向编码(十进制数,如 24),见安装方向重启

CTRL(0x0000)、MCAL_START(0x0008)、ATT_RST(0x00A5)只写,读取返回 0。重启和恢复出厂后,模块不一定应答,处理方法见配置流程与保存。修改 PROFILE、COORD、URFR 后,先向 ATT_RST 写 5,后续步骤见设置顺序。

数据寄存器 ​

数据寄存器均为只读,内容是模块的实时输出。

地址名称类型单位 / 比例说明
0x0034–0x0036ACC X/Y/Zi16G,×0.00048828加速度
0x0037–0x0039GYR X/Y/Zi16deg/s,×0.061035角速度
0x003A–0x003CMAG X/Y/Zi16μT,×0.030517磁场
0x003D–0x003EROLLi32deg,×0.001横滚角,高字在前
0x003F–0x0040PITCHi32deg,×0.001俯仰角
0x0041–0x0042YAWi32deg,×0.001航向角,±180°
0x0043TEMPi16°C,×0.01温度
0x0044–0x0045PRSi32Pa,×0.01气压,仅带气压计的型号有效
0x0046–0x0049Q0–Q3i16×0.0001四元数 W/X/Y/Z
0x004AINCLI_Xi16deg,×0.011倾角 X(横滚)
0x004BINCLI_Yi16deg,×0.011倾角 Y(俯仰)
0x004C–0x004DCPUTIMEi32ms样本时刻,开机累计毫秒,不随对时切换;约 24.8 天后按 i32 解码为负值
0x004E–0x0050HEAVE / SURGE / SWAYi16m,×0.01MRU 位移(MRU 型号)
0x0051–0x0053HEAVE / SURGE / SWAY 频率i16Hz,×0.01MRU 频率(MRU 型号)
  • 能一次读完的数据,用一次请求读取。同一次请求里的数据更接近同一时刻,分开的请求之间不保证对齐。例如读取 0x0034–0x004D(26 个寄存器),一次得到加速度到 CPUTIME 的全部数据。
  • 整型输出按固定量程 ±16 G、±2000 deg/s、±1000 μT 换算,超出量程的读数不可信。需要完整量程或更高精度,使用 HI91 / HI83 的浮点输出,见数据字典。
  • 版本与身份寄存器见读取版本信息。HI83 字段用串口命令 LOG HI83 MAP 设置,见 HI83 字段选择;-I2C 型号也可以写 HI83_MAP 寄存器,见I2C 配置寄存器。

地磁校准寄存器 ​

先按校准步骤做好准备。下表给出各步骤对应的寄存器操作。

对应步骤寄存器操作
第 1 步:切换工作模式向寄存器 0x0006(PROFILE)写 1,向寄存器 0x0000(CTRL)写 0x0000 保存,再写 0x00FF 重启。重启后确认 MAIN_STATUS 的 MAG_AIDING 为 1
第 2 步:检查校准环境无寄存器操作
第 3 步:执行校准向寄存器 0x0008(MCAL_START)写 1(3D)或 2(2D),随后读寄存器 0x000A(MCAL_STATUS),确认变为 1。校准进行中不再写入
第 4 步:查询校准状态每 1–2 s 读一次寄存器 0x000A(MCAL_STATUS)和 0x000B(MCAL_PROGRESS),直到 0x000A 为 3(成功)或 4(失败)。以状态值为准,不按固定时长判断
第 5 步:验证校准结果无寄存器操作。校准成功后自动保存,验证方法见该步骤

常用配置示例 ​

注意

以下报文均以出厂从站 ID 80(0x50)为例。改从站 ID 时,同步改报文第一字节;改 DATA 时也一样。两种改动都要重算 CRC。

写入、保存、重启和读回的顺序见寄存器列表开头的生效说明,下表是各步骤的报文。

操作报文(Hex)
保存配置50 06 00 00 00 00 84 4B
重启50 06 00 00 00 FF C4 0B
恢复出厂(步骤见恢复出厂)50 06 00 00 00 01 45 8B
设为 6 轴模式50 06 00 06 00 00 64 4A
设为 9 轴模式50 06 00 06 00 01 A5 8A
设为低动态 / 倾角仪模式(7)50 06 00 06 00 07 25 88
输出数据轴向设为右-前-上(默认)50 06 00 07 00 00 35 8A
输出数据轴向设为 ROS50 06 00 07 00 04 34 49
全部归零(ATT_RST 0)50 06 00 A5 00 00 94 68
相对零点(ATT_RST 2)50 06 00 A5 00 02 15 A9
自动校平(ATT_RST 3)50 06 00 A5 00 03 D4 69
取消校平(ATT_RST 5)50 06 00 A5 00 05 54 6B

改波特率 ​

寄存器 0x0004(UART1_BAUD)的档位码 0–8 依次对应下表。写入后向寄存器 0x0000(CTRL)写 0x0000 保存,再写 0x00FF 重启。发出重启后,主机切换到新波特率并清空接收缓冲,读回寄存器 0x0004 确认。

档位码波特率报文(ID = 0x50)档位码波特率报文(ID = 0x50)
0480050 06 00 04 00 00 C5 8A511520050 06 00 04 00 05 05 89
1960050 06 00 04 00 01 04 4A623040050 06 00 04 00 06 45 88
21920050 06 00 04 00 02 44 4B746080050 06 00 04 00 07 84 48
33840050 06 00 04 00 03 85 8B892160050 06 00 04 00 08 C4 4C
45760050 06 00 04 00 04 C4 49

注意

档位码只用表内的 0–8。读不到应答时见失联恢复。

改从站 ID ​

写寄存器 0x0005(MD_ID),格式为 [当前ID] 06 00 05 00 [新ID] CRC。例如把从站 ID 从 0x50 改为 0x51:

text
→ 50 06 00 05 00 51 55 B6    写寄存器 0x0005,新从站 ID = 0x51
← 50 06 00 05 00 51 55 B6    回显,第一字节仍是原从站 ID 0x50
→ 51 03 00 05 00 01 98 5B    之后使用新从站 ID,读寄存器 0x0005 确认
← 51 03 02 00 51 B9 B4
→ 51 06 00 00 00 00 85 9A    用新从站 ID 保存配置(寄存器 0x00 ← 0x0000)

从站 ID 立即生效,之后的报文使用新 ID 并重算 CRC。多从站总线上,一次只接一台模块,不要用广播地址修改。

设置安装方向 ​

写寄存器 0x00A6(URFR),DATA 为安装方向编码(十进制数)转成的十六进制,例如 24 写 0x0018。每次设置后保存、重启,用 LOG USRCONFIG 读回(也可读寄存器 0x00A6),并抬车头、右侧下沉,验证姿态符号。完整的 24 种编码见安装方向,只写表内编码。

安装方向(X,Y,Z 箭头指向)编码十六进制报文(ID = 0x50)
右,前,上(默认水平安装)0240x001850 06 00 A6 00 18 64 62
右,下,前(侧装,Y 朝下)0430x002B50 06 00 A6 00 2B 24 77

读取版本信息 ​

从寄存器 0x0070 起读 19 个寄存器,得到型号名、固件版本、引导程序版本和芯片 ID。

text
→ 50 03 00 70 00 13 08 5D
← 50 03 26 [型号名 16 字节] [固件版本 2 字节] [引导程序版本 2 字节] [0x007A–0x007E 10 字节] [芯片 ID 8 字节] [CRC_L] [CRC_H]

应答共 43 字节,数据区 38 字节,每个寄存器高字节在前:

寄存器数据区字节偏移内容
0x0070–0x00770–15型号名(PNAME),ASCII
0x007816–17固件版本(SW_VER),与 LOG VERSION 的 APP_VER=<固件版本> 对应
0x007918–19引导程序版本(BL_VER),与 BL_VER=<引导程序版本> 对应
0x007A–0x007E20–29保留,忽略
0x007F–0x008230–37芯片唯一 ID,与 UUID=<芯片 ID> 对应

产品序列号用 ASCII 命令 LOG VERSION 读取其中的 SN=<序列号>。

读取 IMU/AHRS 数据 ​

从寄存器 0x0034 起读 15 个寄存器(加速度、角速度、磁场、横滚、俯仰、航向),数据区 30 字节:

text
→ 50 03 00 34 00 0F 49 81
← 50 03 1E FF 01 03 B0 06 50 FC C9 FF 7C 00 91 01 D5 FD DB FD 27 00 00 21 FF 00 00 7F F6 FF FD 73 E7 3F 04

按寄存器列表的比例因子换算:

物理量轴寄存器值原始值物理值
加速度(G,×0.00048828)XFF 01−255−0.1245
Y03 B09440.4609
Z06 5016160.7891
角速度(deg/s,×0.061035)XFC C9−823−50.232
YFF 7C−132−8.057
Z00 911458.850
磁场(μT,×0.030517)X01 D546914.312
YFD DB−549−16.754
ZFD 27−729−22.247
横滚(deg,×0.001)—00 00 21 FF87038.703
俯仰(deg,×0.001)—00 00 7F F63275832.758
航向(deg,×0.001)—FF FD 73 E7−166937−166.937

警告

32 位量(欧拉角、气压、CPUTIME)是大端,占两个连续寄存器,高字在前,需成对读取。先拼成完整的 i32,再乘比例因子,例如 FF FD 73 E7 → 0xFFFD73E7 = −166937 → −166.937°。把两个寄存器分别按 i16 解码,得到的角度是错的,且不会报错。

读取倾角 ​

倾角寄存器随时可读,无需另外开启。从寄存器 0x004A 起读 2 个寄存器,按 i16 有符号数乘 0.011 换算为度:

text
→ 50 03 00 4A 00 02 E8 5C
← 50 03 04 00 64 FF 38 BB 0B

X = 0x0064 = 100 → 1.100°,Y = 0xFF38 = −200 → −2.200°。倾角的范围、工作模式和零点设置见倾角输出,零点向寄存器 0x00A5(ATT_RST)写 2。

读取 MRU 数据 ​

MRU 型号从寄存器 0x004E 起读 6 个寄存器:

text
→ 50 03 00 4E 00 06 A8 5E
← 50 03 0C [HEAVE] [SURGE] [SWAY] [HEAVE 频率] [SURGE 频率] [SWAY 频率] [CRC_L] [CRC_H]

每项 2 字节 i16,高字节在前。位移比例因子 ×0.01 m,频率比例因子 ×0.01 Hz。MRU 输出含义见MRU 输出。

最后更新:

IMU · AHRS · INS · RTK 技术支持中心