Bosch Sensortec Community

    cancel
    Showing results for 
    Search instead for 
    Did you mean: 

    BMP388 readings never change/implausible pressure (interfaced from Raspberry Pi Pico)

    SlightlyPunk
    New Poster

    BMP388 readings never change/implausible pressure (interfaced from Raspberry Pi Pico)

    I have the BMP388 from SparkFun connected to the Raspberry Pi Pico. This chip has Vin, 3V0, GND, SCK, SDO, SDI, CS, and INT pinouts. I have Vin = 5v, GND, SCK connected to pico, SDO grounded for default address, and SDI connected to the pico. I'm using the Bosch API provided on github and have defined write, read, and delay functions that interface with the pico. For some reason, when I'm reading in a loop, my temperature (plausible) and pressure readings (implausible) never change. I have observed the flowchart in the datasheet regarding measurement timings and I have added more than enough delay to ensure accurate readings but there must be something wrong. Below is sample code used to try and get repeated measurements from the sensor. I've tried various oversampling settings, ODR frequencies, and varying pico I2C frequencies as well.

     

    // Hardware address for BMP 388
    static uint8_t addr = 0x76;
    
    // Constructor: performs all required pre-setup tasks.
    BMP::BMP() {
        int8_t result = 0;
        int i = 0;
    
    
        // set up i2c stuff on the Pico
        i2c_init(i2c0, 40*1000);
        
        gpio_set_function(PICO_BMP_I2C_SDA_PIN, GPIO_FUNC_I2C);
        gpio_set_function(PICO_BMP_I2C_SCL_PIN, GPIO_FUNC_I2C);
    
        // Set the BMP388 struct to use I2C and self-defined read/write/delay funcs
        bmp388.intf = BMP3_I2C_INTF;
        bmp388.delay_us = (bmp3_delay_us_fptr_t)&bmpDelay;
        bmp388.read = (bmp3_read_fptr_t)&bmpRead;
        bmp388.write = (bmp3_write_fptr_t)&bmpWrite;
    
        // perform selftest for error checking
        //printf("Selftest result is: %d\n", bmp3_selftest_check(&bmp388));
        //fflush(stdout);
    
        /* Variable used to select the sensor component */
        uint8_t sensor_comp;
    
        // Use Pressure and Temperature readings    
        sensor_comp = BMP3_PRESS | BMP3_TEMP;
    
        /* Used to select the settings user needs to change */
        uint16_t settings_sel;
    
        /* Variable used to store the compensated data */
        struct bmp3_data data = { 0 };
    
    
        result = bmp3_soft_reset(&bmp388);
        bmp388.delay_us(40000, bmp388.intf_ptr);
    
    
        result = bmp3_init(&bmp388);
        bmp388.delay_us(40000, bmp388.intf_ptr);
    
        //validate_trimming_param(&bmp388);
    
        bmp388.settings.press_en = BMP3_ENABLE;
        bmp388.settings.temp_en = BMP3_ENABLE;
        bmp388.settings.odr_filter.press_os = BMP3_OVERSAMPLING_8X;
        bmp388.settings.odr_filter.temp_os = BMP3_OVERSAMPLING_2X;
        bmp388.settings.odr_filter.iir_filter = BMP3_IIR_FILTER_COEFF_15;
        bmp388.settings.odr_filter.odr = BMP3_ODR_50_HZ;
    
        settings_sel = BMP3_SEL_PRESS_EN | BMP3_SEL_TEMP_EN | BMP3_SEL_PRESS_OS | BMP3_SEL_TEMP_OS | BMP3_SEL_ODR;
    
        result = bmp3_set_sensor_settings(settings_sel, &bmp388);
    
        bmp388.delay_us(40000, bmp388.intf_ptr);
    
        printf("The sensor set result was %d\n", result);
        fflush(stdout);
    
        bmp388.settings.op_mode = BMP3_MODE_NORMAL;
        bmp3_set_op_mode(&bmp388);
        printf("power mode set result is: %d\n", result);
    
        while(1) {
            bmp388.delay_us(1000000, bmp388.intf_ptr);
    
            bmp3_get_sensor_data(sensor_comp, &data, &bmp388);
    
            printf("Sensor data temp: %lf press: %lf\n", data.temperature, data.pressure/100.0);
    
            printf("Analyzed sensor data: %d\n", analyze_sensor_data(&data));
            fflush(stdout);
            printf("\n");
            bmp388.delay_us(40000, bmp388.intf_ptr);
        }
    
    }
    
    BMP3_INTF_RET_TYPE bmpWrite(uint8_t reg_addr, const uint8_t *read_data, uint32_t len, void *intf_ptr) {
        // Signal the reg addr to be written to
        i2c_write_blocking(i2c0, addr, &reg_addr, sizeof(uint8_t), true);
        
        // Write to reg
        int8_t write_res = i2c_write_blocking(i2c0, addr, read_data, len, true);
        return write_res > 0 ? BMP3_INTF_RET_SUCCESS : BMP3_E_COMM_FAIL;
    }
    
    BMP3_INTF_RET_TYPE bmpRead(uint8_t reg_addr, uint8_t *read_data, uint32_t len, void *intf_ptr) {
        // To read, first write the register address wanting to be read
        i2c_write_blocking(i2c0, addr, &reg_addr, sizeof(uint8_t), true);
    
        int8_t write_result = i2c_read_blocking(i2c0, addr, read_data, len, true);
    
        return write_result > 0 ? BMP3_INTF_RET_SUCCESS : BMP3_E_COMM_FAIL;
    }
    
    BMP3_INTF_RET_TYPE bmpDelay(uint32_t amt, void *intf_ptr) {
        sleep_us(amt);
        return BMP3_INTF_RET_SUCCESS;
    }

     

     

    3 REPLIES 3
    FAE_CA1
    Community Moderator

    Re: BMP388 readings never change/implausible pressure (interfaced from Raspberry Pi Pico)

    Hi,

    Thanks for your inquiry.

    Please verify if you have two 10K Ohms pull-up resistors on I2C bus SDA and SCL lines. Also please check if you are able to read chip_ID back with the value of 0x50 or not. If yes, then your I2C read function works. Then you can write value to register 0x1D to change ODR for example and read register 0x1D back to see if you have successfully written the value to the register. If yes, then your I2C write function works.

    Thanks.

    SlightlyPunk
    New Poster

    Re: BMP388 readings never change/implausible pressure (interfaced from Raspberry Pi Pico)

    Hi, 

    Thanks for your response. The raspberry pi pico has internal programmable internal pullup resistors which I enabled with no effect (they may be on for I2C by default anyways). I was able to successfully get the chip ID but I was unable to get/set data from/to the ODR register. Below is the sample code.

    int8_t result = 0;
        int i = 0;
    
    
        // set up i2c stuff on the Pico
        i2c_init(i2c0, 40*1000);
        
        gpio_set_function(PICO_BMP_I2C_SDA_PIN, GPIO_FUNC_I2C);
        gpio_set_function(PICO_BMP_I2C_SCL_PIN, GPIO_FUNC_I2C);
        gpio_pull_up(PICO_BMP_I2C_SDA_PIN);
        gpio_pull_up(PICO_BMP_I2C_SCL_PIN);
    
        // Set the BMP388 struct to use I2C and self-defined read/write/delay funcs
        bmp388.intf = BMP3_I2C_INTF;
        bmp388.delay_us = (bmp3_delay_us_fptr_t)&bmpDelay;
        bmp388.read = (bmp3_read_fptr_t)&bmpRead;
        bmp388.write = (bmp3_write_fptr_t)&bmpWrite;
    
        /* Variable used to select the sensor component */
        uint8_t sensor_comp;
    
        // Use Pressure and Temperature readings    
        sensor_comp = BMP3_PRESS | BMP3_TEMP;
    
        /* Used to select the settings user needs to change */
        uint16_t settings_sel;
    
        /* Variable used to store the compensated data */
        struct bmp3_data data = { 0 };
    
    
        result = bmp3_soft_reset(&bmp388);
    
        bmp388.delay_us(40000, bmp388.intf_ptr);
    
        // for reply
        uint8_t chip_id = 0;
        result = bmp3_get_regs(BMP3_REG_CHIP_ID, &chip_id, 1, &bmp388);
        printf("Chip id is: %x, result is: %d\n", chip_id, result);
    
        uint8_t read_data = 1;
        uint8_t reg = 0x1D;
        result = bmp3_get_regs(reg, &read_data, 1, &bmp388);
        printf("ODR reg is : %x, result: %d\n", read_data, result);
        read_data = BMP3_ODR_25_HZ;
        result = bmp3_set_regs(&reg, &read_data, 1, &bmp388);
        printf("Result after write is: %d\n", result);
        result = bmp3_get_regs(reg, &read_data, 1, &bmp388);
        printf("ODR reg is : %x, result: %d\n", read_data, result);
    

     Where I get the following output: 

    Starting␍␊
    Chip id is: 50, result is: 0␍␊
    ODR reg is : 0, result: 0␍␊
    Result after write is: 0␍␊
    ODR reg is : 0, result: 0␍␊
    Finished␍␊
    FAE_CA1
    Community Moderator

    Re: BMP388 readings never change/implausible pressure (interfaced from Raspberry Pi Pico)

    Hi,

    It seems like your I2C write function is not working. After you write value of 0x03 to register 0x1D to set ODR to 25Hz, you should get the value of 0x03 back when you read register 0x1D again. But you got value of 0x00 back from register 0x1D.

    Thanks.

    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