I'm having some issues reading both the MSB and LSB data registers from the BME688. I'm using two single-byte read I2C transactions to read first the MSB and then LSB registers. When I reset the sensor and read values, there are no issues, but after running the sensor, something is messed up. I currently don't have access to a logic analyzer but wanted to know is there a requirement to read both data registers in the same transaction?
Thanks for any advice!
Solved! Go to Solution.
Hello cweaver,
You could read one or more sensor data. This is BME68X sensor API code, it demonstrated reading the raw data from the sensor.
/* This internal API is used to read a single data of the sensor */
static int8_t read_field_data(uint8_t index, struct bme68x_data *data, struct bme68x_dev *dev)
{
int8_t rslt = BME68X_OK;
uint8_t buff[BME68X_LEN_FIELD] = { 0 };
uint8_t gas_range_l, gas_range_h;
uint32_t adc_temp;
uint32_t adc_pres;
uint16_t adc_hum;
uint16_t adc_gas_res_low, adc_gas_res_high;
uint8_t tries = 5;
while ((tries) && (rslt == BME68X_OK))
{
rslt = bme68x_get_regs(((uint8_t)(BME68X_REG_FIELD0 + (index * BME68X_LEN_FIELD_OFFSET))),
buff,
(uint16_t)BME68X_LEN_FIELD,
dev);
if (!data)
{
rslt = BME68X_E_NULL_PTR;
break;
}
data->status = buff[0] & BME68X_NEW_DATA_MSK;
data->gas_index = buff[0] & BME68X_GAS_INDEX_MSK;
data->meas_index = buff[1];
/* read the raw data from the sensor */
adc_pres = (uint32_t)(((uint32_t)buff[2] * 4096) | ((uint32_t)buff[3] * 16) | ((uint32_t)buff[4] / 16));
adc_temp = (uint32_t)(((uint32_t)buff[5] * 4096) | ((uint32_t)buff[6] * 16) | ((uint32_t)buff[7] / 16));
adc_hum = (uint16_t)(((uint32_t)buff[8] * 256) | (uint32_t)buff[9]);
adc_gas_res_low = (uint16_t)((uint32_t)buff[13] * 4 | (((uint32_t)buff[14]) / 64));
adc_gas_res_high = (uint16_t)((uint32_t)buff[15] * 4 | (((uint32_t)buff[16]) / 64));
gas_range_l = buff[14] & BME68X_GAS_RANGE_MSK;
gas_range_h = buff[16] & BME68X_GAS_RANGE_MSK;
if (dev->variant_id == BME68X_VARIANT_GAS_HIGH)
{
data->status |= buff[16] & BME68X_GASM_VALID_MSK;
data->status |= buff[16] & BME68X_HEAT_STAB_MSK;
}
else
{
data->status |= buff[14] & BME68X_GASM_VALID_MSK;
data->status |= buff[14] & BME68X_HEAT_STAB_MSK;
}
if ((data->status & BME68X_NEW_DATA_MSK) && (rslt == BME68X_OK))
{
rslt = bme68x_get_regs(BME68X_REG_RES_HEAT0 + data->gas_index, &data->res_heat, 1, dev);
if (rslt == BME68X_OK)
{
rslt = bme68x_get_regs(BME68X_REG_IDAC_HEAT0 + data->gas_index, &data->idac, 1, dev);
}
if (rslt == BME68X_OK)
{
rslt = bme68x_get_regs(BME68X_REG_GAS_WAIT0 + data->gas_index, &data->gas_wait, 1, dev);
}
if (rslt == BME68X_OK)
{
data->temperature = calc_temperature(adc_temp, dev);
data->pressure = calc_pressure(adc_pres, dev);
data->humidity = calc_humidity(adc_hum, dev);
if (dev->variant_id == BME68X_VARIANT_GAS_HIGH)
{
data->gas_resistance = calc_gas_resistance_high(adc_gas_res_high, gas_range_h);
}
else
{
data->gas_resistance = calc_gas_resistance_low(adc_gas_res_low, gas_range_l, dev);
}
break;
}
}
if (rslt == BME68X_OK)
{
dev->delay_us(BME68X_PERIOD_POLL, dev->intf_ptr);
}
tries--;
}
return rslt;
}
https://github.com/BoschSensortec/BME68x-Sensor-API/blob/master/bme68x.c
Thanks! I ultimately found a bug in my program outputting occasionally incorrect SPI transactions.