This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

NRF51422 I2C sensor (TWI)

Hello everyone,
I have an external board with processor nrf51422 and sensor BNO055 (I2C).
I have a processor code created by someone else and I have a problem getting data from the sensor. I know that similar topics have already appeared on the forum, but despite many attempts I have not managed to establish communication.  

I receive "some" data, but they are not logical and change all the time. For example, when I try to read the sensor temperature, I get the values 0x0090, then 0x2003, then 0x0003, then 0x2000, etc.

So I present the original, theoretically working version of Twi_functions.

Twi_functions.c

#include "twi_functions.h"

/* TWI instance. */
const nrf_drv_twi_t twi_sensors_instance = NRF_DRV_TWI_INSTANCE(1);

void twi_init (void)
{
    ret_code_t err_code;

    const nrf_drv_twi_config_t twi_sensors_config = {
       .scl                = I2C_SENSORS_SCL_PIN,
       .sda                = I2C_SENSORS_SDA_PIN,
       .frequency          = NRF_TWI_FREQ_100K,
       .interrupt_priority = APP_IRQ_PRIORITY_LOW
    };

    err_code = nrf_drv_twi_init(&twi_sensors_instance, &twi_sensors_config, NULL, NULL);
    APP_ERROR_CHECK(err_code);

    nrf_drv_twi_enable(&twi_sensors_instance);
}

void twi_read_register(uint8_t slave_address, uint8_t register_address, uint8_t *read_data, uint8_t data_length) {
	// Send register address
	nrf_drv_twi_tx(&twi_sensors_instance, slave_address, &register_address, sizeof(register_address), true);
	// Receive data
	nrf_drv_twi_rx(&twi_sensors_instance, slave_address, read_data, data_length, false);
}

void twi_write_register(uint8_t slave_address, uint8_t register_address, uint8_t *data, uint8_t data_length){
	uint8_t data_packet[data_length + 1];
	data_packet[0] = register_address;
	memcpy(data_packet+1,data, data_length);
	nrf_drv_twi_tx(&twi_sensors_instance, slave_address, data_packet, data_length +1, false);
}

Example of use
int8_t bno055_getTemp() {
  bno055_setPage(0);
  uint8_t t;
  bno055_readData(BNO055_TEMP, &t, 1);
  return t;
}
void bno055_setup() {
  bno055_reset();
  uint8_t id = 0;
  bno055_readData(BNO055_CHIP_ID, &id, 1);
  if (id != BNO055_ID) {
    printf("Can't find BNO055, id: 0x%02x. Please check your wiring.\r\n", id);
  }
  bno055_setPage(0);
  uint8_t tmp = 0x0;
  bno055_writeData(BNO055_SYS_TRIGGER, &tmp);

  // Select BNO055 config mode
  bno055_setOperationModeConfig();
  bno055_delay(10);
}

void bno055_writeData(uint8_t reg, uint8_t *data) {
twi_write_register(BNO055_I2C_ADDR_LO,reg, data, sizeof(*data));
}

void bno055_readData(uint8_t reg, uint8_t *data, uint8_t len) {
twi_read_register(BNO055_I2C_ADDR_LO, reg, data, len);
}
Could someone indicate where the error is?
The problem may also be with the sensor itself, so could anyone suggest a simple read / write register test?
Regards
  • There should be a few twi examples in the nRF5 SDK, I assume you have taken a look at those. A logic analyzer trace would be valuable here(e.g. https://www.saleae.com/), to find if the actual data on the TWI bus. If you have data that is not stable, then it may be a twi variable (address, tx or rx buffer) is not declared right. Try to set them to 'static volatile' this should ensure they are kept outside the function you may be calling them.

    Best regards,
    Kenneth

Related