Bosch Sensortec Community

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

    BMI055 reference driver for acceleration data

    BMI055 reference driver for acceleration data

    ysqcn
    Established Member

    Hi,

    From BMI055 spec: The width of acceleration data is 12 bits given in two´s complement representation. The 12 bits for each axis are split into an MSB upper part (one byte containing bits 11 to 4) and an LSB lower part (one byte containing bits 3 to 0 of acceleration and a (ACC 0x02, 0x04, 0x06) new_data flag)

    But in BMI055 reference driver:  https://github.com/BoschSensortec/BMG160_driver

    The caculation is: 

    *v_data_x_s16 = (s16)((((s32)((s8)v_data_u8[BMG160_X_MSB_DATA])) * 256) | (v_data_u8[BMG160_X_LSB_DATA]));

    It is a bit confused. Could you help to clarify?

    Thanks

    -Austin

     

    BMG160_RETURN_FUNCTION_TYPE bmg160_get_data_x(s16 *v_data_x_s16)
    {
        /* variable used to return the bus communication status*/
        BMG160_RETURN_FUNCTION_TYPE comres = BMG160_INIT_VALUE;
    
        /*Array holding the gyro data x LSB and MSB data
         * v_data_u8[0] - X LSB
         * v_data_u8[1] - X MSB
         */
        u8 v_data_u8[BMG160_X_DATA_SIZE] = { BMG160_INIT_VALUE, BMG160_INIT_VALUE };
    
        /* check the p_bmg160 struct pointer is NULL*/
        if (p_bmg160 == BMG160_NULL)
        {
            return E_BMG160_NULL_PTR;
        }
        else
        {
            /* read the gyro x data */
            comres = p_bmg160->BMG160_BUS_READ_FUNC(p_bmg160->dev_addr,
                                                    BMG160_RATE_X_LSB_BIT__REG,
                                                    v_data_u8,
                                                    BMG160_X_DATA_LENGTH);
            v_data_u8[BMG160_X_LSB_DATA] = BMG160_GET_BIT_POS0(v_data_u8[BMG160_X_LSB_DATA], BMG160_RATE_X_LSB_BIT);
    
            /* To avoid signed integer shifting, multiplication by the same factor of position shift is performed
             * i.e 8 places have been shifted left which is equivalent to multiplying by 256 */
            *v_data_x_s16 = (s16)((((s32)((s8)v_data_u8[BMG160_X_MSB_DATA])) * 256) | (v_data_u8[BMG160_X_LSB_DATA]));
        }
    
        return comres;
    }

     

    7 REPLIES 7

    ysqcn
    Established Member

    Firstly detect the ID. I  can get the expected (Gyro ID 0xf, and Acc ID: 0xfa)

        I2CCoreReadEx(etIsaImuGyro, I2C_IMU_BMI_ID_REG,
                                &u8, sizeof(u8), DA_SingleByte, DA_SingleByte, 0, 0, 0))  /* Gyro Chip Id: 0x0f */
    
    
        I2CCoreReadEx(etIsaImuGyro, I2C_IMU_BMI_ID_REG,
                                &u8, sizeof(u8), DA_SingleByte, DA_SingleByte, 0, 0, 0))  /* Accel chip Id: 0xfa */
    

     

     Then apply bellow init sequence: SoftReset, Configure:

    static imuBMIi2cData s_BMI_SoftReset[] = {
        IMU_BMI_I2C_DATA_INIT(etIsaImuAcc, I2C_IMU_BMI_SOFTRESET, BMI_SOFTRESET)
        IMU_BMI_I2C_DATA_INIT(etIsaImuGyro, I2C_IMU_BMI_SOFTRESET, BMI_SOFTRESET)
    };
    
    static imuBMIi2cData s_BMI_Gyro_cfg[] = {
        IMU_BMI_I2C_DATA_INIT(etIsaImuGyro, I2C_IMU_BMI_WDT, BMI_WDT_EN | BMI_WDT_50MS)
        IMU_BMI_I2C_DATA_INIT(etIsaImuGyro, I2C_GYRO_INT_MAP_1_REG, I2C_GYRO_MAP_INT1_DATA)
        IMU_BMI_I2C_DATA_INIT(etIsaImuGyro, I2C_GYRO_INT_EN_1_REG, I2C_GYRO_INT1_LVL)
        IMU_BMI_I2C_DATA_INIT(etIsaImuGyro, I2C_GYRO_INT_EN_0_REG, I2C_GYRO_INT_DATA_EN)
        IMU_BMI_I2C_DATA_INIT(etIsaImuGyro, I2C_IMU_PMU_RANGE_REG, I2C_GYRO_RANGE_1000)
        // NL, keep BMI_SUSPEND last
        IMU_BMI_I2C_DATA_INIT(etIsaImuGyro, I2C_IMU_BMI_LP_REG, BMI_SUSPEND)
    };
    
    static imuBMIi2cData s_BMI_Acc055_cfg[] = {
        IMU_BMI_I2C_DATA_INIT(etIsaImuAcc, I2C_IMU_BMI_WDT, BMI_WDT_EN | BMI_WDT_50MS)
        IMU_BMI_I2C_DATA_INIT(etIsaImuAcc, I2C_ACC_INT_MAP_1_REG, I2C_ACC_MAP_INT1_DATA)
        IMU_BMI_I2C_DATA_INIT(etIsaImuAcc, I2C_ACC_INT_EN_1_REG, I2C_ACC_INT_DATA_EN)
        IMU_BMI_I2C_DATA_INIT(etIsaImuAcc, I2C_IMU_PMU_RANGE_REG, I2C_ACC_PMU_RANGE_4G)
        // NL, keep BMI_SUSPEND last
        IMU_BMI_I2C_DATA_INIT(etIsaImuAcc, I2C_IMU_BMI_LP_REG, BMI_SUSPEND)
    };

     

    Then continouly poll gyro and accel : firstly pull gyro, then accel, then gryo, then accel......

        /* From DateReg(0x2) read 6 bytes (I2C_IMU_DATA_SIZE) */
        ret = I2CCoreReadEx(s_SensorI2CAddr[dev], s_I2CBMIRegs[dev][eDataReg],
                            pBuffer->IMU_data, I2C_IMU_DATA_SIZE, DA_SingleByte, DA_SingleByte, 100, 0, 10);

     

    The Accel data looks reasonable, and each sample with slight change.

    But Gyro data each sample change siginificantly

     

    BSTRobin
    Community Moderator
    Community Moderator

    Hello ysqcn,

    You could refer the following code to get BMI055 data.

    #define BMI055_GYR_X_L_ADDR UINT8_C(0x02)

    int8_t bmi055_get_gyro_data(struct bmi055_sensor_data *gyro, const struct bmi055_dev *dev)
    {
    int8_t rslt;
    uint8_t index = 0, data_array[6] = { 0 };
    uint16_t lsb = 0, msb = 0, msblsb = 0;

    /* Null-pointer check */
    rslt = bmi055_gyro_null_ptr_check(dev);
    if (rslt == BMI055_OK)
    {
    /* Read accelerometer sensor data */
    rslt = bmi055_get_gyro_regs(BMI055_GYR_X_L_ADDR, data_array, 6, dev);
    if (rslt == BMI055_OK)
    {
    /* Parse X-axis accelerometer data */
    lsb = (uint16_t)data_array[index++];
    msb = ((uint16_t)data_array[index++]) << 8;
    msblsb = msb | lsb;
    gyro->x = (int16_t)msblsb;

    /* Parse Y-axis gyroscope data */
    lsb = (uint16_t)data_array[index++];
    msb = ((uint16_t)data_array[index++]) << 8;
    msblsb = msb | lsb;
    gyro->y = (int16_t)msblsb;

    /* Parse Z-axis accelerometer data */
    lsb = (uint16_t)data_array[index++];
    msb = ((uint16_t)data_array[index++]) << 8;
    msblsb = msb | lsb;
    gyro->z = (int16_t)msblsb;
    }
    else
    {
    /* Communication fail */
    rslt = BMI055_E_COM_FAIL;
    }
    }

    return rslt;
    }

    ysqcn
    Established Member

    Thank you . Issue solved.

    There is init failure issue. After it is fixed, the sample is stable now

    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