Bosch Sensortec Community

    Showing results for 
    Search instead for 
    Did you mean: 

    BME680 with STM32F103C8

    BME680 with STM32F103C8


    Hi. I am planning to use BME680 in my project but have some questions. I already downloaded sample code for BSEC and bme680 api and looked through it. But I dont understand why I must use BSEC. Is it important to use BSEC and also *.lib file for my platform or I can use only functions from bme680.c? When I compile my project in Keil MDK5 it gives a lot of errors L6406E: No space in execution regions with .ANY selector matching .....because I use in this project E-Ink display and nrf24l01.

    Also I have problem in communicating with sensor. I already filled bus_write and bus_read functions:


    int8_t bus_write(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data_ptr, uint16_t data_len)
        uint16_t i;
    	  int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */
         * Data on the bus should be like
         * |------------+---------------------|
         * | I2C action | Data                |
         * |------------+---------------------|
         * | Start      | -                   |
         * | Write      | (reg_addr)          |
         * | Write      | (reg_data[0])       |
         * | Write      | (....)              |
         * | Write      | (reg_data[len - 1]) |
         * | Stop       | -                   |
         * |------------+---------------------|
        I2C_AcknowledgeConfig(I2C_PORT,ENABLE); // Enable I2C acknowledgment
    	  while (!I2C_CheckEvent(I2C_PORT,I2C_EVENT_MASTER_MODE_SELECT)){}; // Wait for EV5
    	  UART1_Transmit_string("\r\nStart sent");	
    	  I2C_Send7bitAddress(I2C_PORT,dev_addr,I2C_Direction_Transmitter); // Send slave address
    		UART1_Transmit_string("\r\nDev_addr sent");
    	  while (!I2C_CheckEvent(I2C_PORT,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){}; // Wait for EV6
    	  I2C_SendData(I2C_PORT,reg_addr); // Send register address
    		UART1_Transmit_string("\r\nReg_addr sent");
    	  while (!I2C_CheckEvent(I2C_PORT,I2C_EVENT_MASTER_BYTE_TRANSMITTED)){}; // Wait for EV8
    	  for(i=0; i < data_len; i++)
        	I2C_SendData(I2C_PORT, reg_data_ptr[i]); // Send all bytes
    	    while (!I2C_CheckEvent(I2C_PORT,I2C_EVENT_MASTER_BYTE_TRANSMITTED)){}; // Wait for EV8
        return rslt;
    int8_t bus_read(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data_ptr, uint16_t data_len)
    	   uint16_t i =0;
    	   uint8_t status = 0;
    	I2C_AcknowledgeConfig(I2C_PORT,ENABLE); // Enable I2C acknowledgment
    	while (!I2C_CheckEvent(I2C_PORT,I2C_EVENT_MASTER_MODE_SELECT)); // Wait for EV5
    	I2C_Send7bitAddress(I2C_PORT,dev_addr,I2C_Direction_Transmitter); // Send slave address 0x76
    	while (!I2C_CheckEvent(I2C_PORT,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); // Wait for EV6
    	I2C_SendData(I2C_PORT,reg_addr); // Send register address
    	while (!I2C_CheckEvent(I2C_PORT,I2C_EVENT_MASTER_BYTE_TRANSMITTED)); // Wait for EV8
    	I2C_GenerateSTOP(I2C_PORT,ENABLE); // Send STOP condition
    	I2C_GenerateSTART(I2C_PORT,ENABLE); // Send repeated START condition (aka Re-START)
    	while (!I2C_CheckEvent(I2C_PORT,I2C_EVENT_MASTER_MODE_SELECT)); // Wait for EV5
    	I2C_Send7bitAddress(I2C_PORT,dev_addr,I2C_Direction_Receiver); // Send slave address for READ
    	while (!I2C_CheckEvent(I2C_PORT,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); // Wait for EV6
    	while (!I2C_CheckEvent(I2C_PORT,I2C_EVENT_MASTER_BYTE_RECEIVED)); // Wait for EV7 (Byte received from slave)
    	status = I2C_CheckEvent(I2C_PORT, I2C_EVENT_MASTER_BYTE_RECEIVED);
    	for(i=0; i < data_len; i++)
    	   reg_data_ptr[i] = I2C_ReceiveData(I2C_PORT); // Receive high byte   
    	   while (!I2C_CheckEvent(I2C_PORT,I2C_EVENT_MASTER_BYTE_RECEIVED)); // Wait for EV7 (Byte received from slave)
         I2C_GenerateSTOP(I2C_PORT,ENABLE); // Send STOP condition
    	/* Return 0 for Success, non-zero for failure */	
      if(status == 1)return 0;
      else		return status;   


    but sensor did not answering(I checked it with logic analyzer). It stops after slave address sent(0x76).


    8 REPLIES 8

    Community Moderator
    Community Moderator

    I don't have access to the documentation of your I2C library, but you may want to check how the implementation of I2C_Send7bitAddress() handles the slave address alignement.

    The BME680 in I2C mode expects the Save Address to be left aligned, with the LSB as R/W bit:


    Here is an example of chip ID read I2C transaction (note that in the Analyzer Settings, Address Display is set to "7-bit, address bits only"):


    With your library, you may need to manually shift the slave address, e.g.:


    I2C_Send7bitAddress(I2C1, (dev_addr << 1), I2C_Direction_Transmitter); // Send slave address for write
    I2C_Send7bitAddress(I2C1, (dev_addr << 1), I2C_Direction_Receiver); // Send slave address for read


    In your screenshot, the initial state of the SCL line is not correct, the start condition is not shown.

    Also the BME680 address is 0x76, but that is a 7-bit address. If you change your logic analyzer display settings, you would see that the i2c address that you are currently trying to access is 0x3B.

    The combination of these 2 issues, make it look like the BME680 is not answering. I believe the root cause of your issue is a misconfiguration of the i2c master.

    Thanks guys, I already found where problem was. It is slave address as you wrote. Yesterday, after posting screenshot from LA, I tried to set  gas_sensor.dev_id = 0xEC and  I recieved ack from BME. And now I see your answers for the same thing. In my code I am using  STM32F10x_StdPeriph_Lib_V3.5.0, and in library  I2C_Send7bitAddress realized in such way:

      * @brief  Transmits the address byte to select the slave device.
      * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.
      * @param  Address: specifies the slave address which will be transmitted
      * @param  I2C_Direction: specifies whether the I2C device will be a
      *   Transmitter or a Receiver. This parameter can be one of the following values
      *     @arg I2C_Direction_Transmitter: Transmitter mode
      *     @arg I2C_Direction_Receiver: Receiver mode
      * @retval None.
    void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction)
      /* Check the parameters */
      /* Test on the direction to set/reset the read/write bit */
      if (I2C_Direction != I2C_Direction_Transmitter)
        /* Set the address bit0 for read */
        Address |= OAR1_ADD0_Set; // Address |= 0x0001
        /* Reset the address bit0 for write */
        Address &= OAR1_ADD0_Reset; // Address &= 0xFFFE
      /* Send the address */
      I2Cx->DR = Address;

    Now I am  put in this function 0xEC address for writing to and 0xED for reading from BME.  

    Hello Guy's,

    I am using STM32f103C8T6 module as a arduino framework but I am unble to complile the below mentioned BMSC library in Platform IO.

    boschsensortec/BSEC Software Library@^1.6.1480

    While complaing the basic.ino file the PIO is generating belwo mentioend error.

    c:/users/yusata infotech/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: cannot find -lalgobsec
    collect2.exe: error: ld returned 1 exit status
    *** [.pio\build\genericSTM32F103CB\firmware.elf] Error 1
    =========================================================== [FAILED] Took 41.81 seconds ===========================================================

    Can anyone let me know how to fix this error??