Bosch Sensortec Community

    Showing results for 
    Search instead for 
    Did you mean: 

    BMX160 accel. and gyro. values ajustment

    BMX160 accel. and gyro. values ajustment

    New Poster


    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 





    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-> = 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-> = 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);
        return rslt;




    3 REPLIES 3


    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.   -> Github, get  latest sensor API code.

    Community Moderator
    Community Moderator


    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).