Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Getting x,y,z values from BMX055 using i2C

So, I am quite beginer with programming and working with this sensors and nrf, So I need your guys help.

I am trying to get the x,y,z values from the accelerometer of BMX055 IMU sensor. So, I did not used BMX055 drivers. But the issue here is that I am not getting any output on Putty. I have set the putty according to https://infocenter.nordicsemi.com/index.jsp?topic=%2Fsdk_nrf5_v17.0.2%2Flib_cli.html&anchor=lib_cli_terminal_settings . It does give results of the addresses of the imu sensor when using TWI scanner example. But when I run my own code, there is no output.

I followed the guide of https://devzone.nordicsemi.com/f/nordic-q-a/38794/procedure-for-using-twi-for-i2c-between-the-nrf52dk-bmx055

Can someone please guide me where is the fault. I think there is small fault which I am unable to catch as of now.

This is my code in bmx.c file : 

#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "nrf_drv_twi.h"
#include "bma2x2.h"


//Initializing TWI0 instance
#define TWI_INSTANCE_ID 0

// A flag to indicate the transfer state
static volatile bool m_xfer_done = false;


// Create a Handle for the twi communication
static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);


//Event Handler
void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
{
//Check the event to see what type of event occurred
switch (p_event->type)
{
//If data transmission or receiving is finished
case NRF_DRV_TWI_EVT_DONE:
m_xfer_done = true;//Set the flag
break;

default:
// do nothing
break;
}
}

//Initialize the TWI as Master device
void twi_master_init(void)
{
ret_code_t err_code;

// Configure the settings for twi communication
const nrf_drv_twi_config_t twi_config = {
.scl = TWI_SCL_M, //SCL Pin
.sda = TWI_SDA_M, //SDA Pin
.frequency = NRF_DRV_TWI_FREQ_400K, //Communication Speed
.interrupt_priority = APP_IRQ_PRIORITY_HIGH, //Interrupt Priority(Note: if using Bluetooth then select priority carefully)
.clear_bus_init = false //automatically clear bus
};


//A function to initialize the twi communication
err_code = nrf_drv_twi_init(&m_twi, &twi_config, twi_handler, NULL);
APP_ERROR_CHECK(err_code);

//Enable the TWI Communication
nrf_drv_twi_enable(&m_twi);
}

/*
A function to write a Single Byte to bmx's internal Register
*/
bool bmxme_register_write(uint8_t register_address, uint8_t value)
{
ret_code_t err_code;
uint8_t tx_buf[BMA2x2_GEN_READ_WRITE_LENGTH+1];

//Write the register address and data into transmit buffer
tx_buf[0] = register_address;
tx_buf[1] = value;

//Set the flag to false to show the transmission is not yet completed
m_xfer_done = false;

//Transmit the data over TWI Bus
err_code = nrf_drv_twi_tx(&m_twi, BMA2x2_I2C_ADDR1, tx_buf, BMA2x2_GEN_READ_WRITE_LENGTH+1, false);

//Wait until the transmission of the data is finished
while (m_xfer_done == false)
{
}

// if there is no error then return true else return false
if (NRF_SUCCESS != err_code)
{
return false;
}

return true;
}
/*
A Function to verify the product id
(its a basic test to check if we are communicating with the right slave, every type of I2C Device has
a special WHO_AM_I register which holds a specific value, we can read it from the MPU6050 or any device
to confirm we are communicating with the right device)
*/
bool bmxme_verify_product_id(void)
{
uint8_t who_am_i; // create a variable to hold the who am i value


if (bmxme_register_read(I_AM_BMX055_ACC, &who_am_i, 1))
{
if (who_am_i != I_AM_BMX055_ACC)
{
return false;
}
else
{
return true;
}
}
else
{
return false;
}

}
/*
Function to initialize the bmx055
*/
bool bmxme_init(void)
{
bool transfer_succeeded = true;

//Check the id to confirm that we are communicating with the right device
transfer_succeeded &= bmxme_verify_product_id();

if(bmxme_verify_product_id() == false)
{
return false;
}

// Set the registers with the required values, see the datasheet to get a good idea of these values
(void)bmxme_register_write(BMA2x2_MODE_CTRL_ADDR , 0x00);
(void)bmxme_register_write(BMA2x2_LOW_NOISE_CTRL_ADDR , 0x00);
(void)bmxme_register_write(BMA2x2_DATA_CTRL_ADDR , 0x40);
(void)bmxme_register_write(BMA2x2_BW_SELECT_ADDR , 0x08);
(void)bmxme_register_write(BMA2x2_RANGE_SELECT_ADDR , 0x08);

return transfer_succeeded;
}


/*
A Function to read data from the bmx055
*/
bool bmxme_register_read(uint8_t register_address, uint8_t * destination, uint8_t number_of_bytes)
{
ret_code_t err_code;

//Set the flag to false to show the receiving is not yet completed
m_xfer_done = false;

// Send the Register address where we want to write the data
err_code = nrf_drv_twi_tx(&m_twi, BMA2x2_I2C_ADDR1 , &register_address, 1, true);

//Wait for the transmission to get completed
while (m_xfer_done == false){}

// If transmission was not successful, exit the function with false as return value
if (NRF_SUCCESS != err_code)
{
return false;
}

//set the flag again so that we can read data from the bmx055's internal register
m_xfer_done = false;

// Receive the data from the bmx055
err_code = nrf_drv_twi_rx(&m_twi, BMA2x2_I2C_ADDR1, destination, number_of_bytes);

//wait until the transmission is completed
while (m_xfer_done == false){}

// if data was successfully read, return true else return false
if (NRF_SUCCESS != err_code)
{
return false;
}

return true;
}


/*
A Function to read accelerometer's values from the internal registers of MPU6050
*/
bool bmxme_ReadAcc( int16_t *pACC_X , int16_t *pACC_Y , int16_t *pACC_Z )
{
uint8_t xaxis_buf[2];
uint8_t yaxis_buf[2];
uint8_t zaxis_buf[2];
bool ret = false;

if(bmxme_register_read(BMA2x2_X_AXIS_LSB_ADDR, xaxis_buf[0], 1) & bmxme_register_read(BMA2x2_X_AXIS_MSB_ADDR, xaxis_buf[1], 1) == true)
{
bmxme_register_read(BMA2x2_X_AXIS_LSB_ADDR, xaxis_buf[0], 1);
bmxme_register_read(BMA2x2_X_AXIS_MSB_ADDR, xaxis_buf[1], 1);

*pACC_X = (xaxis_buf[1] << 8) | xaxis_buf[0];
if(*pACC_X & 0x8000) *pACC_X-=65536;
ret = true;
}

if(bmxme_register_read(BMA2x2_Y_AXIS_LSB_ADDR, yaxis_buf[0], 1) & bmxme_register_read(BMA2x2_Y_AXIS_MSB_ADDR, yaxis_buf[1], 1) == true)
{
bmxme_register_read(BMA2x2_Y_AXIS_LSB_ADDR, yaxis_buf[0], 1);
bmxme_register_read(BMA2x2_Y_AXIS_MSB_ADDR, yaxis_buf[1], 1);

*pACC_Y= (yaxis_buf[1] << 8) | yaxis_buf[0];
if(*pACC_Y & 0x8000) *pACC_Y-=65536;
ret = true;
}

if(bmxme_register_read(BMA2x2_Z_AXIS_LSB_ADDR, zaxis_buf[0], 1) & bmxme_register_read(BMA2x2_Z_AXIS_MSB_ADDR, zaxis_buf[1], 1) == true)
{
bmxme_register_read(BMA2x2_Z_AXIS_LSB_ADDR, zaxis_buf[0], 1);
bmxme_register_read(BMA2x2_Z_AXIS_MSB_ADDR, zaxis_buf[1], 1);

*pACC_Z= (zaxis_buf[1] << 8) | zaxis_buf[0];
if(*pACC_Z & 0x8000) *pACC_Z-=65536;

ret = true;
}

return ret;
}

================================================================================================================

================================================================================================================

and my main.c is : 


#include <stdio.h>
#include "boards.h"
#include "app_util_platform.h"
#include "app_error.h"
#include "nrf_drv_twi.h"
#include "bma2x2.h"


#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"

int main(void)
{
// initialize the logger
APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
NRF_LOG_DEFAULT_BACKENDS_INIT();

NRF_LOG_INFO("TWI accelerometer reading started.");



// create arrays which will hold x,y & z co-ordinates values of acc
static int16_t AccValue[3];

bsp_board_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS); // initialize the leds and buttons

twi_master_init(); // initialize the twi
nrf_delay_ms(1000); // give some delay
bmxme_init();

while(bmxme_init() == false) // wait until bm055 sensor is successfully initialized
{
NRF_LOG_INFO("BMX_055 initialization failed!!!"); // if it failed to initialize then print a message
nrf_delay_ms(1000);
}

NRF_LOG_INFO("BMX055 Initialization Successful!!!");

NRF_LOG_INFO("Reading Values from ACC"); // display a message to let the user know that the device is starting to read the values
nrf_delay_ms(2000);




while (true)
{
if(bmxme_ReadAcc(&AccValue[0], &AccValue[1], &AccValue[2]) == true) // Read acc value from bmx055 internal registers and save them in the array
{
NRF_LOG_INFO("ACC Values: x = %d y = %d z = %d", AccValue[0], AccValue[1], AccValue[2]); // display the read values
}
else
{
NRF_LOG_INFO("Reading ACC values Failed!!!"); // if reading was unsuccessful then let the user know about it
}


nrf_delay_ms(100); // give some delay


}
}

/** @} */

  • Sorry I didnt notice that. 

    So, this is bmx.c file : 

    #include <stdbool.h>
    #include <stdint.h>
    #include <string.h>
    #include "nrf_drv_twi.h"
    #include "bma2x2.h"
    
    
    
    
    //Initializing TWI0 instance
    #define TWI_INSTANCE_ID     0
    
    // A flag to indicate the transfer state
    static volatile bool m_xfer_done = false;
    
    
    // Create a Handle for the twi communication
    static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);
    
    
    
    
    //Event Handler
    void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
    {
        //Check the event to see what type of event occurred
        switch (p_event->type)
        {
            //If data transmission or receiving is finished
    	case NRF_DRV_TWI_EVT_DONE:
            m_xfer_done = true;//Set the flag
            break;
            
            default:
            // do nothing
              break;
        }
    } 
    
    
    
    //Initialize the TWI as Master device
    void twi_master_init(void)
    {
        ret_code_t err_code;
    
        // Configure the settings for twi communication
        const nrf_drv_twi_config_t twi_config = {
           .scl                = TWI_SCL_M,  //SCL Pin
           .sda                = TWI_SDA_M,  //SDA Pin
           .frequency          = NRF_DRV_TWI_FREQ_400K, //Communication Speed
           .interrupt_priority = APP_IRQ_PRIORITY_HIGH, //Interrupt Priority(Note: if using Bluetooth then select priority carefully)
           .clear_bus_init     = false //automatically clear bus
        };
    
    
        //A function to initialize the twi communication
        err_code = nrf_drv_twi_init(&m_twi, &twi_config, twi_handler, NULL);
        APP_ERROR_CHECK(err_code);
        
        //Enable the TWI Communication
        nrf_drv_twi_enable(&m_twi);
    }
    
    
    
    /*
       A function to write a Single Byte to bmx's internal Register
    */ 
    bool bmxme_register_write(uint8_t register_address, uint8_t value)
    {
        ret_code_t err_code;
        uint8_t tx_buf[BMA2x2_GEN_READ_WRITE_LENGTH+1];
    	
        //Write the register address and data into transmit buffer
        tx_buf[0] = register_address;
        tx_buf[1] = value;
    
        //Set the flag to false to show the transmission is not yet completed
        m_xfer_done = false;
        
        //Transmit the data over TWI Bus
        err_code = nrf_drv_twi_tx(&m_twi, BMA2x2_I2C_ADDR1, tx_buf, BMA2x2_GEN_READ_WRITE_LENGTH+1, false);
        
        //Wait until the transmission of the data is finished
        while (m_xfer_done == false)
        {
          }
    
        // if there is no error then return true else return false
        if (NRF_SUCCESS != err_code)
        {
            return false;
        }
        
        return true;	
    }
     
    bool bmxme_verify_product_id(void)
    {
        uint8_t who_am_i; // create a variable to hold the who am i value
    
    
        if (bmxme_register_read(I_AM_BMX055_ACC, &who_am_i, 1))
        {
            if (who_am_i != I_AM_BMX055_ACC)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
        else
        {
            return false;
        }
    
    }
    /*
      Function to initialize the bmx055
    */ 
    bool bmxme_init(void)
    {   
      bool transfer_succeeded = true;
        
      //Check the id to confirm that we are communicating with the right device
      transfer_succeeded &= bmxme_verify_product_id();
        
      if(bmxme_verify_product_id() == false)
        {
        return false;
          }
    
      // Set the registers with the required values, see the datasheet to get a good idea of these values
      (void)bmxme_register_write(BMA2x2_MODE_CTRL_ADDR , 0x00);
      (void)bmxme_register_write(BMA2x2_LOW_NOISE_CTRL_ADDR , 0x00);  
      (void)bmxme_register_write(BMA2x2_DATA_CTRL_ADDR , 0x40); 
      (void)bmxme_register_write(BMA2x2_BW_SELECT_ADDR , 0x08);
      (void)bmxme_register_write(BMA2x2_RANGE_SELECT_ADDR , 0x08);  
    
      return transfer_succeeded;
    }
    
    
    /*
      A Function to read data from the bmx055
    */ 
    bool bmxme_register_read(uint8_t register_address, uint8_t * destination, uint8_t number_of_bytes)
    {
        ret_code_t err_code;
    
        //Set the flag to false to show the receiving is not yet completed
        m_xfer_done = false;
        
        // Send the Register address where we want to write the data
        err_code = nrf_drv_twi_tx(&m_twi, BMA2x2_I2C_ADDR1 , &register_address, 1, true);
    	  
        //Wait for the transmission to get completed
        while (m_xfer_done == false){}
        
        // If transmission was not successful, exit the function with false as return value
        if (NRF_SUCCESS != err_code)
        {
            return false;
        }
    
        //set the flag again so that we can read data from the bmx055's internal register
        m_xfer_done = false;
    	  
        // Receive the data from the bmx055
        err_code = nrf_drv_twi_rx(&m_twi, BMA2x2_I2C_ADDR1, destination, number_of_bytes);
    		
        //wait until the transmission is completed
        while (m_xfer_done == false){}
    	
        // if data was successfully read, return true else return false
        if (NRF_SUCCESS != err_code)
        {
            return false;
        }
        
        return true;
    }
    
    
    /*
      A Function to read accelerometer's values from the internal registers of MPU6050
    */ 
    bool bmxme_ReadAcc( int16_t *pACC_X , int16_t *pACC_Y , int16_t *pACC_Z )
    {
      uint8_t xaxis_buf[2];
      uint8_t yaxis_buf[2];
      uint8_t zaxis_buf[2];
      bool ret = false;		
      
      if(bmxme_register_read(BMA2x2_X_AXIS_LSB_ADDR, xaxis_buf[0], 1) & bmxme_register_read(BMA2x2_X_AXIS_MSB_ADDR, xaxis_buf[1], 1) == true)
      {
        bmxme_register_read(BMA2x2_X_AXIS_LSB_ADDR, xaxis_buf[0], 1);
        bmxme_register_read(BMA2x2_X_AXIS_MSB_ADDR, xaxis_buf[1], 1);
        
        *pACC_X = (xaxis_buf[1] << 8) | xaxis_buf[0];
        if(*pACC_X & 0x8000) *pACC_X-=65536;
        ret = true;
        }
    
      if(bmxme_register_read(BMA2x2_Y_AXIS_LSB_ADDR, yaxis_buf[0], 1) & bmxme_register_read(BMA2x2_Y_AXIS_MSB_ADDR, yaxis_buf[1], 1) == true)
      {
        bmxme_register_read(BMA2x2_Y_AXIS_LSB_ADDR, yaxis_buf[0], 1);
        bmxme_register_read(BMA2x2_Y_AXIS_MSB_ADDR, yaxis_buf[1], 1);
    
        *pACC_Y= (yaxis_buf[1] << 8) | yaxis_buf[0];
        if(*pACC_Y & 0x8000) *pACC_Y-=65536;
        ret = true;
        }
    
      if(bmxme_register_read(BMA2x2_Z_AXIS_LSB_ADDR, zaxis_buf[0], 1) & bmxme_register_read(BMA2x2_Z_AXIS_MSB_ADDR, zaxis_buf[1], 1) == true)
      {
        bmxme_register_read(BMA2x2_Z_AXIS_LSB_ADDR, zaxis_buf[0], 1);
        bmxme_register_read(BMA2x2_Z_AXIS_MSB_ADDR, zaxis_buf[1], 1);
    
        *pACC_Z= (zaxis_buf[1] << 8) | zaxis_buf[0];
        if(*pACC_Z & 0x8000) *pACC_Z-=65536;
     		
        ret = true;
        }
      
      return ret;
    }
    
    
    
    

    and below is my main.c : 

    #include <stdio.h>
    #include "boards.h"
    #include "app_util_platform.h"
    #include "app_error.h"
    #include "nrf_drv_twi.h"
    #include "bma2x2.h"
    
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    
    
    int main(void)
    {   
    // initialize the logger
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    
          NRF_LOG_INFO("TWI accelerometer reading started.");
          
    	
    	
    // create arrays which will hold x,y & z co-ordinates values of acc
        static int16_t AccValue[3];
    
        bsp_board_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS); // initialize the leds and buttons
    
        twi_master_init(); // initialize the twi 
        nrf_delay_ms(1000); // give some delay
        bmxme_init();
        
        while(bmxme_init() == false) // wait until bm055 sensor is successfully initialized
        {
          NRF_LOG_INFO("BMX_055 initialization failed!!!"); // if it failed to initialize then print a message
          nrf_delay_ms(1000);
        }
    
       NRF_LOG_INFO("BMX055 Initialization Successful!!!"); 
    
       NRF_LOG_INFO("Reading Values from ACC"); // display a message to let the user know that the device is starting to read the values
       nrf_delay_ms(2000);
    
    
      
        
        while (true)
        {
            if(bmxme_ReadAcc(&AccValue[0], &AccValue[1], &AccValue[2]) == true) // Read acc value from bmx055 internal registers and save them in the array
            {
              NRF_LOG_INFO("ACC Values:  x = %d  y = %d  z = %d", AccValue[0], AccValue[1], AccValue[2]); // display the read values
            }
            else
            {
              NRF_LOG_INFO("Reading ACC values Failed!!!"); // if reading was unsuccessful then let the user know about it
            }
    
    
           nrf_delay_ms(100); // give some delay 
    
    
        }
    }
    
    /** @} */
     

  • Hi,

    Do you get any output on the serial terminal, for instance the line "TWI accelerometer reading started."?

    If not, have you enabled NRF_LOG and the UART backend in your sdk_config.h file?

    // <e> NRF_LOG_ENABLED - nrf_log - Logger
    //==========================================================
    #ifndef NRF_LOG_ENABLED
    #define NRF_LOG_ENABLED 1
    #endif
    
    // <e> NRF_LOG_BACKEND_UART_ENABLED - nrf_log_backend_uart - Log UART backend
    //==========================================================
    #ifndef NRF_LOG_BACKEND_UART_ENABLED
    #define NRF_LOG_BACKEND_UART_ENABLED 1
    #endif

    If you have the logger configured to use deferred mode (NRF_LOG_DEFERRED set to 1), you also needs to process the log in your main while-loop:

    while(NRF_LOG_PROCESS() == true);
    
    //or:
    
    NRF_LOG_FLUSH();
    
    

    Best regards,
    Jørgen

  • No, I don't even have this in output "TWI accelerometer reading started."

    yes I have already enable NRF_LOG_ENABLED and NRF_LOG_BACKEND_UART_ENABLED.

    I also tried this while(NRF_LOG_PROCESS() == true);

    but still the it is not showing anything.

     

  • Have you checked if the application runs correctly at all, or is it "stuck" in a reset-loop? If you add blinking of LEDs in your application, that would indicate if it is running correctly apart from the logging.

    I would also recommend you to build the application with the Debug configuration enabled, and run the debugger to see if there are any errors reported or HardFaults happening. 

    Which SDK version are you using?

Related