CO2 Sensor Reverse Engineering - Part II
co2 sensor reverse engineering i2c temperature sensorAfter 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](/assets/img/co2sensor-dis-4-k8HfyCFyKn-orig.jpeg)
Logging the communication #
Again the following PulseView traces show the communication between the microcontroller and the sensor:
![PulseView trace of I2C command](/assets/img/co2-i2cth-first-cmd-GcKXCTVLDt-orig.png)
Initially after power-on the microcontroller sends 22 36
to I2C address 0x44
.
![PulseView trace of I2C command with response](/assets/img/co2-i2cth-cmd-response-ei1xKc0l74-orig.png)
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](/assets/img/co2-temphum-ds1--yBeLV0bIC-orig.png)
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](/assets/img/co2-temphum-ds2-gFMurnJ769-orig.png)
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](/assets/img/co2-temphum-ds3-0Q3vCJxZ5k-orig.png)
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)
25.769054703593497
# humidity in %RH
>>> (0x93*256 + 0xca) * 100/(2**16 - 1)
57.73098344396124
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.