Bosch Sensortec Community

    BMI088 giving wrong Accelerometer values

    Highlighted
    New Poster

    BMI088 giving wrong Accelerometer values

    I used nRF52840 to drive bmi088 and successfully got the ID value of the accelerometer. The gyroscope can also get the ID value normally, but I modified the driver given by github, which is similar to the function of reading the accelerometer ID value, and the redundant previous byte is discarded to get the gyroscope ID normally value. Here are the changes I made in bmi08g.c

    static int8_t get_regs(uint8_t reg_addr, uint8_t *reg_data, uint16_t len, const struct bmi08x_dev *dev)
    {
        int8_t rslt;
        uint16_t index;
        uint16_t temp_len = len + dev->dummy_byte;
        uint8_t temp_buff[temp_len];
    
        if (dev->intf == BMI08X_SPI_INTF)
        {
            /* Configuring reg_addr for SPI Interface */
            reg_addr = reg_addr | BMI08X_SPI_RD_MASK;
        }
    
        /* Read the data from the register */
        rslt = dev->read(dev->gyro_id, reg_addr, temp_buff, temp_len);
    
        if (rslt == BMI08X_OK)
        {
            for (index = 0; index < len; index++)
            {
                /* Updating the data buffer */
                reg_data[index] = temp_buff[index + dev->dummy_byte];
            }
        }
        else
        {
            /* Failure case */
            rslt = BMI08X_E_COM_FAIL;
        }
    
        return rslt;
    }

    After getting the chip ID value, I continued to initialize the BMI088.

    struct bmi08x_dev bmi088_dev = 
    {
        .accel_id = MCU_GPIO_BMI088_CSB1,
        .gyro_id  = MCU_GPIO_BMI088_CSB2,
        .intf     = BMI08X_SPI_INTF,
        .read     = user_bmi088_spi_read,
        .write    = user_bmi088_spi_write,
        .delay_ms = user_delay_milli_sec,
    };
    
    static void official_bmi088_init(void)
    {
        struct bmi08x_data_sync_cfg bmi088_sync_cfg;
        int8_t rslt;
        uint8_t data = 0;
    
        bmi08a_soft_reset(&bmi088_dev);
        nrf_delay_ms(50);
        if (rslt == BMI08X_OK) 
        {
            /* Initializing the bmi088 sensors the below function will Initialize both accel and gyro sensors*/
            rslt = bmi08a_init(&bmi088_dev);
            if (rslt == BMI08X_OK) 
            {
                bmi088_dev.accel_cfg.odr = BMI08X_ACCEL_ODR_1600_HZ;
                bmi088_dev.accel_cfg.range = BMI088_ACCEL_RANGE_24G;
                bmi088_dev.accel_cfg.power = BMI08X_ACCEL_PM_ACTIVE; //user_accel_power_modes[user_bmi088_accel_low_power];
                bmi088_dev.accel_cfg.bw = BMI08X_ACCEL_BW_NORMAL; /* Bandwidth and OSR are same */
                bmi088_dev.accel_cfg.power = BMI08X_ACCEL_PM_ACTIVE;
                rslt = bmi08a_set_power_mode(&bmi088_dev);
                nrf_delay_ms(50);
                if (rslt == BMI08X_OK) 
                {
                    rslt = bmi08a_set_meas_conf(&bmi088_dev);
                    nrf_delay_ms(50);
                    if (rslt == BMI08X_OK)
                    {
                        NRF_LOG_INFO("bmi088 init all done.");
                    }
                    else
                    {
                        NRF_LOG_ERROR("bmi08a set meas conf error: %d.", rslt);
                    }
                        
                }            
                else
                {
                    NRF_LOG_ERROR("bmi08a set power mode error: %d.", rslt);
                }
            }
            else
            {
                NRF_LOG_ERROR("bmi08a init error: %d.", rslt);
            }
        }
        else
        {
            NRF_LOG_ERROR("bmi08a soft reset error: %d.", rslt);
        }
    }

    Everything looks normal. But when I want to take the acceleration value, the value taken to the x-axis, y-axis, and z-axis is always a constant error value.

    rslt = bmi08a_get_data(&user_accel_bmi088, &bmi088_dev);
        if (rslt == BMI08X_OK)
        {
    
            accel_y = (double)user_accel_bmi088.y;
            accel_z = (double)user_accel_bmi088.z;
            
            #ifdef USER_UART_ENABLED
            printf("accel x in mg: %lf\r\n", accel_x);
            printf("accel y in mg: %lf\r\n", accel_y);
            printf("accel z in mg: %lf\r\n", accel_z);
            #endif
        }
        else
        {
            NRF_LOG_ERROR("bmi08a get data error: %d.", rslt);
        }

    Is there anything wrong with my operation? How do I get the correct acceleration value?

    By the way in order that you can quickly locate the problem, I will send the mapping code of the SPI I read and write, as follows:

    void spi_bmi088_event_handler(nrf_drv_spi_evt_t const * p_event,
                                  void *                    p_context)
    {
        spi_bmi088_xfer_done = true;
        NRF_LOG_INFO("Spi bmi088 transfer completed.");
    //    if (m_rx_buf[0] != 0)
    //    {
    //        NRF_LOG_INFO(" Received:");
    //        NRF_LOG_HEXDUMP_INFO(m_rx_buf, strlen((const char *)m_rx_buf));
    //    }
    }
    
    static void spi_bmi088_init(void)
    {
        nrf_drv_spi_config_t spi_bmi088_config = NRF_DRV_SPI_DEFAULT_CONFIG;
        nrf_gpio_cfg_output(MCU_GPIO_BMI088_CSB1);
        nrf_gpio_cfg_output(MCU_GPIO_BMI088_CSB2);
        nrf_delay_ms(10);
        nrf_gpio_pin_set(MCU_GPIO_BMI088_CSB1);
        nrf_gpio_pin_set(MCU_GPIO_BMI088_CSB2);
        spi_bmi088_config.ss_pin   = NRF_DRV_SPI_PIN_NOT_USED;
        spi_bmi088_config.miso_pin = SPI_BMI088_MISO_PIN;
        spi_bmi088_config.mosi_pin = SPI_BMI088_MOSI_PIN;
        spi_bmi088_config.sck_pin  = SPI_BMI088_SCK_PIN;
        APP_ERROR_CHECK(nrf_drv_spi_init(&spi_0, &spi_bmi088_config, spi_bmi088_event_handler, NULL));
    }
    
    int8_t user_bmi088_spi_write(uint8_t cs_pin, uint8_t reg_addr, uint8_t *data, uint16_t len)
    {
        if (cs_pin == MCU_GPIO_BMI088_CSB1)
        {
            nrf_gpio_pin_set(MCU_GPIO_BMI088_CSB2);
            nrf_gpio_pin_clear(MCU_GPIO_BMI088_CSB1);
        }
        else if (cs_pin == MCU_GPIO_BMI088_CSB2)
        {
            nrf_gpio_pin_set(MCU_GPIO_BMI088_CSB1);
            nrf_gpio_pin_clear(MCU_GPIO_BMI088_CSB2);
        }
        else if ((cs_pin != MCU_GPIO_BMI088_CSB1) && (cs_pin != MCU_GPIO_BMI088_CSB2))
        {
            return -2;
        }
        nrf_delay_us(1);
        if (len <= 32)
        {
            uint8_t m_tx_buf[33] = {0};
            m_tx_buf[0] = reg_addr;
            uint8_t m_tx_length = ((uint8_t)len) + 1;
    //        const uint8_t m_rx_length = 0;
            memcpy(&m_tx_buf[1], &data, len);
    
            spi_bmi088_xfer_done = false;
    
            APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi_0, m_tx_buf, m_tx_length, NULL, 0));
            while(!spi_bmi088_xfer_done)
            {
                __WFE();
            }
        }
        else
        {
            NRF_LOG_INFO("Spi write over length.");
        }
        nrf_delay_us(1);
        nrf_gpio_pin_set(cs_pin);
    
        return 0;
    }
    
    int8_t user_bmi088_spi_read(uint8_t cs_pin, uint8_t reg_addr, uint8_t *data, uint16_t len)
    {
        if (cs_pin == MCU_GPIO_BMI088_CSB1)
        {
            nrf_gpio_pin_set(MCU_GPIO_BMI088_CSB2);
            nrf_gpio_pin_clear(MCU_GPIO_BMI088_CSB1);
        }
        else if (cs_pin == MCU_GPIO_BMI088_CSB2)
        {
            nrf_gpio_pin_set(MCU_GPIO_BMI088_CSB1);
            nrf_gpio_pin_clear(MCU_GPIO_BMI088_CSB2);
        }
        else if ((cs_pin != MCU_GPIO_BMI088_CSB1) && (cs_pin != MCU_GPIO_BMI088_CSB2))
        {
            return -2;
        }
        nrf_delay_us(1);
        if (len <= 32)
        {
            uint8_t m_tx_buf[33] = {reg_addr};
            uint8_t m_tx_length = (uint8_t)len+1;
            uint8_t m_rx_length = (uint8_t)len+1;
    				
            spi_bmi088_xfer_done = false;
    
            APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi_0, m_tx_buf, m_tx_length, data, m_rx_length));
            while(!spi_bmi088_xfer_done)
            {
                __WFE();
            }
        }
        else
        {
            NRF_LOG_INFO("Spi read over length.");
        }
        nrf_delay_us(1);
        nrf_gpio_pin_set(cs_pin);
    
        return 0;
    }

    Hope to be answered quickly!

    Thanks a lot!

    2 REPLIES 2
    Highlighted
    New Poster

    Re: BMI088 giving wrong Accelerometer values

    By the way, in order to solve the call to the bmi088_init function, where bmi08g_init reports an error BMI08X_E_DEV_NOT_FOUND, I modified the get_regs function in bmi08g.c

    Highlighted
    New Poster

    Re: BMI088 giving wrong Accelerometer values

    But I did not call bmi088_init again, but used bmi08a_init because I only need to take the value of the accelerometer.

    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