Skip to content

Wrong decoding of humitiy calibration constants #17

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
robert-hh opened this issue Nov 16, 2018 · 8 comments
Closed

Wrong decoding of humitiy calibration constants #17

robert-hh opened this issue Nov 16, 2018 · 8 comments
Assignees

Comments

@robert-hh
Copy link
Contributor

robert-hh commented Nov 16, 2018

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
Copy link
Member

ladyada commented Nov 16, 2018

cater - wanna take a look sometime next week?

@caternuson
Copy link

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:

  • Why only read 7 bytes?
  • Why cast to float?

@ladyada
Copy link
Member

ladyada commented Nov 16, 2018

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
Copy link

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
Copy link
Member

ladyada commented Nov 16, 2018

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
Copy link
Contributor Author

robert-hh commented Nov 16, 2018

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
Copy link

OOOOHHHHHH. E5 is in there twice. I was counting actual table entries. Ha! and also 🤦‍♂️

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

@caternuson
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants