Bosch Sensortec Community

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

    BMI270 I2C with Raspberry Pi 3B+

    BMI270 I2C with Raspberry Pi 3B+

    somml
    Member

    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:  http://wiringpi.com/
    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:

    ------START------

    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

    ------END------

    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
    Kevin


    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;


    // 8192 elements - THIS CONFIG FILE WAS SHORTED FOR FORUMS POST
    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;
    }
    else
    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;

    // --------------------------------------
    // INITIALIZATION - AREA
    // --------------------------------------

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

    // Load config file
    wiringPiI2CWriteReg8(fd, BMI2_PWR_CONF_ADDR, 0x00);
    usleep(450);
    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";

    // --------------------------------------
    // CONFIGURATION - AREA
    // --------------------------------------

    // 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;
    }

    // --------------------------------------
    // FUNCTIONS - AREA
    // --------------------------------------

    // REMOVED FOR FORUMS POST
     
     
    7 REPLIES 7

    somml
    Member

    Not sure if this information helps but I wanted to also add it.
    As mentioned in my previous post I managed to received the gyro data from the BMI160 through a python script with a specific library for this IMU.

    Now I've tried reading out the gyro data of the BMI270 with smbus2 for python.
    I have noticed a command in there:
    read_i2c_block_data(..)

    Which i used to read out the 0x16 (DATA_18 -  gyr_z_7_0)  register in this way (most likely the wrong way, but at least I finally received a different output than 0):
    print("data: " + str(bus.read_i2c_block_data(BMI270_ADDR, 0x16, 12)))

    Output Logs:
    data: [0, 0, 69, 147, 243, 0, 0, 0, 0, 0, 0, 0]
    data: [0, 0, 235, 147, 243, 0, 0, 0, 0, 0, 0, 0]
    data: [0, 0, 251, 255, 243, 0, 0, 0, 0, 0, 0, 0]
    data: [0, 0, 251, 255, 243, 0, 0, 0, 0, 0, 0, 0]
    data: [0, 0, 251, 255, 243, 0, 0, 0, 0, 0, 0, 0]
    data: [0, 0, 251, 255, 243, 0, 0, 0, 0, 0, 0, 0]
    data: [0, 0, 251, 255, 243, 0, 0, 0, 0, 0, 0, 0]
    data: [0, 0, 251, 255, 243, 0, 0, 0, 0, 0, 0, 0]
    data: [0, 0, 251, 255, 243, 0, 0, 0, 0, 0, 0, 0]
    data: [0, 0, 251, 255, 243, 0, 0, 0, 0, 0, 0, 0]
    data: [0, 0, 251, 255, 243, 0, 0, 0, 0, 0, 0, 0]

    Not sure why it gets stuck at these numbers and most likely the format is wrong too. But maybe someone knows which direction to point me to.

     

    Best Regards
    Kevin

    BSTRobin
    Community Moderator
    Community Moderator

    Hi somml,

    You need to make sure the BMI270 hardware is connected correctly as you use I2C communication.

    BMI270 primary I2C secondary none.png
    We had little experience about Raspberry Pi 3B+. Official BMI270 sensor API code was written by C language, there are example code on github https://github.com/boschsensortec/BMI270-Sensor-API, you could refer them and migrate them to your platform.

    Thanks for your reply.
    The BMI270 (with breakout board) is connected properly to the Raspberry Pi. Still when reading out the data registers, I only receive zeros.
    When trying to read out data with the same setup but the BMI160 instead, I can read out the data registers and receive values.

    Also when using the Official BMI270 sensor API code on github which you linked, I receive this error when executing:
    Error [-9] : Configuration load error. It occurs when failure observed while loading the configuration into the sensor


    What could be the problem?

    Best Regards
    Kevin

    BSTRobin
    Community Moderator
    Community Moderator

    Hi somml,

    There are different BMI270 configuration file versions, and different configuration file versions have different features.
    If you you used BMI270 base version, you should load the configuration array bmi270_config_file[] in file bmi270.c, add refer to the procedure for loading configuration file in function bmi2_write_config_file() in file bmi2.c.

     

    BMI270 (base)

    • Any motion, No motion, Significant motion detectors
    • Wrist worn Step counter and Step detector (Pedometer)
    • Activity change recognition
      • Still
      • Walking
      • Running
    • Wrist gestures
      • Push arm down
      • Pivot up
      • Wrist shake jiggle
      • Flick in
      • Flick out
    • Wrist wear wake up

     

    BMI270 Context

    • Step counter and Step detector (Pedometer)
    • Activity change recognition
      • Still
      • Walking
      • Running

     

    BMI270 Legacy

    • Any motion, No motion, Significant motion detector
    • Orientation detector (Advanced Potrait-Landscape)
    • High-G, Low-G (Freefall) detector
    • Flat detector
    • Tap detection (Single, Double, Triple taps)
    • Smartphone Step counter and Step detector (Pedometer)
    • Activity change recognition
      • Still
      • Walking
      • Running

     

    BMI270 Maximum FIFO

    • Supports a 6kB FIFO
    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