路面平整度采集模块 Modbus TCP 对接指南
先说一个反直觉的地方
做路面平整度采集模块对接,第一件容易栽的事不是协议细节,而是角色搞反了。

添加微信好友, 获取产品信息
复制微信号
一般做 Modbus 集成的习惯是:自己的程序当主站(Master / Client),设备当从站(Slave / Server),程序主动去设备里读寄存器。这套习惯用在这个模块上会让你连不上——模块的采集卡在网络里是 TCP/IP 主机(Server 侧),站点地址 21,等你的程序主动连上来。
连上之后也不完全是你拉它推:状态数据每 0.15 秒自己发一次,10 米段的结果数据攒够一段自己发一次,都不需要你发指令请求。所以你写的程序本质上是一个"长连接 + 报文分流 + 解析入库"的接收端,只在标定和改参数的时候才发写指令。
默认网络参数:IP 192.168.0.96,端口 8190,站点地址 21。
连接之后会收到三种报文
同一个 socket 上会混着来三类数据,必须按功能码分流,否则解析全乱:
| 功能码 | 报文性质 | 触发方式 | 内容 |
|---|---|---|---|
| 0x03 / 0x10 | 读写寄存器的应答 | 你发指令后返回 | 寄存器值 |
| 25 | 10 米段结果包 | 攒够 10 米自动发 | 起终点位置、车速、经纬度、100 个高程值、IRI 或 VBI |
| 50 | 状态包 | 每 0.15 秒自动发 | 当前工作模式、车速、经纬度、编码器脉冲、传感器原始读数 |
建议的分流逻辑:先看报文头里的功能码字段,等于 25 交给"段落结果解析",等于 50 交给"状态刷新",其余交给"指令应答队列"。不要试图用报文长度来判断,两类数据包长度接近,靠长度会分辨错。
寄存器怎么用
采集卡的寄存器按 Word 编址,重要的那些如下。读写权限和是否掉电保存都列出来了,这两列在写代码时最容易忽略。
| 地址 | 含义 | 单位 / 取值 | 读写 |
|---|---|---|---|
| 0 | 传感器零位电压更新指令 | 单次写 10000 生效,其余值无效 | 写 |
| 1 | 工作模式 | 1 编码器触发 / 3 GPS 测距 / 4 停止 / 5~150 模拟速度 | 读写 |
| 2 | 行车速度 | 10 米/小时 | 读写 |
| 3–4 | 经度 | 1×10⁻⁷ 度,高 16 位在前 | 读写 |
| 5–6 | 纬度 | 1×10⁻⁷ 度,高 16 位在前 | 读写 |
| 7 | GPS 海拔 | 0.1 米 | 读写 |
| 8–9 | 编码器脉冲数量 | 32 位,高 16 位在前 | 只读 |
| 10 | 编码器脉冲间距 | 0.1 微米 | 读写,掉电保存 |
| 11 | 加速度原始电压 | 毫伏(仅模拟量传感器) | 只读 |
| 12 | 加速度值/电压系数 | mm/s² 每伏 | 读写,掉电保存 |
| 13 | 加速度零位 | 零位加速度 cm/s²;零位电压 mV | 只读 |
| 14 | 实时加速度 | cm/s²,范围 −10000~10000 | 只读 |
| 15 | 激光原始电压 | 毫伏 | 只读 |
| 16 | 激光位移/电压系数 | 10 µm 每伏 | 读写,掉电保存 |
| 17 | 激光零位电压 | 毫伏 | 只读 |
| 18 | 激光位移读数 | 0.05 毫米 | 只读 |
| 19–95 | 保留 | 预留给 13 路车辙激光等扩展 | — |
| 96–99 | 采集卡 IP | 四个字节,出厂 192.168.0.96 | 读写,掉电保存 |
| 100 | TCP 端口 | 出厂 8190 | 读写,掉电保存 |
| 104 | 编码器运行模式 | 0 双相正向 / 1 双相反向 / 2 单相 | 读写,掉电保存 |
五个单位换算,错一个数就废了
这个模块的单位全部是定点整数,没有浮点。好处是不会有精度漂移,坏处是每个字段都要乘一个系数,漏乘或乘错不会被报错,只会得到一串看起来合理但完全错误的数。
| 字段 | 原始值 | 换算 | 例 |
|---|---|---|---|
| 车速 | 10 米/小时 | ×10 得米/小时,÷1000 得 km/h | 原始 800 → 80 km/h |
| 经纬度 | 1×10⁻⁷ 度 | ÷1×10⁷ | 原始 1214750000 → 121.475°E |
| 高程值 | 0.05 毫米 | ×0.05 得毫米 | 原始 200 → 10 mm |
| 激光位移读数 | 0.05 毫米,有符号 | ×0.05,注意负值 | 原始 −120 → −6 mm |
| 编码器脉冲间距 | 0.1 微米 | ×0.1 得微米 | 原始 500 → 50 µm |
| IRI / VBI | mm/km | ÷1000 得 m/km | 原始 1850 → 1.85 m/km |
特别提醒两件事:高程值和高程本身不是一回事,它是相对于某个基准的偏移量,符号有正负;激光位移读数是有符号 16 位整数,解析时必须按 signed 处理,按 unsigned 读会把 −6 mm 读成 3276 mm。
大端字节序
Modbus 规定 16 位寄存器内部是高位在前。32 位数据(如经纬度、编码器脉冲、本段起点位置)拆成两个寄存器,高 16 位落在地址小的那个。所以组装 32 位整数时是 (word[n] << 16) | word[n+1],反了就得到经纬度错乱的结果——比如经度变成纬度,或者数值大得离谱。
标定类寄存器只能在停止模式写
编码器脉冲间距、加速度电压系数、激光电压系数、IP 与端口,这些是掉电保存的。手册里有一句容易被跳过的话:掉电保存的寄存器,仅在"停止模式"下才可更新。
于是最常见的困惑是"我明明写进去了,一读还是旧值"。原因就是当时还在编码器触发模式或者 GPS 模式。正确的顺序永远是:写 1 号寄存器 = 4(停止)→ 写参数 → 读回校验 → 写 1 号寄存器 = 目标模式。
零位校准是个一次性指令
0 号寄存器比较特殊,它不是"设成某个值",而是"收到 10000 这个数就执行一次动作"——把当前传感器电压记成零位。写其他任何值都不会有反应。
所以零位校准的标准流程是:
切到停止模式
把车停在平直路面上,静置,确认车身没有明显振动(人在车上走动都会影响)
向 0 号寄存器写 10000
读 13 号(加速度零位)和 17 号(激光零位),确认数值已更新且合理
零位不准,后面所有数据的绝对值都偏,而且偏得很隐蔽——波形形状还是对的,就是整体平移了。
一个最小可用流程
把上面这些拼起来,一个能跑通的最小程序大致是这五步:
建连。TCP 连 192.168.0.96:8190,超时设 3 秒。断线要有重连,行车颠簸导致网线松动是常态。
切停止模式。写 1 号寄存器 = 4,读回确认。
设距离参数。编码器方案写 10 号(脉冲间距),GPS 方案跳过这步。同时确认 104 号编码器运行模式对不对(正向/反向/单相)。
进入采集模式。有编码器写 1,无编码器写 3。
持续接收。状态包用来刷 UI 上的车速和经纬度;25 号包按段落库,每段落一条记录。
调试阶段可以用 5~150 的模拟速度模式,不接编码器也不接 GPS,模块会按设定的虚拟车速自己产生数据。这样能在办公室把整条链路跑通,不用上车。
常见问题
问:连不上,ping 通但端口连不上。
三个方向查:一是采集卡 IP 和你的工控机是不是同一网段(默认 192.168.0.x,很多车载设备用 192.168.1.x,会撞);二是端口被改过(100 号寄存器),试 8190 之外常用值;三是采集卡只能接受一个 TCP 连接,如果之前的调试程序没退干净,新连接会被拒。
问:收到了数据但解析出来全是乱码数字。
先确认你按功能码分流了。80% 的"乱码"是把 25 号段落包当成寄存器应答在解析,字段错位之后整篇都错。
问:段落数据一直不来。
25 号包是"攒够 10 米才发"。车不动就永远不发。用模拟速度模式测试时,如果设的速度太低(比如 5 km/h),要走 7 秒多才出一段,容易误判成没数据。
问:一个连接能接几台设备?
一个采集卡一个连接。做多车道、多传感器同步采集时,建议按设备分 socket、分线程收,别指望在一个连接里区分。
问:数据要落什么格式?
建议原样存:段落起终点位置、车速、经纬度、IRI 或 VBI,加上那 100 个高程值。高程值按 0.05 毫米存整数,别转成米存浮点——转一次就有一次舍入,后面重新演算 IRI 时误差会累积。
本文链接:https://www.gongluxitong.com/?id=1048
转载声明:本站发布文章及版权归原作者所有,转载本站文章请注明文章来源!

请发表您的评论