Bosch Sensortec Community

    cancel
    Showing results for 
    Search instead for 
    Did you mean: 
    SOLVED

    BMX160 accel. and gyro. values ajustment

    BMX160 accel. and gyro. values ajustment

    JayLynkz
    New Poster

    Hi, 

    This is my init function for the BMI160. I just want to test the accel and the gyro data. 

    The data I get doesn't seem valid. When the device is flat, I get around 0 for X and around 0 for Y, and the Z value is around 17 000.

    If the measurement is in mg, I would expect it to be around 1000. When I add the FOC (as you can see in the code below), the Z value for the same situation turns around 9500 (see picture). 

    Should I be seeing results around 1000 mg or is it normal to add a formula to set them around 1000 manually ?

    Thank you 

    Jerome

     
     

     

     

    int8_t initBMI160(struct bmi160_dev *dev){
    
        int8_t rslt = BMI160_OK;
    
        dev->id = BMI_DEVICE_ID;
        dev->interface = BMI160_SPI_INTF;
        dev->read = bosch_read_regs;
        dev->write = bosch_write_regs;
        dev->delay_ms = nrf_delay_ms;
    
        
        /* Configure device structure for auxiliary sensor parameter BMM150 */
        dev->aux_cfg.aux_sensor_enable = 1; // auxiliary sensor enable
        dev->aux_cfg.aux_i2c_addr = BMI160_AUX_BMM150_I2C_ADDR; // auxiliary sensor address
        dev->aux_cfg.manual_enable = 1; // setup mode enable
        dev->aux_cfg.aux_rd_burst_len = 2;// burst read of 2 byte
    
        rslt = bmi160_init(dev);
    
        /* Select the Output data rate, range of accelerometer sensor */
        dev->accel_cfg.odr = BMI160_ACCEL_ODR_1600HZ;
        dev->accel_cfg.range = BMI160_ACCEL_RANGE_2G;
        dev->accel_cfg.bw = BMI160_ACCEL_BW_NORMAL_AVG4;
    
        /* Select the power mode of accelerometer sensor */
        dev->accel_cfg.power = BMI160_ACCEL_NORMAL_MODE;
    
        /* Select the Output data rate, range of Gyroscope sensor */
        dev->gyro_cfg.odr = BMI160_GYRO_ODR_3200HZ;
        dev->gyro_cfg.range = BMI160_GYRO_RANGE_2000_DPS;
        dev->gyro_cfg.bw = BMI160_GYRO_BW_NORMAL_MODE;
    
        /* Select the power mode of Gyroscope sensor */
        dev->gyro_cfg.power = BMI160_GYRO_NORMAL_MODE; 
    
        /* Set the sensor configuration */
        rslt = bmi160_set_sens_conf(dev);
        
        /* Initialize the auxiliary sensor interface */
        rslt = bmi160_aux_init(dev);
    
    
        /* Initialize the Fast Offset Compensation (FOC) */
    
        const struct bmi160_foc_conf foc_conf =
        {
            .foc_gyr_en = BMI160_ENABLE,
            .foc_acc_x = BMI160_FOC_ACCEL_0G,
            .foc_acc_y = BMI160_FOC_ACCEL_0G,
            .foc_acc_z = BMI160_FOC_ACCEL_NEGATIVE_G,
            .acc_off_en = BMI160_ENABLE,
            .gyro_off_en = BMI160_ENABLE
        };
        
        struct bmi160_offsets offset;
    
        offset.off_acc_x = 0;
        offset.off_acc_y = 0;
        offset.off_acc_z = 0;
        offset.off_gyro_x = 0;
        offset.off_gyro_y = 0;
        offset.off_gyro_z = 0;
    
    
        bmi160_start_foc(&foc_conf, &offset, dev);
        nrf_delay_ms(255);
    
    
        return rslt;
    }

     

     

     

    3 REPLIES 3

    xinyi
    Member

    Dear Sir,

    Yes, raw data you read from sensor should be converted.

    acc actual data = raw data * acc range/2^16(16 bit).

    gyro actual data = raw data * gyro range/2^16(16 bit).

    we have the reference code in Sensor API.

    https://www.bosch-sensortec.com/products/   -> Github, get  latest sensor API code.

    fish
    Community Moderator
    Community Moderator

    Hi,

    Maybe this function can help you calculate mg. 

    /*!
    * @brief This internal API is used to convert lsb to mg
    *
    * @param[in] val: value, accel raw data
    * @param[in] range: range value, ACCEL_RANGE_2G/4G...
    * @param[in] bit_width, 12 or 16 bit
    *
    * @return float value in mg
    *
    */

    float lsb_to_mg(int16_t val, float g_range, uint8_t bit_width)
    {
    float half_scale = (float)(1 << bit_width) / 2.0f;

    return 1000.0f * val * g_range / half_scale;
    }

    Thank you for your answers!

    Both solutions work, Xinyi's one being more intuitive (though I had to multiply the result by 2), and Fish's one being more complicated, but accurate (and I guess it is more optimized cpu speed wise). 

     

    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