设备清单:
1、高精度温湿度传感器变送器工业级RS485 sht20探头 x1个,某宝 27元
2、工业级usb转rs485通讯模块双向半双工串口线转换器 x1个,某宝 11元
3、调试工具--串口调试工具或modbus调试转手(推荐:USR-TCP232-Test-V1.3或MODBUS调试助手)


接线方式:
探头A(黄色)-------转换器A
探头B(白色)-------转换器B
探头正极(红色)-----转换器+5V
探头负极(黑色)-----转换器 GND


AUTO是这个探头支持的普通协议。自报
产品所用功能码:
0x03:读保持寄存器
0x04: 读输入寄存器
0x06:写单个保持寄存器
0x10:写多个保持寄存器
|
寄存器类型 |
寄存器地址 |
数据内容 |
字节数 |
|
输入寄存器 |
0x0001 |
温度值 |
2 |
|
0x0002 |
湿度值 |
2 |
|
|
保持寄存器 |
0x0101 |
设备地址 (1~247) |
2 |
|
0x0102 |
波特率 0:9600 1:14400 2:19200 |
2 |
|
|
0x0103 |
温度修正值(/10) -10.0~10.0 |
2 |
|
|
0x0104 |
湿度修正值(/10) -10.0~10.0 |
2 |
Modbus通讯格式:
主机发送数据帧:
|
从机地址 |
功能码 |
寄存器地址 高字节 |
寄存器地址 低字节 |
寄存器数量 高字节 |
寄存器数量 低字节 |
CRC 高字节 |
CRC 低字节 |
从机响应数据帧:
|
从机地址 |
响应功能码 |
字节数 |
寄存器1数据 高字节 |
寄存器1数据 低字节 |
寄存器N数据 高字节 |
寄存器N数据 低字节 |
CRC 高字节 |
CRC 低字节 |
MODBUS命令帧
主机读取温度命令帧(0x04):
|
从机地址 |
功能码 |
寄存器地址 高字节 |
寄存器地址 低字节 |
寄存器数量 高字节 |
寄存器数量 低字节 |
CRC 高字节 |
CRC 低字节 |
|
0x01 |
0x04 |
0x00 |
0x01 |
0x00 |
0x01 |
0x60 |
0x0a |
从机响应数据帧:
|
从机地址 |
功能码 |
字节数 |
温度 高字节 |
温度 低字节 |
CRC 高字节 |
CRC 低字节 |
|
0x01 |
0x04 |
0x02 |
0x01 |
0x31 |
0x79 |
0x74 |
温度值=0x131,转换成十进制305,实际温度值 = 305 / 10 = 30.5℃
注:温度是有符号16进制数,温度值=0xFF33,转换成十进制 -205,实际温度= -20.5℃;
主机读取湿度命令帧(0x04):
|
从机地址 |
功能码 |
寄存器地址 高字节 |
寄存器地址 低字节 |
寄存器数量 高字节 |
寄存器数量 低字节 |
CRC 高字节 |
CRC 低字节 |
|
0x01 |
0x04 |
0x00 |
0x02 |
0x00 |
0x01 |
0x90 |
0x0A |
从机响应数据帧:
|
从机地址 |
功能码 |
字节数 |
湿度 高字节 |
湿度 低字节 |
CRC 高字节 |
CRC 低字节 |
|
0x01 |
0x04 |
0x02 |
0x02 |
0x22 |
0xD1 |
0xBA |
湿度值=0x222,转换成十进制546,实际湿度值=546 / 10 = 54.6%;
连续读取温湿度命令帧(0x04):
|
从机地址 |
功能码 |
寄存器地址 高字节 |
寄存器地址 低字节 |
寄存器数量 高字节 |
寄存器数量 低字节 |
CRC 高字节 |
CRC 低字节 |
|
0x01 |
0x04 |
0x00 |
0x01 |
0x00 |
0x02 |
0x20 |
0x0B |
从机响应数据帧:
|
从机地址 |
功能码 |
字节数 |
温度 高字节 |
温度 低字节 |
湿度 高字节 |
湿度 低字节 |
CRC 高字节 |
CRC 低字节 |
|
0x01 |
0x04 |
0x04 |
0x01 |
0x31 |
0x02 |
0x22 |
0x2A |
0xCE |
读取保持寄存器的内容(0x03):
以读取从机地址为例:
|
从机地址 |
功能码 |
寄存器地址 高字节 |
寄存器地址 低字节 |
寄存器数量 高字节 |
寄存器数量 低字节 |
CRC 高字节 |
CRC 低字节 |
|
0x01 |
0x03 |
0x01 |
0x01 |
0x00 |
0x01 |
0xD4 |
0x36 |
从机响应帧:
|
从机地址 |
功能码 |
字节数 |
从机地址 高字节 |
从机地址 低字节 |
CRC 高字节 |
CRC 低字节 |
|
0x01 |
0x03 |
0x02 |
0x00 |
0x01 |
0x30 |
0x18 |
修改保持寄存器的内容(0x06):
以修改从机地址为例:
|
从机地址 |
功能码 |
寄存器地址 高字节 |
寄存器地址 低字节 |
寄存器值 高字节 |
寄存器值 低字节 |
CRC 高字节 |
CRC 低字节 |
|
0x01 |
0x06 |
0x01 |
0x01 |
0x00 |
0x08 |
0xD8 |
0x30 |
修改从机地址:0x08 = 8
从机响应帧( 与发送相同 ):
|
从机地址 |
功能码 |
寄存器地址 高字节 |
寄存器地址 低字节 |
寄存器值 高字节 |
寄存器值 低字节 |
CRC 高字节 |
CRC 低字节 |
|
0x01 |
0x06 |
0x01 |
0x01 |
0x00 |
0x08 |
0xD4 |
0x0F |
连续修改保持寄存器(0x10):
|
从机地址 |
功能码 |
起始地址 高字节 |
起始地址 低字节 |
寄存器数量 高字节 |
寄存器数量 低字节 |
字节数 |
寄存器1高字节 |
寄存器1低字节 |
寄存器2高字节 |
寄存器2低字节 |
CRC 高字节 |
CRC 低字节 |
|
0x01 |
0x10 |
0x01 |
0x01 |
0x00 |
0x02 |
0x04 |
0x00 |
0x20 |
0x25 |
0x80 |
0x25 |
0x09 |
修改从机地址:0x20 = 32
波特率:0x2580 = 9600
从机响应帧:
|
从机地址 |
功能码 |
寄存器地址 高字节 |
寄存器地址 低字节 |
寄存器数量 高字节 |
寄存器数量 低字节 |
CRC 高字节 |
CRC 低字节 |
|
0x01 |
0x10 |
0x00 |
0x11 |
0x00 |
0x04 |
0xD4 |
0x0F |
普通版本协议
波特率默认9600(用户可自行设定),8位数据,1位停止,无校验
RS485通信
|
串口命令 |
说明 |
|
READ |
触发一次温湿度上报 (27.4℃,67.7% 温度27.4℃湿度67.7%) |
|
AUTO |
启动温湿度自动上报功能 (同上) |
|
STOP |
停止温湿度自动上报功能 |
|
BR:XXXX |
设置波特率 9600~19200 (BR:9600 波特率为9600) |
|
TC:XX.X |
设置温度校准 (-10.0~10.0) (TC:02.0温度修正值为2.0℃) |
|
HC:XX.X |
设置湿度校准 (-10.0~10.0) (HC:-05.1 湿度修正值为 -5.1%) |
|
HZ:XXX |
设置温湿度上报速率 (0.5,1,2,5,10) (HZ:2 自动上报速率 2Hz) |
|
PARAM |
读取系统当前设置 |
PARAM指令:
TC:0.0,HC:0.0,BR:9600,HZ:1 ->温度修正值0.0湿度修正值0.0波特率9600上报速率 1Hz
SLAVE_ADD:1 ->MODBUS从机地址 0x01
具体操作之前,先普及几个名词:
用到modbus协议,本质上很简单,只是第一次接触,被这些词语搞得云里雾里的。这里整理一下,方便以后查询:
0x01: 读线圈寄存器
0x02: 读离散输入寄存器
0x03: 读保持寄存器
0x04: 读输入寄存器
0x05: 写单个线圈寄存器
0x06: 写单个保持寄存器
0x0f: 写多个线圈寄存器
0x10: 写多个保持寄存器
如上所示一共8种功能码。这其中有涉及到线圈、离散输入、保持、输入四种寄存器。
线圈寄存器:实际上就可以类比为开关量(继电器状态),每一个bit对应一个信号的开关状态。所以一个byte就可以同时控制8路的信号。比如控制外部8路io的高低。 线圈寄存器支持读也支持写,写在功能码里面又分为写单个线圈寄存器和写多个线圈寄存器。对应上面的功能码也就是:0x01 0x05 0x0f
离散输入寄存器:如果线圈寄存器理解了这个自然也明白了。离散输入寄存器就相当于线圈寄存器的只读模式,他也是每个bit表示一个开关量,而他的开关量只能读取输入的开关信号,是不能够写的。比如我读取外部按键的按下还是松开。所以功能码也简单就一个读的 0x02
保持寄存器:这个寄存器的单位不再是bit而是两个byte,也就是可以存放具体的数据量的,并且是可读写的。一般对应参数设置,比如我我设置时间年月日,不但可以写也可以读出来现在的时间。写也分为单个写和多个写,所以功能码有对应的三个:0x03 0x06 0x10
输入寄存器:这个和保持寄存器类似,但是也是只支持读而不能写,一般是读取各种实时数据。一个寄存器也是占据两个byte的空间。类比我我通过读取输入寄存器获取现在的AD采集值。对应的功能码也就一个 0x04
使用操作过程说明:









注: 寄存器地址 是十进制格式, 任意指令 是十六进制格式。