-
Notifications
You must be signed in to change notification settings - Fork 23
Description
Just some hints, most of them addressing already opend issues. There are massive bugs in void readCompensationParams(void)
The union compParams_u elements do not match in size, the compStruct is larger than the array. The uinion fixes this;) but a compiler will warn.
Then in readCompensationParams(void) the buffer is declared as 20 bytes, requested are 24 bytes but the loop reads 28 bytes. This just doen't crash due to the union. But there is no need for a union at all, because the compensation parameters can't be read into the struct directly! The endianess of the values has to be corrected.
The byte order of the T and P params are stored as big endian but they are read as little endian. The short bytes have to be swapped, refer to the original BME280driver by Bosch. This bug leads to very noisy measurements of T and P.
My suggestion:
#define BIG_ENDIAN_UINT16(msb, lsb) (((uint16_t)msb << 8) | (uint16_t)lsb)
uint8_t data[26];
Wire.beginTransmission(addrBME280);
Wire.write(regCalibStart);
Wire.endTransmission();
Wire.requestFrom(addrBME280, 26);
for (int count = 0; count < 26; count++) { // burst read of 26 bytes (including dig_H1)
data[count] = Wire.read();
}
compParams_ts.dig_T1 = BIG_ENDIAN_UINT16(data[1], data[0]);
// repeat swapping bytes for the remaing shorts of the struct;
compParams_ts.dig_H1 = data[25];
reading the other humidity copmensation parameters is fine.
There is no need to do a readCompensationParams(void) in every loop. These values are fixed and stored in the ROM during the production of the BME device. These values get copied from NV-ROM to the I²C registers at boot/soft reset and are read only.