2. Modbus RTU 土壤多参数传感器联调与寄存器映射

联调对象与接线关系

本例使用一台支持 Modbus RTU 的土壤多参数传感器(常见为 RS485 四线制:V+、GND、A、B),通过 USB-RS485 转换器接入上位机。传感器出厂默认从站地址多为 1,波特率 9600、8 数据位、无校验、1 停止位(8N1)。联调的核心不是"能通就行",而是把物理接线、串口参数、从站地址、寄存器映射四层对齐,再用原始寄存器值反算工程量,确认温湿度、电导率等通道读数合理。

上位机 / 串口调试工具 COM3 · 9600 · 8N1 功能码 03 / 06 / 16 从站地址 0x01 USB-RS485 转换器 USB 侧:虚拟串口 RS485 侧:A / B 差分 半双工,需终端电阻 土壤多参数传感器 V+ 5~24V · GND A(+) / B(−) 从站地址 1 · 9600 8N1 USB A/B 寄存器映射(保持寄存器,功能码 03 读取,示例地址以手册为准) 寄存器地址 通道 数据类型 换算系数 工程量示例 0x0000 土壤温度 int16 ×0.1 ℃ 0x00FA → 25.0 ℃ 0x0001 土壤湿度 uint16 ×0.1 % 0x00D2 → 21.0 % 0x0002 电导率 EC uint16 ×1 µS/cm 0x01A4 → 420 µS/cm

串口参数与从站地址确认

先用转换器厂商驱动确认虚拟串口号(如 COM3),再在串口工具中设置 9600 8N1。若传感器手册标注默认地址为 1,则直接以地址 1 发起读取;若不确定,可用广播地址 0 配合功能码 03 试探(部分设备不支持广播读,需以手册为准)。读取失败时优先排查 A/B 是否接反、供电是否正常、终端电阻是否缺失。

寄存器读取与工程量换算

以功能码 03 读取保持寄存器,起始地址 0x0000、数量 3,可一次取回温度、湿度、电导率三个通道。下面给出一个可直接运行的 Python 示例,使用 pyserial 与 minimalmodbus 完成读取与换算。示例中的寄存器地址与系数为教学假设,实际以传感器手册为准。

import minimalmodbus
import serial

# 1. 建立串口连接:COM3、9600、8N1、从站地址 1
sensor = minimalmodbus.Instrument('COM3', 1)
sensor.serial.baudrate = 9600
sensor.serial.bytesize = 8
sensor.serial.parity = serial.PARITY_NONE
sensor.serial.stopbits = 1
sensor.serial.timeout = 1.0

# 2. 读取 3 个保持寄存器(功能码 03),起始地址 0x0000
raw = sensor.read_registers(0x0000, 3, functioncode=3)
print("原始寄存器:", [hex(v) for v in raw])

# 3. 工程量换算(系数为示例,需按手册核对)
temp_c = raw[0] * 0.1          # int16,×0.1 ℃
moist_pct = raw[1] * 0.1       # uint16,×0.1 %
ec_us_cm = raw[2] * 1.0        # uint16,×1 µS/cm

print(f"土壤温度: {temp_c:.1f} ℃")
print(f"土壤湿度: {moist_pct:.1f} %")
print(f"电导率:   {ec_us_cm:.0f} µS/cm")
若读回值恒为 0 或 0xFFFF,通常是地址偏移差 1(部分设备寄存器从 1 开始编号)或 A/B 接反。可先用功能码 03 读取单个寄存器做最小验证,再扩展到多寄存器批量读取。

读数正确性验证

验证分两步:先看原始值是否稳定(连续读取 5 次,波动应在个位以内),再看换算值是否落在物理合理区间。例如室温 25 ℃ 时土壤温度应在 20~30 ℃,干燥土壤湿度 15~25 %,电导率在几百 µS/cm 量级。若温度出现 -40 ℃ 或 85 ℃ 这类边界值,多为符号位处理错误或传感器未插入土壤。

检查项预期现象异常时的排查方向
串口打开无报错,能收到回帧驱动、COM 号、被其他程序占用
从站应答返回字节数与请求一致地址错误、A/B 反接、波特率不符
原始值稳定性连续 5 次波动 ≤ 个位供电不稳、线缆过长、干扰
工程量合理性温度 20~30 ℃、湿度 15~25 %换算系数、符号位、寄存器偏移
RS485 总线为半双工,读取时不要同时让多个主站发起请求;长距离布线时在总线两端加 120 Ω 终端电阻,并确保所有设备共地,否则容易出现偶发 CRC 错误。