08-29-2020 11:21 PM - edited 08-29-2020 11:24 PM
Hello Everyone,
I am considering BME280 in one of our projects, using Sparkfun BME280 break out board to evaluate the accuracy and performance of the sensor. I am getting temperature, humidity, and pressure readings 0 (uncompensated value 0, after compensation temperature -40, humidity 0, and pressure 110000.
struct bme280_dev dev;
uint32_t req_delay;
uint8_t i2c_try = 0;
/* BME280 sensor's API call */
static int8_t bme280_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr){
while (i2c_try < 5){
if (HAL_I2C_Mem_Read(&I2c2Handle, *(uint16_t *)intf_ptr, (uint16_t) reg_addr, 1, reg_data, (uint16_t) len, 1000) != HAL_OK){
I2C2_Error ();
i2c_try++;
} else {
i2c_try = 5;
}
}
i2c_try = 0;
return 0;
}
static int8_t bme280_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr){
while (i2c_try < 5){
if (HAL_I2C_Mem_Write(&I2c2Handle, *(uint16_t *) intf_ptr, (uint16_t) reg_addr, 1, reg_data, (uint16_t) len, 1000) != HAL_OK){
I2C2_Error ();
i2c_try++;
} else {
i2c_try = 5;
}
}
i2c_try = 0;
return 0;
}
static void bme280_delay_us(uint32_t period, void *intf_ptr){
HAL_Delay(1000);
}
int8_t bme280_Senosr_Init (void){
int8_t rslt = BME280_OK;
memset(&dev, 0, sizeof(struct bme280_dev));
uint8_t dev_addr = (BME280_I2C_ADDR_SEC << 1);
dev.intf_ptr = &dev_addr;
dev.intf = BME280_I2C_INTF;
dev.read = bme280_i2c_read;
dev.write = bme280_i2c_write;
dev.delay_us = bme280_delay_us;
rslt = bme280_init(&dev);
uint8_t settings_sel;
/* Recommended mode of operation: Weather monitoring */
dev.settings.osr_h = BME280_OVERSAMPLING_1X;
dev.settings.osr_p = BME280_OVERSAMPLING_1X;
dev.settings.osr_t = BME280_OVERSAMPLING_1X;
dev.settings.filter = BME280_FILTER_COEFF_OFF;
settings_sel = BME280_OSR_PRESS_SEL | BME280_OSR_TEMP_SEL | BME280_OSR_HUM_SEL | BME280_FILTER_SEL;
rslt = bme280_set_sensor_settings(settings_sel, &dev);
/*Calculate the minimum delay required between consecutive measurement based upon the sensor enabled
* and the oversampling configuration. */
req_delay = bme280_cal_meas_delay(&dev.settings);
return rslt;
}
int8_t bme280_readings (struct bme280_data *comp_data){
int8_t rslt = BME280_OK;
rslt = bme280_set_sensor_mode(BME280_FORCED_MODE, &dev);
/* Wait for the measurement to complete and print data @25Hz */
dev.delay_us(req_delay, dev.intf_ptr);
rslt = bme280_get_sensor_data(BME280_ALL, comp_data, &dev);
return rslt;
}
I have added a delay for 1 second between bme280_set_sensor_mode and bme280_get_sensor_data. I call bme280_Senosr_Init after I2C initialization at one time, bme280_readings in a process that runs every 10 seconds.
I am using the BME280 V.3.50. Why BME280 not giving sensor reading correctly? Any thought? If more information needed to understand the problem, please let me know.
Thanks!
-Arya
08-31-2020 10:52 PM
I want to understand how offten you see this issue, for example every 5 times measurement, you will get all 0 from sensor.
And if possible, the interface plotter from logic analyzer is also highly recommend here to better understand this issue.
Please also tell me which API version you are currently using for BME280.
In your current description, i didn't find abnormal point yet.
09-01-2020 03:42 PM
Hi Vincent,
Thanks for the reply, answer to your few questions;
1. There is no fixed interval, I get 0 at a random interval.
2. I will share the logic analyzer plot later, I cannot recreate this issue if I would have, then the logic analyzer can give valuable insight.
3. v3.5.0 downloaded from GitHub
09-01-2020 04:21 PM
I would like to share some new observation;
When I restart the BME280 (bme280_soft_reset) every time before I read, It works better. If I call bme280_Senosr_Init before bme280_readings (same code as in my question) every time, I get the correct temperature, pressure, and humidity reading. I only got 4 incorrect output from BME280.
bme280_Senosr_Init();
bme280_readings(&comp_data);
I logged the BME280 overnight and got 4 incorrect following data.
{"temp": -40.00, "hum": 0.00, "pressure": 110000.00}
Any thought why BME280 needed restart? I2C bus behaving correctly, rslt variable is always 0 (BME280_OK).
Thanks!
09-02-2020 12:53 AM
1. BME280 don't need reset every time, it should working properly for long run without any reset
2. the bme280_init function is not only doing soft reset, also try to read out all the calibration parameters. if those parameters got lost in system, then the final humidity, temperature, pressure will output wrong.
3. if you perform tne bme280_init, all sensor setting will be reset to 0 including oversampling T / P/ H. after that, if you directly trigger sensor to Force mode and read out sensor data, it will get all 0 because you skip all the measurement.
So your code procedure is not matching the correct behavior here. I think you can do the following:
1. Print out the ADC value for T / P / H at the same time as compensated value
2. Check again your code to see if every read / write on the bus is correctly issued from bus with logic analyer.
3. Check if the stored calibration parameters will be lost