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 , ®ister_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
}
}
/** @} */