Bosch Sensortec Community

    Showing results for 
    Search instead for 
    Did you mean: 

    BMI270 I2C with Raspberry Pi 3B+

    BMI270 I2C with Raspberry Pi 3B+


    Hello everyone,

    I am a student and currently in my practical phase. I am trying to figure out what I am doing wrong when trying to read out the gyro data of the BMI270 for example.

    I tried to compile the official Sensor API on Github but ran into error codes with COINES (i installed it) while compiling, so I used the latest version v2-53-2 which was without COINES, compiled it and ran into this error:
    Error [-9] : Configuration load error. It occurs when failure observed while loading the configuration into the sensor

    Which I couldn't figure out how to solve, so I started to write my own code as I really only want to read out the gyro data itself.
    I connected the BMI270 via the quickconnect cable to the Raspberry Pi pins 1 (3.3 VDC), 3 (GPIO8 SDA1 (I2C)), 5 (GPIO 9 SCL1 (I2C)) and 9 (ground).

    I am currently using the WiringPi library found here:
    Essentially these are all the functions from the WiringPi libary for I2C:
    int wiringPiI2CRead (int fd) ;
    int wiringPiI2CWrite (int fd, int data) ;
    int wiringPiI2CWriteReg8 (int fd, int reg, int data) ;
    int wiringPiI2CWriteReg16 (int fd, int reg, int data) ;
    int wiringPiI2CReadReg8 (int fd, int reg) ;
    int wiringPiI2CReadReg16 (int fd, int reg) ;

    There are also these functions which I wasn't able to use yet because I didn't know how I should give this function the dPin and cPin, though I saw that the cPin is 13 and dPin is 14 in the Datasheet.
    uint8_t shiftIn (uint8_t dPin, uint8_t cPin, uint8_t order) ;
    void shiftOut (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val) ;

    In general I tried following the Quickstart Guide in the BMI270 Datasheet when writing my code.

    Console logs of my code:


    Device found!

    DEVICE_ID: 3
    CHIP_ID: 0x24
    WRITING DATA ......... --> LAST DATA: 0xC1
    Initialization status: 00000000 (Bit 0 = 1 --> OK)
    7D before: 00001110
    7D after: 00001110
    40 before: 10101000
    40 after: 10101000
    42 before: 11101001
    42 after: 11101001
    7C before: 00000000
    7C after: 00000010
    rateX -8-Data_14: 0
    rateX2-8-Data_15: 0
    rateY -8-Data_16: 0
    rateY2-8-Data_17: 0
    rateZ -8-Data_18: 0
    rateZ2-8-Data_19: 0
    rateX -8-Data_14: 0
    rateX2-8-Data_15: 0
    rateY -8-Data_16: 0
    rateY2-8-Data_17: 0
    rateZ -8-Data_18: 0
    rateZ2-8-Data_19: 0
    rateX -8-Data_14: 0
    rateX2-8-Data_15: 0
    rateY -8-Data_16: 0
    rateY2-8-Data_17: 0
    rateZ -8-Data_18: 0
    rateZ2-8-Data_19: 0


    My burst_write function is essentially just using wiringPiI2CWriteReg8(..) in a for loop. Not sure if that would be the right way to do it when you want to upload the config file. But I believe it is probably not, because when I read out the Initialization status I alway receive a 0 for the Bit 0, which according to the Datasheet means its "not ok".

    All in all I believe setting bits in the register works, but for some reason I can't read out data, probably because I am doing it wrong I believe. Also I tried out a very simple python code with the BMI160 and a compatible python Driver for it to test if the I2C even works and it seems to give me data there. I didn't try anything in python with the BMI270 yet because I wanted to keep it in C/C++. Maybe there could also be a problem with the WiringPi library I am using. Or I am just missing a specific register which I didn't set properly yet?
    Or recommend me a different library which I could use or even post a code sample which works simliar to mine without using the Sensor API of Bosch.

    Hopefully someone can help me bringt light into this. 🙂

    Best Regards

    This is how my code looks at the moment:

    #include <stdio.h>
    #include <stdint.h>
    #include <unistd.h>
    #include <iostream>
    #include <bitset>

    #include <wiringPiI2C.h>
    #include <wiringShift.h>

    #include "bmi2_defs.h"

    #define BIT_8 UINT8_C(8)
    #define BIT_16 UINT8_C(16)

    #define DATA_14 UINT8_C(0x12) // GYR_X(LSB) - gyr_x_7_0
    #define DATA_15 UINT8_C(0x13) // GYR_X(MSB) - gyr_x_15_8
    #define DATA_16 UINT8_C(0x14) // GYR_Y(LSB) - gyr_y_7_0
    #define DATA_17 UINT8_C(0x15) // GYR_Y(MSB) - gyr_y_15_8
    #define DATA_18 UINT8_C(0x16) // GYR_Z(LSB) - gyr_z_7_0
    #define DATA_19 UINT8_C(0x17) // GYR_Z(MSB) - gyr_z_15_8

    using std::bitset;
    using std::cout;
    using std::endl;
    using std::hex;
    using std::uppercase;
    using std::string;

    const uint8_t bmi270_config_file[] = { 0xc8, 0x2e, 0x00, ..., 0x2e, 0x00, 0xc1};

    // -----------------------------------------------------------------------------------

    void burst_write_reg(int fd, int reg, int array_len, const uint8_t *data, int format);
    void burst_read_reg(int fd, int reg, int len, int format);
    void configure_reg(int fd, int reg, int value, int format);

    int main()
    // --------------------------------------
    // START - AREA
    // --------------------------------------

    cout << "\n\n------START------\n\n";

    int fd = wiringPiI2CSetup(BMI2_I2C_PRIM_ADDR);
    if (fd == -1)
    cout << "ERROR: Device not found!\n\n";
    return -1;
    cout << "Device found!\n\n";

    cout << "DEVICE_ID: " << fd << endl;

    int chipID = wiringPiI2CReadReg8(fd, BMI2_CHIP_ID_ADDR);
    cout << "CHIP_ID: 0x" << hex << chipID << endl;

    // --------------------------------------
    // --------------------------------------

    // Reset the device
    #if 0
    configure_reg(fd, BMI2_CMD_REG_ADDR, BMI2_SOFT_RESET_CMD, BIT_8);

    // Load config file
    wiringPiI2CWriteReg8(fd, BMI2_PWR_CONF_ADDR, 0x00);
    wiringPiI2CWriteReg8(fd, BMI2_INIT_CTRL_ADDR, 0x00);
    burst_write_reg(fd, BMI2_INIT_CTRL_ADDR, 8192, bmi270_config_file, BIT_8);
    wiringPiI2CWriteReg8(fd, BMI2_INIT_CTRL_ADDR, 0x01);
    // Check initialization status (Bit 0 = 1 --> OK)
    bitset<8> binary_initialization(wiringPiI2CReadReg8(fd, BMI2_INTERNAL_STATUS_ADDR));
    cout << "Initialization status: " << binary_initialization << "\t\t(Bit 0 = 1 --> OK)\n";

    // --------------------------------------
    // --------------------------------------

    // Configuring the device for performance mode
    // enable acquisiton of acceleration, gyroscope and temperature sensor data. disable the auxiliary interface.
    configure_reg(fd, BMI2_PWR_CTRL_ADDR, 0x0E, BIT_8);

    // enable the acc_filter_perf bit; set acc_bwp to normal mode; set acc_odr to 100 Hz
    configure_reg(fd, BMI2_ACC_CONF_ADDR, 0xA8, BIT_8);

    // enable the gyr_filter_perf bit; enable gyr_noise_perf bit; set gyr_bwp to normal mode; set gyr_odr to 200 Hz
    configure_reg(fd, BMI2_GYR_CONF_ADDR, 0xE9, BIT_8);

    // disable the adv_power_save bit; leave the fifo_self_wakeup enabled
    configure_reg(fd, BMI2_PWR_CONF_ADDR, 0x02, BIT_8);

    // --------------------------------------
    // OUTPUT - AREA
    // --------------------------------------

    int LOOPS = 3;
    for (int i = 0; i < LOOPS; i++)
    int rateX = wiringPiI2CReadReg8(fd, DATA_14);
    // rateY = -(~(int8_t)rateY + 1);
    cout << "rateX -8-Data_14: " << rateX << endl;
    int rateX2 = wiringPiI2CReadReg8(fd, DATA_15);
    cout << "rateX2-8-Data_15: " << rateX2 << endl;
    int rateY = wiringPiI2CReadReg8(fd, DATA_16);
    cout << "rateY -8-Data_16: " << rateY << endl;
    int rateY2 = wiringPiI2CReadReg8(fd, DATA_17);
    cout << "rateY2-8-Data_17: " << rateY2 << endl;
    int rateZ = wiringPiI2CReadReg8(fd, DATA_18);
    cout << "rateZ -8-Data_18: " << rateZ << endl;
    int rateZ2 = wiringPiI2CReadReg8(fd, DATA_19);
    cout << "rateZ2-8-Data_19: " << rateZ2 << endl;

    // --------------------------------------
    // END - AREA
    // --------------------------------------

    cout << "\n\n------END------\n\n";
    return 0;

    // --------------------------------------
    // --------------------------------------

    7 REPLIES 7

    Thanks for your response.

    Essentially I didn't change any code from the official BMI270-Sensor-API on Github when using it, if you are referring to that. Still the issue of not beeing able to load the config into the BMI270 persists. I feel that loading the config is necessary to even use the BMI270 because otherwise I won't receive any data from the DATA_X registers. Having no problems receiving data from the BMI160. Either way, loading the config through the "official" way doesn't work and also not in my own way. So I don't understand what the problem with this sensor is. I have two BMI270 and for both sensors the config won't load. I don't think that both sensors would have some internal problems, but I really tried a lot since the last 2 weeks to get this thing up and running.


    Community Moderator
    Community Moderator

    Hi somml,

    See it from your previous software code, you didn't use BMI270 sensor API to access BMI270.

    Yes I did not use the BMI270 sensor API to access the BMI270 because as explained before using it without any modifications, multiple versions of the API it didn't work for me.
    Either way I managed to get it working with my own code now.