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:  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
 
 
Best reply by somml

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.

Regards
Kevin

View original
7 replies
Resolved