
Intro
I recently picked up a very affordable SHT30 temperature and humidity sensor from AliExpress to use with my STM32 RS485 Modbus embedded controller project. I chose this particular unit because it had a built-in DIN-rail mount, communicated via Modbus RTU over RS485, and was a great candidate for testing hybrid master/slave communication on my controller.
As you might expect with ultra-budget hardware, documentation was practically non-existent – and that turned out to be the main challenge.
While digging around, I came across a GitHub repository linked in a YouTube video, which referenced a similar model number that was printed on the sensor (zts-3008-ws-n01). That repo included a copy of the manufacturer’s Windows configuration tool, which I used to successfully read and write the sensor’s baud rate and slave ID.
However, I’m not a big fan of using black-box software from an unknown source, so I decided to listen to the serial communications to work out what was going on behind the scenes.
Reverse Engineering
I used a serial port sniffer on Windows to capture communication between the configuration tool and the sensor. What I found was a simple 7-byte command protocol (not standard Modbus RTU) that wraps baud/slave configuration into a minimal frame.

What I found
The device accepts a custom 7-byte frame that looks like:
FD FD FD [baud ID] [slave ID] [CRC_L] [CRC_H]
- Want to query the current baud and slave ID? Set both to
00
and the sensor replies with the real values (in the same frame format, just with the values inserted). - Want to set a new baud rate? Set the slave ID to
00
and the baud ID to what you wish to select (0x01
for2400
,0x02
for4800
,0x03
for9600
). - Want to set the slave ID? Just the opposite – set the baud ID to
00
and pick a new slave ID.
It’s quite simple – just remember to append the CRC which is a standard Modbus RTU CRC16, little-endian, over the first five bytes.
Modbus Data Format
After setup, the sensor behaves like a regular Modbus RTU slave. It supports:
- Functions
0x03
and0x04
(Read holding/input registers) - Register
0x00
= Relative Humidity - Register
0x01
= Temperature
You’ll need to divide the value of the humidity and temperature by 10 to get the proper reading.
Full Protocol + Examples
I’ve documented the entire protocol in a GitHub README, including frame examples and register maps