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??

Parents
  • Hi,

    1. There is API in the library you linked for getting sensor data. What have you done to integrate the library in your application? Did you follow the User Guide?
    2. You need to integrate the library in order to get the data first. The data can be sent over BLE using the function ble_nus_data_send().

    Best regards,
    Jørgen

  • Then you need to post the code you have implemented in order for us to help your any further.

    You need to implement the SPI/TWI read/write functions for the library to work. It is just a general library and does not know how to interface with peripherals of nRF5x ICs.

  • Here is my first code that with rslt data

    by default  in bmi160_defs.h

    BMI160_I2c_ADDR  -  0x68

    but i changed to 0x69 after scan the address by using TWI sacnner code.

    #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 Acc_i2c_Write(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t 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;
    
    	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);
        APP_ERROR_CHECK(err_code);
    
        nrf_drv_twi_enable(&m_twi);
    }
    
    void BMI_mode()
    { 
      
        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;
    }
     
    
    
    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.\r\n");
        NRF_LOG_FLUSH();
        twi_init();
        BMI_mode();
        ret_code_t rslt = BMI160_OK;
        struct bmi160_sensor_data accel;
        struct bmi160_sensor_data gyro;
    
       // NRF_LOG_FLUSH();
        /* Select the Output data rate, range of accelerometer sensor */
        sensor.accel_cfg.odr = BMI160_ACCEL_ODR_1600HZ;
        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_3200HZ;
        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);
    
        NRF_LOG_INFO("sensor is :%d \r\n",rslt);
        NRF_LOG_FLUSH();
    Acc_delay_ms(5000);
        
        NRF_LOG_INFO("rslt is :%d \r\n",rslt);
      //  NRF_LOG_FLUSH();
        rslt = BMI160_OK;
        rslt = bmi160_init(&sensor);
        NRF_LOG_INFO("rslt is :%d \r\n",rslt);
        /* To read only Accel data */
        rslt = bmi160_get_sensor_data(BMI160_ACCEL_SEL, &accel, NULL, &sensor);
           NRF_LOG_INFO("Acc is :%d \r\n",rslt);
        
        /* To read only Gyro data */
        rslt = bmi160_get_sensor_data(BMI160_GYRO_SEL, NULL, &gyro, &sensor);
         NRF_LOG_INFO("gyro is :%d \r\n",rslt);
        /* To read both Accel and Gyro data */
        rslt = bmi160_get_sensor_data((BMI160_ACCEL_SEL | BMI160_GYRO_SEL), &accel, &gyro, &sensor);
         NRF_LOG_INFO("Acc is :%d \r\n",rslt);
        /* To read Accel data along with time */
        rslt = bmi160_get_sensor_data((BMI160_ACCEL_SEL | BMI160_TIME_SEL) , &accel, NULL, &sensor);
         NRF_LOG_INFO("Acc is :%d \r\n",rslt);
        /* To read Gyro data along with time */
        rslt = bmi160_get_sensor_data((BMI160_GYRO_SEL | BMI160_TIME_SEL), NULL, &gyro, &sensor);
         NRF_LOG_INFO("gyro is :%d \r\n",rslt);
        /* To read both Accel and Gyro data along with time*/
        rslt = bmi160_get_sensor_data((BMI160_ACCEL_SEL | BMI160_GYRO_SEL | BMI160_TIME_SEL), &accel, &gyro, &sensor);
         NRF_LOG_INFO("Acc_t is :%d \r\n",rslt);
    rslt = BMI160_OK;
    rslt = bmi160_perform_self_test(BMI160_ACCEL_ONLY, &sensor);
    NRF_LOG_INFO("rslt is :%d \r\n",rslt);
    	/* Utilize the enum BMI160_GYRO_ONLY instead of BMI160_ACCEL_ONLY
    	   to perform self test for gyro */
    	if (rslt == BMI160_OK) {
    		NRF_LOG_INFO("\n ACCEL SELF TEST RESULT SUCCESS");
    	} else {
    		NRF_LOG_INFO("\n ACCEL SELF TEST RESULT FAIL");
    	}
    
        NRF_LOG_FLUSH();
       
    }
    
    
    
    
    
    

    as a result got

    <info> app: BMI160 get started.

    <info> app: sensor is :0

    <info> app: rslt is :0

    <info> app: rslt is :0

    <info> app: Acc is :0

    <info> app: gyro is :0

    <info> app: Acc is :0

    <info> app: Acc is :0

    <info> app: Acc is :0

    <info> app: Acc is :0

    <info> app: Acc is :0

    <info> app:
     ACCEL SELF TEST RESULT SUCCESS

    Is rslt shows error return code or any. i didn't understood the exact function of RSLT in code.

  • rslt is the return code from the function call. The received data is stored in parameter 'struct bmi160_sensor_data *accel'

Reply Children
  • HI,

    I am trying to get the Accel X value and gyro X value but the rslt is 0 and data also 0.

    #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;
    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)
    {
    	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;
    
    	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);
        APP_ERROR_CHECK(err_code);
    
        nrf_drv_twi_enable(&m_twi);
    }
    
    void Acc_Gyro_config(void)
    {
    /* Select the Output data rate, range of accelerometer sensor */
        sensor.accel_cfg.odr = BMI160_ACCEL_ODR_1600HZ;
        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_3200HZ;
        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);
    
        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);// accelerometer x value
    
        rslt = bmi160_get_sensor_data(BMI160_GYRO_SEL, NULL, &gyro, &sensor);
    	
    	NRF_LOG_INFO("rslt:%d, data: %d", rslt,gyro.x); // gyroscope x value
        NRF_LOG_FLUSH();
    
     }

  • Most likely there is some error in your TWI read function. From the datasheet, it looks like the I2C read operation does not expect a stop condition between TX and RX. Try changing the no_stop parameter of nrf_drv_twi_tx() in Acc_i2c_Read() to true instead of false.

  • Even though it won't works.  

    i got link as similar error obtain but here i don't know how to apply here is the link

    https://github.com/BoschSensortec/BMI160_driver/issues/44

    in that at last it says : " I got the data from the BMI160 by enable the chip with CS. However, When I integrate the code with the BLE-uart, I kept getting zero with the right configuration..."

  • Have you checked the TWI lines with a logic analyzer to see if any data is transmitted/received?

  • No, i didn't check that. but with rslt return data only. i checked

Related