This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

BMI160 + NRF52832 + I2C

HI,

I want to develop a program to access Accelerometer and gyroscope value from BMI160 sensor. I have used this BMI160 library 

I alter the TWI_SENSOR code and it works for self testing ACC code. but i need to calibrate the x, y, z axis value and i want to add BLE stack to read in mobile app.

1. How to collect all the X,Y,Z axis value

2. i need to see the LOGS in Bluetooth app by using BLE_UART. how to edit the BLE_UART code to get the respective ACC and GYRO value in BLE APP.

Is there any code for reading X,Y,Z axis for BMI160??

  • I do not understand what you mean by this:

    Sunil vignesh said:
    but with rslt return data only. i checked

    Did you receive the data? If not, I recommend that you check the TWI lines.

  • I print the data which in Acc_i2c_Read() and Acc_i2c_Write();

    #include <stdio.h>
    #include "boards.h"
    #include "app_util_platform.h"
    #include "app_error.h"
    #include "nrf_drv_twi.h"
    #include "nrf_delay.h"
    
    /* Sensor */
    #include "bmi160.h"
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    
    
    /* TWI instance ID. */
    #define TWI_INSTANCE_ID     0
    
    /* Indicates if operation on TWI has ended. */
    static volatile bool m_xfer_done = false;
    
    /* TWI instance. */
    static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);
    struct bmi160_dev sensor;
    
    int8_t rslt = BMI160_OK;
    uint8_t data = 0;
    struct bmi160_sensor_data accel;
    struct bmi160_sensor_data gyro;
    //struct bmi160_sensor_data.gyro Gyro;
    
    int8_t Acc_i2c_Write(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
    {
    
          NRF_LOG_INFO("WRITE: dev_id: %x reg_addr: %x reg_data: %x len: %i\n", dev_id, reg_addr, reg_data, len);
    	int8_t rslt = 0;
    	uint8_t data[len + 1];
    	data[0] = reg_addr;
    	for (uint16_t i = 0; i < len; i++) {
    		data[i + 1] = reg_data[i];
    	}
    	
    	rslt = nrf_drv_twi_tx(&m_twi, dev_id, data, len + 1, false);
    	return rslt;
    }
    
    
    int8_t Acc_i2c_Read(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
    {
    	int8_t rslt = 0;
    NRF_LOG_INFO("READ: dev_id: %x reg_addr: %x reg_data: %x len: %i\n", dev_id, reg_addr, reg_data, len);
    	rslt = nrf_drv_twi_tx(&m_twi, dev_id, &reg_addr, 1, false);
    	//nrf_delay_ms(5);
    	if (rslt == 0)
    	{
    		rslt = nrf_drv_twi_rx(&m_twi, dev_id, reg_data, len);
    	}
    	
    	return rslt;
    }
    
    void Acc_delay_ms(uint32_t period)
    { 
    	// delay time
    	
      nrf_delay_ms( period ) ;
    } // user_delay_ms()
    
    void twi_init (void)
    {
        ret_code_t err_code;
    
        const nrf_drv_twi_config_t twi_config = {
           .scl                = ARDUINO_SCL_PIN,
           .sda                = ARDUINO_SDA_PIN,
           .frequency          = NRF_DRV_TWI_FREQ_100K,
           .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
           .clear_bus_init     = false
        };
    
        err_code = nrf_drv_twi_init(&m_twi, &twi_config, NULL, NULL);
        if (NRF_SUCCESS == err_code)
    	{
    		nrf_drv_twi_enable(&m_twi);
    		NRF_LOG_INFO("success");	
    	}
        APP_ERROR_CHECK(err_code);
    
        
    }
    
    void Acc_Gyro_config(void)
    {
    /* Select the Output data rate, range of accelerometer sensor */
        sensor.accel_cfg.odr = BMI160_ACCEL_ODR_100HZ;
        sensor.accel_cfg.range = BMI160_ACCEL_RANGE_2G;
        sensor.accel_cfg.bw = BMI160_ACCEL_BW_NORMAL_AVG4;
    
        /* Select the power mode of accelerometer sensor */
        sensor.accel_cfg.power = BMI160_ACCEL_NORMAL_MODE;
    
        /* Select the Output data rate, range of Gyroscope sensor */
        sensor.gyro_cfg.odr = BMI160_GYRO_ODR_100HZ;
        sensor.gyro_cfg.range = BMI160_GYRO_RANGE_2000_DPS;
        sensor.gyro_cfg.bw = BMI160_GYRO_BW_NORMAL_MODE;
    
        /* Select the power mode of Gyroscope sensor */
        sensor.gyro_cfg.power = BMI160_GYRO_NORMAL_MODE; 
    
        /* Set the sensor configuration */
    
        rslt = bmi160_set_sens_conf(&sensor);
        Acc_delay_ms(100);
        rslt = bmi160_get_regs(BMI160_ERROR_REG_ADDR, &data, 1, &sensor);
    
    if (rslt == BMI160_OK) {
    	data = data >> 1;
    	data = data & BMI160_ERR_REG_MASK;
    	if (data == 1)
    		rslt = BMI160_E_ACCEL_ODR_BW_INVALID;
    	else if (data == 2)
    		rslt = BMI160_E_GYRO_ODR_BW_INVALID;
    	else if (data == 3)
    		rslt = BMI160_E_LWP_PRE_FLTR_INT_INVALID;
    	else if (data == 7)
    	rslt = BMI160_E_LWP_PRE_FLTR_INVALID;
    }
    
    NRF_LOG_INFO("setup result is : %d",rslt);
    
    
    
        if(rslt == BMI160_OK){
        NRF_LOG_INFO("sensor Configured... \n");
        } else {
       NRF_LOG_INFO("sensor not Configured... \n");
        }
       
        NRF_LOG_FLUSH();
    }
    void Acc_Gyro_self_test(void)
    {
      rslt = bmi160_perform_self_test(BMI160_ACCEL_ONLY, &sensor);
     
              
              if (rslt == BMI160_OK) {
                      NRF_LOG_INFO("ACCEL SELF TEST RESULT SUCCESS \n");
              } else {
                      NRF_LOG_INFO("ACCEL SELF TEST RESULT FAIL\n");
              }NRF_LOG_FLUSH();
      
      rslt = bmi160_perform_self_test(BMI160_GYRO_ONLY, &sensor);
      
              
              if (rslt == BMI160_OK) {
                      NRF_LOG_INFO("gyro SELF TEST RESULT SUCCESS \n");
              } else {
                      NRF_LOG_INFO("gyro SELF TEST RESULT FAIL \n");
              }
    
          NRF_LOG_FLUSH();
    }
    
    
    void BMI_mode(void)
    { 
        
        sensor.id = BMI160_I2C_ADDR;
        sensor.interface = BMI160_I2C_INTF;
        sensor.read = Acc_i2c_Read;
        sensor.write = Acc_i2c_Write;
        sensor.delay_ms = Acc_delay_ms;
    
        rslt = bmi160_init(&sensor);
        if(rslt == BMI160_OK){
        NRF_LOG_INFO("BMI160 Initialized... \n");
        } else {
        NRF_LOG_INFO("BMI160 not Initialized... \n");
        }
        NRF_LOG_FLUSH();
    }
     
     int main(void)
     {
      bsp_board_init(BSP_INIT_LEDS);
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    
        NRF_LOG_INFO("BMI160 get started.\n");
        NRF_LOG_FLUSH();
        Acc_delay_ms(1000);
        twi_init();
        Acc_delay_ms(300);
        BMI_mode();
        Acc_delay_ms(300);
        Acc_Gyro_config();
        Acc_delay_ms(300);
        Acc_Gyro_self_test();
        Acc_delay_ms(300);
        bmi160_get_sensor_data(BMI160_ACCEL_SEL, &accel, NULL, &sensor);
        NRF_LOG_INFO("x is %ld \r\n",accel.x);
        
    
        rslt = bmi160_get_sensor_data(BMI160_GYRO_SEL, NULL, &gyro, &sensor);
    	
    	NRF_LOG_INFO("rslt:%d, data: %i", rslt,gyro.x);
        NRF_LOG_FLUSH();
       
    
     }
    

    <info> app: BMI160 get started.

    <info> app: success
    <info> app: READ: dev_id: 69 reg_addr: 0 reg_data: 200006D0 len: 1

    <info> app: WRITE: dev_id: 69 reg_addr: 7E reg_data: 2000FFBF len: 1

    <info> app: BMI160 Initialized...

    <info> app: READ: dev_id: 69 reg_addr: 40 reg_data: 2000FFC4 len: 2

    <info> app: WRITE: dev_id: 69 reg_addr: 40 reg_data: 2000FFC4 len: 1

    <info> app: WRITE: dev_id: 69 reg_addr: 41 reg_data: 2000FFC5 len: 1

    <info> app: READ: dev_id: 69 reg_addr: 42 reg_data: 2000FFC4 len: 2

    <info> app: WRITE: dev_id: 69 reg_addr: 42 reg_data: 2000FFC4 len: 1

    <info> app: WRITE: dev_id: 69 reg_addr: 43 reg_data: 2000FFC5 len: 1

    <info> app: READ: dev_id: 69 reg_addr: 40 reg_data: 2000FFAE len: 1

    <info> app: WRITE: dev_id: 69 reg_addr: 7E reg_data: 200006D4 len: 1

    <info> app: WRITE: dev_id: 69 reg_addr: 7E reg_data: 200006DC len: 1

    <info> app: READ: dev_id: 69 reg_addr: 2 reg_data: 2000FFC4 len: 1

    <info> app: READ: dev_id: 69 reg_addr: 2 reg_data: 200006BC len: 1

    <info> app: setup result is : 0
    <info> app: sensor Configured...

    <info> app: READ: dev_id: 69 reg_addr: 40 reg_data: 2000FF94 len: 2

    <info> app: WRITE: dev_id: 69 reg_addr: 40 reg_data: 2000FF94 len: 1

    <info> app: WRITE: dev_id: 69 reg_addr: 41 reg_data: 2000FF95 len: 1

    <info> app: READ: dev_id: 69 reg_addr: 42 reg_data: 2000FF94 len: 2

    <info> app: WRITE: dev_id: 69 reg_addr: 42 reg_data: 2000FF94 len: 1

    <info> app: WRITE: dev_id: 69 reg_addr: 43 reg_data: 2000FF95 len: 1

    <info> app: READ: dev_id: 69 reg_addr: 2 reg_data: 2000FF94 len: 1

    <info> app: WRITE: dev_id: 69 reg_addr: 40 reg_data: 2000FFBC len: 1

    <info> app: WRITE: dev_id: 69 reg_addr: 6D reg_data: 2000FFBC len: 1

    <info> app: READ: dev_id: 69 reg_addr: 12 reg_data: 2000FF80 len: 6

    <info> app: WRITE: dev_id: 69 reg_addr: 6D reg_data: 2000FFAF len: 1

    <info> app: READ: dev_id: 69 reg_addr: 12 reg_data: 2000FF80 len: 6

    <info> app: WRITE: dev_id: 69 reg_addr: 7E reg_data: 2000FF97 len: 1

    <info> app: ACCEL SELF TEST RESULT SUCCESS

    <info> app: WRITE: dev_id: 69 reg_addr: 7E reg_data: 200006DC len: 1

    <info> app: READ: dev_id: 69 reg_addr: 6D reg_data: 2000FFBC len: 1

    <info> app: WRITE: dev_id: 69 reg_addr: 6D reg_data: 2000FFBC len: 1

    <info> app: READ: dev_id: 69 reg_addr: 1B reg_data: 2000FFBC len: 1

    <info> app: WRITE: dev_id: 69 reg_addr: 7E reg_data: 2000FF97 len: 1

    <info> app: gyro SELF TEST RESULT SUCCESS

    <info> app: READ: dev_id: 69 reg_addr: 12 reg_data: 2000FFC8 len: 6

    <info> app: x is 0

    <info> app: READ: dev_id: 69 reg_addr: C reg_data: 2000FFC8 len: 6

    <info> app: rslt:0, data: 0

  • This give no indication if the data is actually transmitted on the bus, it only show that the function is called. 

  • I tried but i don't know how its work.?

    If you know please help me to get the data...

  • i try to access acclerometer X value

    #define BMI160_ACCEL_DATA_ADDR        UINT8_C(0x12)   // defined in bmi160_defs.h

    #include <stdio.h>
    #include "boards.h"
    #include "app_util_platform.h"
    #include "app_error.h"
    #include "nrf_drv_twi.h"
    #include "nrf_delay.h"
    
    /* Sensor */
    #include "bmi160.h"
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    //typedef int8_t (*bmi160_com_fptr_t)(uint8_t dev_addr, uint8_t reg_addr,
    		//uint8_t *data, uint16_t len);
    
    /* TWI instance ID. */
    #define TWI_INSTANCE_ID     0
    
     #define TWI_ADDRESSES      127
    #define LM75B_ADDR          0x12U 
    
    /* Indicates if operation on TWI has ended. */
    static volatile bool m_xfer_done = false;
    
    /* TWI instance. */
    static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);
    struct bmi160_dev sensor;
    static uint8_t m_sample;
    
    
    int8_t rslt = BMI160_OK;
    uint8_t data = 0;
    struct bmi160_sensor_data accel;
    struct bmi160_sensor_data gyro;
    //struct bmi160_sensor_data.gyro Gyro;
    
    
    
    int8_t Acc_i2c_Write(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
    {
    
        //  NRF_LOG_INFO("WRITE: dev_id: %x reg_addr: %x reg_data: %x len: %i\n", dev_id, reg_addr, &reg_data, len);
    	int8_t rslt = 0;
    	uint8_t data[len + 1];
    	data[0] = reg_addr;
    	for (uint16_t i = 0; i < len; i++) {
    		data[i + 1] = reg_data[i];
    	}
    	
    	rslt = nrf_drv_twi_tx(&m_twi, dev_id, data, len + 1, false);
    	APP_ERROR_CHECK(rslt);
       // while (m_xfer_done == false);
    }
    
    
    int8_t Acc_i2c_Read(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
    {
    	int8_t rslt = 0;
    //NRF_LOG_INFO("READ: dev_id: %x reg_addr: %x reg_data: %x len: %i\n", dev_id, reg_addr, reg_data, len);
    	rslt = nrf_drv_twi_tx(&m_twi, dev_id, &reg_addr, 1, true);
            APP_ERROR_CHECK(rslt);
    //    while (m_xfer_done == false);
    	//nrf_delay_ms(5);
    	if (rslt == 0)
    	{
    		rslt = nrf_drv_twi_rx(&m_twi, dev_id, reg_data, len);
    	}
    	
    	return rslt;
    }
    
    void Acc_delay_ms(uint32_t period)
    { 
    	
    if (period==NULL){
    period = 1;
    }// delay time
    	
      nrf_delay_ms( period ) ;
    } // user_delay_ms()
    
    
    
    void twi_init (void)
    {
        ret_code_t err_code;
    
        const nrf_drv_twi_config_t twi_config = {
           .scl                = ARDUINO_SCL_PIN,
           .sda                = ARDUINO_SDA_PIN,
           .frequency          = NRF_DRV_TWI_FREQ_100K,
           .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
           .clear_bus_init     = false
        };
    
        err_code = nrf_drv_twi_init(&m_twi, &twi_config, NULL, NULL);
        
        APP_ERROR_CHECK(err_code);
        if (NRF_SUCCESS == err_code)
    	{
    		nrf_drv_twi_enable(&m_twi);
    		NRF_LOG_INFO("success");	
    	}
    
        
    }
    
    static void read_sensor_data()
    {
      //  m_xfer_done = false;
    
        /* Read 1 byte from the specified address - skip 3 bits dedicated for fractional part of temperature. */
        ret_code_t err_code = nrf_drv_twi_rx(&m_twi, LM75B_ADDR, &m_sample, sizeof(m_sample));
        APP_ERROR_CHECK(err_code);
        NRF_LOG_INFO("x: %d ", m_sample);
    }
    
    void Acc_Gyro_config(void)
    {
    /* Select the Output data rate, range of accelerometer sensor */
        sensor.accel_cfg.odr = BMI160_ACCEL_ODR_100HZ;
        sensor.accel_cfg.range = BMI160_ACCEL_RANGE_2G;
        sensor.accel_cfg.bw = BMI160_ACCEL_BW_NORMAL_AVG4;
    
        /* Select the power mode of accelerometer sensor */
        sensor.accel_cfg.power = BMI160_ACCEL_NORMAL_MODE;
    
        /* Select the Output data rate, range of Gyroscope sensor */
        sensor.gyro_cfg.odr = BMI160_GYRO_ODR_100HZ;
        sensor.gyro_cfg.range = BMI160_GYRO_RANGE_2000_DPS;
        sensor.gyro_cfg.bw = BMI160_GYRO_BW_NORMAL_MODE;
    
        /* Select the power mode of Gyroscope sensor */
        sensor.gyro_cfg.power = BMI160_GYRO_NORMAL_MODE; 
    
        /* Set the sensor configuration */
    
        rslt = bmi160_set_sens_conf(&sensor);
        Acc_delay_ms(100);
        rslt = bmi160_get_regs(BMI160_ERROR_REG_ADDR, &data, 1, &sensor);
    
    if (rslt == BMI160_OK) {
    	data = data >> 1;
    	data = data & BMI160_ERR_REG_MASK;
    	if (data == 1)
    		rslt = BMI160_E_ACCEL_ODR_BW_INVALID;
    	else if (data == 2)
    		rslt = BMI160_E_GYRO_ODR_BW_INVALID;
    	else if (data == 3)
    		rslt = BMI160_E_LWP_PRE_FLTR_INT_INVALID;
    	else if (data == 7)
    	rslt = BMI160_E_LWP_PRE_FLTR_INVALID;
    }
    
    NRF_LOG_INFO("setup result is : %d", data);
    
    
    
        if(rslt == BMI160_OK){
        NRF_LOG_INFO("sensor Configured... \n");
        } else {
       NRF_LOG_INFO("sensor not Configured... \n");
        }
       
        NRF_LOG_FLUSH();
    }
    void Acc_Gyro_self_test(void)
    {
      rslt = bmi160_perform_self_test(BMI160_ACCEL_ONLY, &sensor);
     
              
              if (rslt == BMI160_OK) {
                      NRF_LOG_INFO("ACCEL SELF TEST RESULT SUCCESS \n");
              } else {
                      NRF_LOG_INFO("ACCEL SELF TEST RESULT FAIL\n");
              }NRF_LOG_FLUSH();
      
      rslt = bmi160_perform_self_test(BMI160_GYRO_ONLY, &sensor);
      
              
              if (rslt == BMI160_OK) {
                      NRF_LOG_INFO("gyro SELF TEST RESULT SUCCESS \n");
              } else {
                      NRF_LOG_INFO("gyro SELF TEST RESULT FAIL \n");
              }
    
          NRF_LOG_FLUSH();
    }
    
    
    void BMI_mode(void)
    { 
        
        sensor.id = BMI160_I2C_ADDR;
        sensor.interface = BMI160_I2C_INTF;
        sensor.read = Acc_i2c_Read;
        sensor.write = Acc_i2c_Write;
        sensor.delay_ms = Acc_delay_ms;
    
        rslt = bmi160_init(&sensor);
        if(rslt == BMI160_OK){
        NRF_LOG_INFO("BMI160 Initialized... \n");
        } else {
        NRF_LOG_INFO("BMI160 not Initialized... \n");
        }
        NRF_LOG_FLUSH();
    }
     
     int main(void)
     {
        ret_code_t err_code;
        uint8_t address;
        uint8_t sample_data;
        bool detected_device = false;
    
      bsp_board_init(BSP_INIT_LEDS);
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    /*
        NRF_LOG_INFO("TWI scanner started.");
        NRF_LOG_FLUSH();
        twi_init();
    
        for (address = 1; address <= TWI_ADDRESSES; address++)
        {
            //err_code = Acc_i2c_Read(BMI160_I2C_ADDR,address, &sample_data, sizeof(sample_data));
            err_code = nrf_drv_twi_rx(&m_twi, address, &sample_data, sizeof(sample_data));
            if (err_code == NRF_SUCCESS)
            {
                detected_device = true;
                NRF_LOG_INFO("TWI device detected at address 0x%x", address);
                NRF_LOG_INFO("TWI device detected at address 0x%x", sample_data);
            }
            NRF_LOG_FLUSH();
        }
    
        if (!detected_device)
        {
            NRF_LOG_INFO("No device was found.");
            NRF_LOG_FLUSH();
        }
    
    Acc_delay_ms(10000);*/
    
        NRF_LOG_INFO("BMI160 get started.\n");
        NRF_LOG_FLUSH();
        Acc_delay_ms(1000);
        twi_init();
        Acc_delay_ms(300);
        BMI_mode();
        Acc_delay_ms(300);
        Acc_Gyro_config();
        Acc_delay_ms(300);
        Acc_Gyro_self_test();
        Acc_delay_ms(300);
        bmi160_get_sensor_data(BMI160_ACCEL_SEL, &accel, NULL, &sensor);
        NRF_LOG_INFO("x is %ld \r\n",accel.x);
        
    
        rslt = bmi160_get_sensor_data(BMI160_GYRO_SEL, NULL, &gyro, &sensor);
    	
    	NRF_LOG_INFO("rslt:%d, data: %i", rslt,gyro.x);
        NRF_LOG_FLUSH();
       err_code = nrf_drv_twi_rx(&m_twi, BMI160_ACCEL_DATA_ADDR, &sample_data, sizeof(sample_data));
    if (err_code == NRF_SUCCESS)
            {
                detected_device = true;
                NRF_LOG_INFO("TWI device detected at address 0x%x", address);
                NRF_LOG_INFO("TWI device detected at address 0x%x", sample_data);
                NRF_LOG_FLUSH();
            }
    
          // read_sensor_data();
            NRF_LOG_FLUSH();
    
            ret_code_t err_cod = nrf_drv_twi_rx(&m_twi, LM75B_ADDR, &m_sample, sizeof(m_sample));
        APP_ERROR_CHECK(err_cod);
        NRF_LOG_INFO("x: %d ", m_sample);
        NRF_LOG_FLUSH();
        
     }
    
    

     and output side

    <info> app: BMI160 get started.

    <info> app: success
    <info> app: BMI160 Initialized...

    <info> app: setup result is : 0
    <info> app: sensor Configured...

    <info> app: ACCEL SELF TEST RESULT SUCCESS

    <info> app: gyro SELF TEST RESULT SUCCESS

    <info> app: x is 0

    <info> app: rslt:0, data: 0
    <error> app: Fatal error

Related