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

Reply
  • 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

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

  • well now the output is showing in NRF log. the deferred was to be disabled. 

    But now i am stuck in Reading the x,y,z values from BMX055 sensor.

    It just goes till 

    line 42 : NRF_LOG_INFO("Reading Values from ACC");  

    but the verification and initialization is successful. It means that my read and write functions of i2c are working fine. But to read values, that function is having some issue. 

    Can you have a look, Your support would highly be appreciated 

  • You should change this code in bmxme_register_read() and bmxme_register_write():

    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;
    }

    You need to check the error before waiting for the flag. With the current code, if there is an error preventing the transfer from starting, your application will block waiting for the event indicating that the transfer completed, before it is able to detect that the transfer never started.

Related