BMX160 magnetometer problem

Hello,

I bought a BMX160 shuttleboard and connected it to master chip via 4-wire SPI. By following the instructions in the data sheet I was able to setup and read the data from accelerometer and gyroscope. Unfortunately I wasn't able to do the same with magnetometer. The readings from magnetometer constantly return zeros. What is the procedure for configuring magnetometer and fetching data? Is the procedure described in table 16, section 2.4.3.1.3 of BMX160 data sheet enough? I fetched the data by reading data registers (0x04-0x0B) described in  section 2.11.4.

Magnetometer configuration code:

 

write_spi(0x7E, 0x19);
delay_ms(1);
write_spi(0x4C, 0x80);
write_spi(0x4F, 0x01);
write_spi(0x4E, 0x4B);
write_spi(0x4F, 0x01);
write_spi(0x4E, 0x51);
write_spi(0x4F, 0x0E);
write_spi(0x4E, 0x52);
write_spi(0x4F, 0x02);
write_spi(0x4E, 0x4C);
write_spi(0x4D, 0x42);
write_spi(0x44, 0x05);
write_spi(0x4C, 0x00);
write_spi(0x7E, 0x1A);
delay_ms(1);

 

Magnetometer fetch data code:

 

uint8_t data;

//X-axis
read_spi(0x05, &data); //MSB
*mag_x = data;

*mag_x = *mag_x << 8;

read_spi(0x04, &data); //LSB
*mag_x |= data;

//Y-axis
read_spi(0x07, &data); //MSB
*mag_y = data;

*mag_y = *mag_y << 8;

read_spi(0x06, &data); //LSB
*mag_y |= data;

//Z-axis
read_spi(0x09, &data); //MSB
*mag_z = data;

*mag_z = *mag_z << 8;

read_spi(0x08, &data); //LSB
*mag_z |= data;

//RHALL
read_spi(0x0B, &data); //MSB
*rhall = data;

*rhall = *rhall << 8;

read_spi(0x0A, &data); //LSB
*rhall |= data;

 

Kind regards,

Marko Njirjak

Best reply by mnjirjak

OK, I figured it out. Unfortunately I forgot to connect VDDIO pin to the power supply. After I did so and tried the sample code, everything worked like a charm. Thank you very much for your assistance, I really appreciate it.

For anyone else experiencing the same problem, please make sure you connect VDDIO to power supply. The code that I used can be found here. I modified it a bit and tested everything by reading all three sensors. Here's the code that I used:

 

#include "bmi160.h"
#include "bmm150.h"

struct bmi160_dev bmi;
struct bmm150_dev bmm;

struct bmi160_sensor_data accel;
struct bmi160_sensor_data gyro;

int8_t bmm150_aux_read(uint8_t id, uint8_t reg_addr, uint8_t *aux_data, uint16_t len);
int8_t bmm150_aux_write(uint8_t id, uint8_t reg_addr, uint8_t *aux_data, uint16_t len);

int main(void)
{
    bmi.id = 0;
    bmi.interface = BMI160_SPI_INTF;
    bmi.read = spi_read_transfer;
    bmi.write = spi_write_transfer;
    bmi.delay_ms = delay;

    bmm.dev_id = BMM150_DEFAULT_I2C_ADDRESS;
    bmm.intf = BMM150_I2C_INTF;
    bmm.read = bmm150_aux_read;
    bmm.write = bmm150_aux_write;
    bmm.delay_ms = delay;

    bmi160_init(&bmi);
  
    bmi.aux_cfg.aux_sensor_enable = BMI160_ENABLE;
    bmi.aux_cfg.aux_i2c_addr = bmm.dev_id;
    bmi.aux_cfg.manual_enable = BMI160_ENABLE;
    bmi.aux_cfg.aux_rd_burst_len = BMI160_AUX_READ_LEN_3;

    bmi160_aux_init(&bmi);
    bmm150_init(&bmm);

    bmi.accel_cfg.odr = BMI160_ACCEL_ODR_100HZ;
    bmi.accel_cfg.range = BMI160_ACCEL_RANGE_2G;
    bmi.accel_cfg.bw = BMI160_ACCEL_BW_NORMAL_AVG4;
    bmi.accel_cfg.power = BMI160_ACCEL_NORMAL_MODE;

    bmi.gyro_cfg.odr = BMI160_GYRO_ODR_100HZ;
    bmi.gyro_cfg.range = BMI160_GYRO_RANGE_2000_DPS;
    bmi.gyro_cfg.bw = BMI160_GYRO_BW_NORMAL_MODE;
    bmi.gyro_cfg.power = BMI160_GYRO_NORMAL_MODE;

    bmi160_set_sens_conf(&bmi);

    bmm.settings.preset_mode = BMM150_PRESETMODE_REGULAR;
    bmm150_set_presetmode(&bmm);

    bmm.settings.pwr_mode = BMM150_FORCED_MODE;
    bmm150_set_op_mode(&bmm);


	uint8_t aux_addr = 0x42;	
	uint8_t mag_data[8] = {0};
	
	uint8_t index;

	bmi.aux_cfg.aux_odr = 8;
	bmi160_config_aux_mode(&bmi);
	
	bmi160_set_aux_auto_mode(&aux_addr, &bmi);


    while(1) {
        bmi160_get_sensor_data((BMI160_ACCEL_SEL | BMI160_GYRO_SEL), &accel, &gyro, &bmi);
    	bmi160_read_aux_data_auto_mode(mag_data, &bmi);
    	bmm150_aux_mag_data(mag_data, &bmm);

        printf("****************\n");
        printf("ACC X: %d, Y: %d, Z: %d\n", accel.x, accel.y, accel.z);
        printf("GYRO X: %d, Y: %d, Z: %d\n", gyro.x, gyro.y, gyro.z);
    	printf("MAG X : %d Y : %d Z : %d\n", bmm.data.x, bmm.data.y, bmm.data.z);
        printf("################\n");
    }
}

int8_t bmm150_aux_read(uint8_t id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len) {
    (void) id;
    return bmi160_aux_read(reg_addr, reg_data, len, &bmi);
}

int8_t bmm150_aux_write(uint8_t id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len) {
    (void) id;
    return bmi160_aux_write(reg_addr, reg_data, len, &bmi);
}

where spi_read_transfer, spi_write_transfer and delay represent master-chip-specific functions for spi transfers and delay.

The sample data that I got:

****************
ACC X: -16140, Y: 27, Z: -551
GYRO X: 7, Y: 3, Z: -5
MAG X : 37 Y : -12 Z : 6
################
****************
ACC X: -16171, Y: -18, Z: -516
GYRO X: 8, Y: 2, Z: -5
MAG X : 36 Y : -12 Z : 7
################
****************
ACC X: -16132, Y: -13, Z: -550
GYRO X: 8, Y: 3, Z: -5
MAG X : 37 Y : -12 Z : 8
################

Once again, thank you for your help!

Kind regards,

Marko Njirjak

 

View original
8 replies
Resolved