Use BSEC with BHI260AP on Arduino Nicla Sense ME

Hi,

is there currently an easy way to use the BME688 on the Arduino Nicla Sense ME board in combination with the BSEC library? The NRF52 chip on the board is connected to a BHI260AP via SPI which is connected to the BME688 via SPI.

In our use case, we are currently only interested in the air quality index provided by BSEC.

Best Regards,
Max

Best reply by reichemn

Hi BSTRobin,

I got it working. A bit dirty but sufficent. I used the "Arduino_BHY2" library from here: https://docs.arduino.cc/ca179f48cffbddcae9863d07cb19054b/nicla-sense-me-libs.zip (Available here: https://docs.arduino.cc/tutorials/nicla-sense-me/cheat-sheet )

I did some changes to the "BoschSensortec.h" file, to make the _bhy2 reference public available. 

Also I think there is a bug in the bhy2_soft_passthrough_transfer function in the bhy2.c file. The buffersize passed to the bhy2_hif_exec_soft_passthrough function was to small and I got a BHY2_E_BUFFER error (caused in the bhy2_hif_get_status_fifo function while reading the response back) no matter what I tried. So I increased the buffer size (passed to the bhy2_hif_exec_soft_passthrough function) by 8 to got it working. (So I used  buffer_size+8 in the read case and increased the size of tmp_rd_buf to 20 in the write case).

I used the following code for the BSEC library (version 1.4.8.0) so that it can communicate with the BME688 via the BHI260AP:

 

#include "BoschSensortec.h"

bhy2_soft_passthrough_conf conf = {
  .conf = {
    .direction = BHY2_SPASS_READ,
    .trans_type = BHY2_SPASS_MULTI_TRANS,
    .delay_ctrl = BHY2_SPASS_DELAY_DIS,
    .master_bus = 0, // sensor driver mode
    .spi_mode = BHY2_SPASS_SPI_4_WIRE,
    .cpol = BHY2_SPASS_SPI_CPOL_0, // unsued in sensor driver mode
    .cpha = BHY2_SPASS_SPI_CPHA_0, // unused in sensor driver mode

    .delay_val = 4u, // ignored if delay_ctrl disabled
    .cs_level = BHY2_SPASS_SPI_CS_LOW, // unused in sensor driver mode
    .lsb_first = BHY2_SPASS_SPI_LSB_FIRST_EN, // unused in sensor driver mode

    .trans_rate = 1000, // 1000khz

    // overwritten with gas sensor id later
    .address_shift = 0, // unused in sensor driver mode, used for sensor id instead
    .read_bit_pol = 0, // unused in sensor driver mode, used for sensor id instead
    .read_bit_pos = 0, // unused in sensor driver mode, used for sensor id instead

    .func_set = {
    .cs_pin = 4u // CS_680, pad 18, gpio 4
    }
  }
};


int8_t bme688_spi_read(uint8_t devId, uint8_t regAddr, uint8_t *regData, uint16_t length)
{
  conf.data[4] = 19u; // physical sensor id of the gas sensor on the BHI260AP
  conf.conf.direction = BHY2_SPASS_READ;
  return (int8_t) bhy2_soft_passthrough_transfer(&conf, regAddr , length, regData, &sensortec._bhy2 );
}

int8_t bme688_spi_write(uint8_t devId, uint8_t regAddr, uint8_t *regData, uint16_t length)
{
  conf.data[4] = 19u; // physical sensor id of the gas sensor on the BHI260AP
  conf.conf.direction = BHY2_SPASS_WRITE;
  return (int8_t)bhy2_soft_passthrough_transfer(&conf, regAddr , length, regData, &sensortec._bhy2 );
}

void bme688_delay_us(uint32_t period)
{
  delayMicroseconds(period);
}

Bsec iaqSensor;

void setup(void)
{
  sensortec.begin();
  iaqSensor.begin(19, BME680_SPI_INTF, bme688_spi_read, bme688_spi_write, bme688_delay_us);
}

 

View original
11 replies
Resolved