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


}
}

/** @} */

Parents Reply Children
  • 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 
    
    
        }
    }
    
    /** @} */
     

Related