CO2 Sensor Reverse Engineering - Part II

co2 sensor reverse engineering i2c temperature sensor

After finding out how to decode the CO2 sensor measurements in the previous post I wanted to look at other salvageable components of the "BreeRainz DM1308A".

Battery Management

On the bottom side of the main PCB there is a battery management IC I didn't mention: HM4052 from Shenzhen Huazhimei Semiconductor Co., Ltd. It's quite interesting because it combines a 3.3V buck regulator with battery charging and safety functions without the need for an external microcontroller for configuration. It just works: You plug in USB and the battery is charged with a rate configured with an external resistor and your device is powered by USB. You unplug it and your 3.3V come from the battery.

Temperature/Humidity Sensor

The gadget also shows the temperature and humidity on the display. What kind of sensor is it using?

TLDR: It's a Sensirion SHT31 connected via I2C.

a PCB with a white print screen and a small black IC with a white blob on it

Logging the communication

Again the following PulseView traces show the communication between the microcontroller and the sensor:

PulseView trace of I2C command

Initially after power-on the microcontroller sends 22 36 to I2C address 0x44.

PulseView trace of I2C command with response

Then it waits around 500 ms and sends another command (E0 00) to 0x44 and reads a response from the same address. Then it sends the first command again.

The Protocol

Luckily with I2C the addresses are pretty telling: There are a few known devices using this address and of those the Sensirion SHT 31 fits the bill perfectly. The datasheet contains all the information we need.

table from the datasheet showing measurement modes
Datasheet: Measurement command

So the 22 36 from the command means that 2 measurements per second should be taken with the "high" repeatability setting.

diagram from the datasheet showing the packet structure
Datasheet: Data fetch command

And this shows that E0 00 is the "data fetch command" which gives us 16 bit temperature and humidity measurements, each one with a CRC checksum.

formulas from the datasheet showing conversion between protocol bytes and humidity and temperature values
Datasheet: Humidity and temperature value conversion

And this is how we get human-readable measurements after reassembling the bytes in the right endianness into 16 bit values.

Decoding our logs

We can now decode the measurements in our logic analyzer traces above.

In the screenshot we got the following response bytes:

44 67 86 A6  93 CA 7D
^^ ^^ ^^
AR ^^^^^ CRC ^^^^^ CRC
temp. humid.

Converting them this gives us:

# temperature in °C
>>> -45 + 175*(0x67*256 + 0x86)/(2**16 - 1)

# humidity in %RH
>>> (0x93*256 + 0xca) * 100/(2**16 - 1)

Don't you love this summer.

We now have a temperature and humidity sensor for our own gadget! But we should really check the checksums, too. Their CRC parameters are given in the datasheet.