adafruit / Adafruit_CircuitPython_BME280

CircuitPython driver for the BME280
MIT License
64 stars 42 forks source link

Wrong decoding of humitiy calibration constants #17

Closed robert-hh closed 5 years ago

robert-hh commented 5 years ago

The decoding of the calubration constant dig_H5 seems wrong. The adafruit driver is:

    self._humidity_calib[4] = float(((coeff[3] & 0xF0) << 4) | coeff[4])

while the Bosch driver is:

    dig_H5_msb = (int16_t)(int8_t)reg_data[5] * 16;
    dig_H5_lsb = (int16_t)(reg_data[4] >> 4);
    calib_data->dig_H5 = dig_H5_msb | dig_H5_lsb;

Along that, the adafruit code should be:

    self._humidity_calib[4] = float((coeff[4] << 4) | (coeff[3] >> 4))
ladyada commented 5 years ago

cater - wanna take a look sometime next week?

caternuson commented 5 years ago

Looks like there may be even more happening.

Here's a summary from Table 16 for the H (humidity) coefficients from the datasheet. humidity_coeffs H1 is read directly, while H2 - H6 are read in one go and then struct.unpacked, followed by some bit shifting and casting. Here's the code that does it (link):

        self._humidity_calib = [0]*6
        self._humidity_calib[0] = self._read_byte(_BME280_REGISTER_DIG_H1)
        coeff = self._read_register(_BME280_REGISTER_DIG_H2, 7)
        coeff = list(struct.unpack('<hBBBBb', bytes(coeff)))
        self._humidity_calib[1] = float(coeff[0])
        self._humidity_calib[2] = float(coeff[1])
        self._humidity_calib[3] = float((coeff[2] << 4) |  (coeff[3] & 0xF))
        self._humidity_calib[4] = float(((coeff[3] & 0xF0) << 4) | coeff[4])
        self._humidity_calib[5] = float(coeff[5])

So it looks like H5 (humidity_calib[4]), should be using coeff[4] and coeff[5]. And the register for H6 isn't even read. Questions I have:

ladyada commented 5 years ago

we have to cast to float because some of the numbers are fixed point weirdness and python sux at fixed point, so we just cast to float early instead of messing around with fixed later

caternuson commented 5 years ago

Figured it was something like that. How about the register reading? 7 vs. 8 in self._read_register

Don't have one of these on hand. I'll get one so I can test this further - so yah, next weekish or later because of turkey and stuff.

ladyada commented 5 years ago

next week it is! i will note that over the years evey time this comes up it often turns out that i did it right and there's Reasons so lets not fix before were're sure lest we have to refix :D

robert-hh commented 5 years ago

I just dumped the calibration data from a sensor and calculated the values dig_H2 - dig_H6 with both this Python script and the Bosch driver code. Only dig_H5 differs. If I changed the code according to my post, they match. The Bosch data sheet IS confusing, because in the doc the bit orders for dig_H5 are written reversed. @caternuson it's seven bytes, address E1 - E7

caternuson commented 5 years ago

OOOOHHHHHH. E5 is in there twice. I was counting actual table entries. Ha! and also :man_facepalming:

@robert-hh thanks for the follow up. we'll check this out.

caternuson commented 5 years ago

OK, hopefully this one is a little better. The indices in the second column are the indices of the actual coefficient, not the register value. humidity_coeffs2