BMI160 INIT with Arduino UNO - SPI 4 wire communication.

Hello everybody,

That’s my first post, if there is any problems, would you excuse me.

So, here is my problem :

I would like to use the IMU BMI160 with an arduino UNO …
First question : Am i the first ? I didn’t find any topic with this configuration in many forum.

First of all, I don’t use the Library CurieIMU.h and BMI160.h

My problem is that i try to initialize my BMI160 on my setup() (code below) but it doesn’t work. I think my real problem is that the NVM is not enable.

Registers of configuration of the BMI160 (0x1B and 0x03) feed me back that ACC and GYRO are Enable but not the non volatile memory (NVM).

The initialization of the BMI160 was copy in the Library BMI160.h (BMI160.cpp).

you will find below my init process with communication functions. If you want to build it, it works and write you back (0x1B and 0x03).

Is there anybody who had the same problem or did it like me ?

Thanking you in advance,

Waiting to reading you.

// the sensor communicates using SPI, so include the library:
#include <SPI.h>
#include <SD.h>
#include <avr/wdt.h>


//usefull register
const int BMI160_RA_CMD = 0x7E;

const int BMI160_CMD_START_FOC        =0x03;
const int BMI160_CMD_ACC_MODE_NORMAL  =0x11;
const int BMI160_CMD_GYR_MODE_NORMAL  =0x15;
const int BMI160_CMD_MAG_MODE_NORMAL  =0x19;
const int BMI160_CMD_STEP_CNT_CLR     =0xB2;
const int BMI160_CMD_SOFT_RESET       =0xB6;

const int DATA_RATE = 0b00101100; // 160 Hz
const int GYRO_RANGE = 0b00000100; // GYRO_RAGE -> +- 125°/s : 3.8m°/LSB
const int ACC_RANGE = 0b00001111; //+- 2g
const int IF_CONF =   0b00000001; // SPI Enable
const int NV_CONF =   0b00000000; //SPI 4 wire Enable
const int READ = 0b10000000; // MSB READ or WRITE + 7 bit d'adresse
const int WRITE = 0b01111111; // MSB READ or WRITE + 7 bit d'adresse

const int chipSelectSD = 4;
const int chipSelectBMI160 =10;
const int RED_LED = 6;
const int GREEN_LED = 7;
const int YELLOW_LED = 5;
const bool RST_SWITCH = 3;
const int RUN_PIN = 2;

void setup() {
  Serial.begin(9600);
    // start the SPI library:
  SPI.begin(); 
  
  /*-------- SPI ENABLE BMI160 --------*/
  digitalWrite(chipSelectBMI160, LOW);
  digitalWrite(chipSelectBMI160, HIGH);

/*-------- BMI 160 INIT -------------*/
  digitalWrite(YELLOW_LED,HIGH);


  
  
  writeRegister (BMI160_RA_CMD, BMI160_CMD_SOFT_RESET); //soft reset to clean register
  delay(200);
  readRegister(0x7F);
  delay(1);
  writeRegister (0x70, NV_CONF);
  delay(200);
  writeRegister (BMI160_RA_CMD, BMI160_CMD_ACC_MODE_NORMAL); //power up acc
  delay(600);
  writeRegister(BMI160_RA_CMD, BMI160_CMD_GYR_MODE_NORMAL); //power up gyr
  delay(600);
  writeRegister (0x043,GYRO_RANGE); // GYRO_RAGE -> +- 125°/s : 3.8m°/LSB
  delay(200);
  writeRegister(0x41, ACC_RANGE); // ACC_RANGE => +- 2g
  delay(200);
  writeRegister (0x40,DATA_RATE); // ACC_CONF data rate : 1600Hz
  delay(200);
  writeRegister (0x42, DATA_RATE); // GYRO_CONF data rate : 1600Hz
  delay(200);

  
   byte ID = readRegister(0x00);
  Serial.print("ID=");
  Serial.print(ID);
  delay(50);
  Serial.print(";\t");
  
  writeRegister (0x6D,0b00001101);
  delay(60);
  byte self_test = readRegister(0x1B);
  Serial.print("selftest=");
  Serial.print(self_test);
  Serial.print(";\t");

  
  byte stat = readRegister (0x03);
  delay(60);
  Serial.print("status=");
  Serial.print(stat);
  Serial.print("\r\n");


}

void loop() {
  // put your main code here, to run repeatedly:

}

void writeRegister(byte thisRegister, byte thisValue) {
  // now combine the register address and the command into one byte:
  byte dataToSend = thisRegister & WRITE; // masque write 
  // take the chip select low to select the device:
  digitalWrite(chipSelectBMI160, LOW);
  SPI.transfer(dataToSend); //Send register location
  SPI.transfer(thisValue);  //Send value to record into register
  // take the chip select high to de-select:
  digitalWrite(chipSelectBMI160, HIGH);

}

//Read from BMI160
unsigned int readRegister(byte thisRegister) {
  //digitalWrite(GREEN_LED, HIGH);

  int result = 0;   // result to return
  //Serial.print("\r\n");
  // now combine the address and the command into one byte
  byte dataToSend = thisRegister | READ;
  digitalWrite(chipSelectBMI160, LOW);

  // send the device the register you want to read:
  SPI.transfer(dataToSend);
  result=SPI.transfer(0x00);
  // take the chip select high to de-select:
  digitalWrite(chipSelectBMI160, HIGH);
  // return the result:
  return (result);
}

Datasheet Breakboard BMI160.pdf (514 KB)

Hi FuentesTime, I am doing the same thing as you, and i met the problem cant power up acc and gyr,and i dont know why,.... and i am stucked.i used https://github.com/hanyazou/BMI160-Arduino;but it seems not work,have you make some progress? THX

Hello there, I also want to use the BMI160 with an Arduino Uno or Mega. I tried it with I2C by copying and pasting stuff from other I2C tutorials but have been unsuccessful so far. As a first test, I wanted to read the chip ID (which always should be 160). I am a little confused since the I2C address of the sensor is 0x69 and you read on the internet, that the I2C address is only the upper 7 bits of that. So the Least Significant but would be cut?! Is the address then 0x34?! I tried lots of different combinations to read something meaningful and one time I read 290 (at least I hope that I really read from the sensor). If anybody has a hint where to start with this sensor, this would be greatly appreciated.

Hello,

I used the library for Hanyazou to interact in SPI with the BMI160 and it didn't work at first. There is a mistake at some points which makes the library not working. You need to comment or remove the line where you can read : "BMI160GenClass BMI160;" in BMI160Gen.cpp and .h and then it worked wonderful for me.

you can use my corrected version of the library if you want, i am currently working on it, so feel free to report any issues !

https://github.com/uzhul38/BMI160_Arduino_Library

Hello,

I am also using BMI160 Shuttleboard along with Arduino Mego with SPI interface. Initially I was able to read the accelerometer and gyroscope values. Later I tried interfacing with Magnetemeter(which did not work). But now unforunateley even the accelorometer and gyroscope is not getting powered up at all!! Any suggestions for the issue?