Bosch Sensortec Community

    cancel
    Showing results for 
    Search instead for 
    Did you mean: 

    BME680 I2C read and write

    BME680 I2C read and write

    Helio_Moreira
    New Poster

    Hi,

    I'm new using  a Bosch sensor and I want to acess it using "HAL" library.

    I have a BME680 sensor and I'm using a Nucleo-144 from ST. I want to use the API in GitHub (https://github.com/BoschSensortec/BME680_driver) but in file "bme680.c" I don't understand how use "read" and "write" called, for example,  in function get_mem_page().

    In "readme" file there are a template for "int8_t user_i2c_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)" and "int8_t user_i2c_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)" but I don´t know how to fill it and where to include it (in main.c? or bme680.c?). Can someone explain it?

    Best resgard.

    8 REPLIES 8

    zgg
    Long-established Member

    Hi

     

    You could follow the README and copy the code examples and put the code clips in your main.c.

    and in user_i2c_read() and user_i2c_write(), call the I2C functions provided  by your ST MCU I2C functions.

    for example:

     

    int8_t user_i2c_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
    {
    int err;
    //pseudo code below
    //the dev_id is the i2c address for BME680 and needs to be passed in some way to the st mcu's I2C function
    err = st_nucleo_144_i2c_read(..., reg_addr, reg_data, len);
    return err;
    }

     

    The bme680.c is the so called API code and supposed to be kept intact in most cases (unless you spot some bug  fix or change needed).

    Hope this is clear.

     

    zgg
    Long-established Member

    to compliment the above answer, you could refer to a working example code which uses the same API here:

    https://github.com/adafruit/Adafruit_BME680/blob/master/Adafruit_BME680.cpp

    in this case, it's using SPI to interface with the sensor, but the way how the API is used should be similar to I2C.

    more info about this example could be found here: https://learn.adafruit.com/adafruit-bme680-humidity-temperature-barometic-pressure-voc-gas/arduino-w...

     

     

     

    Hi 

    Thanks for you explanation! I already fill the functions  user_i2c_read() and user_i2c_write() but something isn't right. My code doesn't advance from function bme680_init() (return always NULL) and I think that those functions are reason that didn´t work. This is the code that I used:

    int8_t user_i2c_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len) {
    	int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */
    
    	HAL_StatusTypeDef status = HAL_OK;
    	uint8_t array[I2C_RX_SIZE_BUFF] = { 0 };
    	uint8_t stringpos = 0;
    	array[0] = reg_addr;
    
    	while (HAL_I2C_IsDeviceReady(&hi2c1, (uint8_t) (dev_id << 1), 3, 100)
    			!= HAL_OK) {
    	}
    
    	status = HAL_I2C_Mem_Read(&hi2c1,	                // i2c handle
    			(uint8_t) (dev_id << 1),		// i2c address, left aligned
    			(uint8_t) reg_addr,			// register address
    			I2C_MEMADD_SIZE_8BIT,	                // bme280 uses 8bit register addresses
    			(uint8_t*) (&array),		        // write returned data to this variable
    			len,						// how many bytes to expect returned
    			100);					// timeout
    
    	if (status != HAL_OK) {
    		rslt = (-1);
    	}
    	for (stringpos = 0; stringpos < len; stringpos++) {
    		*(reg_data + stringpos) = array[stringpos];
    	}
    
    	return rslt;
    }

     

    int8_t user_i2c_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len) {
    	int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */
    
    	HAL_StatusTypeDef status = HAL_OK;
    
    	while (HAL_I2C_IsDeviceReady(&hi2c1, (uint8_t) (dev_id << 1), 3, 100)
    			!= HAL_OK) {
    	}
    
    	status = HAL_I2C_Mem_Write(&hi2c1,	                // i2c handle
    			(uint8_t) (dev_id << 1),		// i2c address, left aligned
    			(uint8_t) reg_addr,			// register address
    			I2C_MEMADD_SIZE_8BIT,	                // bme280 uses 8bit register addresses
    			(uint8_t*) (&reg_data),		       // write returned data to reg_data
    			len,			        	// write how many bytes
    			100);					// timeout
    
    	if (status != HAL_OK) {
    		rslt = (-1);
    	}
    
    	return rslt;
    }

    best regards!

    This is also a question of mine!

    did you got your answer? My code returns strange values of Temp/Press/Hum for example 0.5 deg or 130 deg temp!!

    I think this is for I2C read/Write function

    Can you please share your experience

     

    /* Private user code ---------------------------------------------------------*/
    /* USER CODE BEGIN 0 */

    int8_t user_i2c_read (uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len) {

    if (HAL_I2C_Master_Transmit(&hi2c4, (dev_id << 1), reg_addr, 1, 10)
    != HAL_OK)
    return -1;
    if (HAL_I2C_Master_Receive (& hi2c4, (dev_id << 1), reg_data, len, 10)
    != HAL_OK)
    return -1;
    return 0;
    }

    //int8_t user_i2c_read (uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len) {
    // if (HAL_I2C_Mem_Read(& hi2c4, dev_id<<1, reg_addr,1, reg_data, len, 5000) == HAL_OK)
    // return 0;
    // else
    // return 1;}
    void user_delay_ms (uint32_t period) {
    HAL_Delay (period);
    }
    int8_t user_i2c_write (uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
    {
    int8_t * buf;
    buf = malloc (len + 1);
    buf [0] = reg_addr;
    memcpy (buf + 1, reg_data, len);
    if (HAL_I2C_Master_Transmit (& hi2c4, (dev_id << 1), (uint8_t *) buf, len + 1, HAL_MAX_DELAY)!= HAL_OK)
    return -1;
    free(buf);
    return 0;
    }

    Icon--AD-black-48x48Icon--address-consumer-data-black-48x48Icon--appointment-black-48x48Icon--back-left-black-48x48Icon--calendar-black-48x48Icon--center-alignedIcon--Checkbox-checkIcon--clock-black-48x48Icon--close-black-48x48Icon--compare-black-48x48Icon--confirmation-black-48x48Icon--dealer-details-black-48x48Icon--delete-black-48x48Icon--delivery-black-48x48Icon--down-black-48x48Icon--download-black-48x48Ic-OverlayAlertIcon--externallink-black-48x48Icon-Filledforward-right_adjustedIcon--grid-view-black-48x48IC_gd_Check-Circle170821_Icons_Community170823_Bosch_Icons170823_Bosch_Icons170821_Icons_CommunityIC-logout170821_Icons_Community170825_Bosch_Icons170821_Icons_CommunityIC-shopping-cart2170821_Icons_CommunityIC-upIC_UserIcon--imageIcon--info-i-black-48x48Icon--left-alignedIcon--Less-minimize-black-48x48Icon-FilledIcon--List-Check-grennIcon--List-Check-blackIcon--List-Cross-blackIcon--list-view-mobile-black-48x48Icon--list-view-black-48x48Icon--More-Maximize-black-48x48Icon--my-product-black-48x48Icon--newsletter-black-48x48Icon--payment-black-48x48Icon--print-black-48x48Icon--promotion-black-48x48Icon--registration-black-48x48Icon--Reset-black-48x48Icon--right-alignedshare-circle1Icon--share-black-48x48Icon--shopping-bag-black-48x48Icon-shopping-cartIcon--start-play-black-48x48Icon--store-locator-black-48x48Ic-OverlayAlertIcon--summary-black-48x48tumblrIcon-FilledvineIc-OverlayAlertwhishlist