01-11-2024 10:21 PM
#define CTRL_MEAS ((BYTE)0x74)
#define CTRL_HUM ((BYTE)0x72)
#define OVERSAMPLE_X1 0b001
#define CTRL_REG 0b01100101
double var1, var2, var3, var4, t_fine, temp_comp, hum_comp, press_comp;
int par_t1, par_t2, par_t3;
int hum_adc, par_h1, par_h2, par_h3, par_h4, par_h5, par_h6, par_h7;
int temp_adc;
int press_adc, par_p1, par_p2, par_p3, par_p4, par_p5, par_p6, par_p7, par_p8,par_p9, par_p10;
double temp(I2Cmaster::Device &i2cDevice) {
i2cDevice.write(CTRL_MEAS, CTRL_REG); // osrs_t
temp_adc = i2cDevice.read((BYTE) 0x22) << 12
| i2cDevice.read((BYTE) 0x23) << 4
| i2cDevice.read((BYTE) 0x24) >> 4;
par_t1 = i2cDevice.read((BYTE) 0xEA) << 8
| i2cDevice.read((BYTE) 0xE9);
par_t2 = i2cDevice.read((BYTE) 0x8B) << 8
| i2cDevice.read((BYTE) 0x8A);
par_t3 = i2cDevice.read((BYTE) 0x8C);
var1 = (((double) temp_adc / 16384.0) - ((double) par_t1 / 1024.0)) * (double) par_t2;
var2 = ((((double) temp_adc / 131072.0) - ((double) par_t1 / 8192.0)) * (((double) temp_adc / 131072.0) - ((double) par_t1 / 8192.0))) * ((double) par_t3 * 16.0);
t_fine = var1 + var2;
return t_fine / 5120.0;
}
double hum(I2Cmaster::Device &i2cDevice) {
i2cDevice.write(CTRL_MEAS, 0b01);
i2cDevice.write(CTRL_HUM, (OVERSAMPLE_X1 << 0)); // osrs_h
hum_adc = i2cDevice.read((BYTE) 0x25) << 8
| i2cDevice.read((BYTE) 0x26);
par_h1 = i2cDevice.read((BYTE) 0xE3) << 4
| (i2cDevice.read((BYTE) 0xE2) & 0b00001111);
par_h2 = i2cDevice.read((BYTE) 0xE1) << 4
| i2cDevice.read((BYTE) 0xE2) >> 4;
par_h3 = i2cDevice.read((BYTE) 0xE4);
par_h4 = i2cDevice.read((BYTE) 0xE5);
par_h5 = i2cDevice.read((BYTE) 0xE6);
par_h6 = i2cDevice.read((BYTE) 0xE7);
par_h7 = i2cDevice.read((BYTE) 0xE8);
var1 = hum_adc - (((double) par_h1 * 16.0) + (((double) par_h3 / 2.0) * temp_comp));
var2 = var1 * (((double) par_h2 / 262144.0) * (1.0 + (((double) par_h4 / 16384.0) * temp_comp) + (((double) par_h5 / 1048576.0) * temp_comp * temp_comp)));
var3 = (double) par_h6 / 16384.0;
var4 = (double) par_h7 / 2097152.0;
return var2 + ((var3 + (var4 * temp_comp)) * var2 * var2);
}
double press(I2Cmaster::Device &i2cDevice) {
i2cDevice.write(CTRL_MEAS, CTRL_REG); // osrs_p
press_adc = i2cDevice.read((BYTE) 0x1F) << 12
| i2cDevice.read((BYTE) 0x20) << 4
| i2cDevice.read((BYTE) 0x21) >> 4;
par_p1 = i2cDevice.read((BYTE) 0x8F) << 8
| i2cDevice.read((BYTE) 0x8E);
par_p2 = i2cDevice.read((BYTE) 0x91) << 8
| i2cDevice.read((BYTE) 0x90);
par_p3 = i2cDevice.read((BYTE) 0x92);
par_p4 = i2cDevice.read((BYTE) 0x95) << 8
| i2cDevice.read((BYTE) 0x94);
par_p5 = i2cDevice.read((BYTE) 0x97) << 8
| i2cDevice.read((BYTE) 0x96);
par_p6 = i2cDevice.read((BYTE) 0x99);
par_p7 = i2cDevice.read((BYTE) 0x98);
par_p8 = i2cDevice.read((BYTE) 0x9D) << 8
| i2cDevice.read((BYTE) 0x9C);
par_p9 = i2cDevice.read((BYTE) 0x9F) << 8
| i2cDevice.read((BYTE) 0x9E);
par_p10 = i2cDevice.read((BYTE) 0xA0);
var1 = ((double) t_fine / 2.0) - 64000.0;
var2 = var1 * var1 * ((double) par_p6 / 131072.0);
var2 = var2 + (var1 * (double) par_p5 * 2.0);
var2 = (var2 / 4.0) + ((double) par_p4 * 65536.0);
var1 = ((((double) par_p3 * var1 * var1) / 16384.0) + ((double) par_p2 * var1)) / 524288.0;
var1 = (1.0 + (var1 / 32768.0)) * (double) par_p1;
press_comp = 1048576.0 - (double) press_adc;
press_comp = ((press_comp - (var2 / 4096.0)) * 6250.0) / var1;
var1 = ((double) par_p9 * press_comp * press_comp) / 2147483648.0;
var2 = press_comp * ((double) par_p8 / 32768.0);
var3 = (press_comp / 256.0) * (press_comp / 256.0) * (press_comp / 256.0) * (par_p10 / 131072.0);
press_comp = press_comp + (var1 + var2 + var3 + ((double) par_p7 * 128.0)) / 16.0;
return press_comp;
}
It does not work, like I want it to.
Humidity works fine.
But I have problems with Temperature, it does not give me negative values, this means -0.5 is 0.5.
But worst is that it shows me wrong Pressure values, on 22 Degree Celsius I get a valid value, but if the temperatur goes down,
the Pressure rises and vice versa.
01-14-2024 04:23 PM
Hi mika,
Based on BME68x sensor API https://github.com/boschsensortec/BME68x-Sensor-API, I uploaed example code on STM32 for your reference, hope it will be helpful for you.
01-17-2024 12:00 PM
The calibration data (par_) have different data types (signed or unsigned, 8 or 16 bit). This must be taken into account during type cast to 'double'. Unfortunately, the data sheet does not provide any information on this. Further more, the data type 'int' is not portable because it is 32 bit long on 32-bit controller (e.g. STM32) but 16 bit on 8-bit controller (e.g. AVR). Use instead:
uint16_t par_h1;
uint16_t par_h2;
int8_t par_h3;
int8_t par_h4;
int8_t par_h5;
uint8_t par_h6;
int8_t par_h7;
int8_t par_gh1;
int16_t par_gh2;
int8_t par_gh3;
uint16_t par_t1;
int16_t par_t2;
int8_t par_t3;
uint16_t par_p1;
int16_t par_p2;
int8_t par_p3;
int16_t par_p4;
int16_t par_p5;
int8_t par_p6;
int8_t par_p7;
int16_t par_p8;
int16_t par_p9;
uint8_t par_p10;
03-11-2024 10:16 AM
Hi tbr1,
You can modify the reference code based on the platform you are using.
Usually, we recommend using a 32-bit host platform because it has the ability to run software such as BSEC. If using an 8-bit host platform, it will not have enough memory to support running BSEC software.