Using a BMX160 connected over I2C to a Raspberry Pi I have the following two issues:
1. The magnetometer self-tests fail (both the normal and advanced test). On the contrary, the accelerometer and gyroscope self-tests succeed.
2. The Fast Offset Calibration for the accelerometer and gyroscope fails, with error -11.
Could you please provide any tips as to why this might be? Thank you in advance.
Code for setting up the sensor:
void calibrate_sensor()
{
struct bmi160_foc_conf foc_conf;
struct bmi160_offsets offsets;
foc_conf.acc_off_en = BMI160_ENABLE;
foc_conf.foc_acc_x = BMI160_FOC_ACCEL_0G;
foc_conf.foc_acc_y = BMI160_FOC_ACCEL_0G;
foc_conf.foc_acc_z = BMI160_FOC_ACCEL_POSITIVE_G;
foc_conf.foc_gyr_en = BMI160_ENABLE;
foc_conf.gyro_off_en = BMI160_ENABLE;
//////// FIXME: This fails and returns -11
auto rslt = bmi160_start_foc(&foc_conf, &offsets, &m_bmi);
handle_potential_error(rslt, "bmi160_start_fox");
}
void test_sensor()
{
auto rslt = bmi160_perform_self_test(BMI160_ACCEL_ONLY, &m_bmi);
handle_potential_error(rslt, "bmi160_perform_self_test; accelerometer");
user_delay_ms(100);
rslt = bmi160_perform_self_test(BMI160_GYRO_ONLY, &m_bmi);
handle_potential_error(rslt, "bmi160_perform_self_test; gyroscope");
user_delay_ms(100);
////////FIXME: Test fails
rslt = bmm150_perform_self_test(BMM150_NORMAL_SELF_TEST, &m_bmm);
handle_potential_error(rslt, "bmm150_perform_self_test: magnetometer");
}
void setup_sensor()
{
int8_t rslt;
m_bmi.id = BMI160_I2C_ADDR;
m_bmi.interface = BMI160_I2C_INTF;
m_bmi.read = i2c_read;
m_bmi.write = i2c_write;
m_bmi.delay_ms = user_delay_ms;
rslt = bmi160_init(&m_bmi);
handle_potential_error(rslt, "bmi160_init");
/* Configure the BMM150 device structure by mapping user_aux_read and user_aux_write */
m_bmm.read = user_aux_read;
m_bmm.write = user_aux_write;
m_bmm.dev_id = BMM150_DEFAULT_I2C_ADDRESS;
/* Ensure that sensor.aux_cfg.aux_i2c_addr = bmm150.id for proper sensor operation */
m_bmm.delay_ms = user_delay_ms;
m_bmm.intf = BMM150_I2C_INTF;
/* Configure device structure for auxiliary sensor parameter */
m_bmi.aux_cfg.aux_sensor_enable = BMI160_ENABLE; // auxiliary sensor enable
m_bmi.aux_cfg.aux_i2c_addr = m_bmm.dev_id; // auxiliary sensor address
m_bmi.aux_cfg.manual_enable = BMI160_ENABLE; // setup mode enable
m_bmi.aux_cfg.aux_rd_burst_len = BMI160_AUX_READ_LEN_3 ;// burst read; 8 bytes
/* Initialize the auxiliary sensor interface */
rslt = bmi160_aux_init(&m_bmi);
handle_potential_error(rslt, "bmi160_aux_init");
/* Auxiliary sensor is enabled and can be accessed from this point */
/* Configure the desired settings in auxiliary BMM150 sensor
* using the bmm150 APIs */
/* Initialising the bmm150 sensor */
rslt = bmm150_init(&m_bmm);
handle_potential_error(rslt, "bmm150_init");
/* After the above function call, accel and gyro parameters in the device structure
are reset with default values, found in the datasheet of the sensor */
m_bmi.accel_cfg.odr = BMI160_ACCEL_ODR_25HZ; // Output data rate
m_bmi.accel_cfg.range = BMI160_ACCEL_RANGE_2G; // Range
m_bmi.accel_cfg.bw = BMI160_ACCEL_BW_NORMAL_AVG4; // Bandwidth
m_bmi.accel_cfg.power = BMI160_ACCEL_NORMAL_MODE; // Power mode
m_bmi.gyro_cfg.odr = BMI160_GYRO_ODR_25HZ; // Output data rate
m_bmi.gyro_cfg.range = BMI160_GYRO_RANGE_500_DPS; // Range
m_bmi.gyro_cfg.bw = BMI160_GYRO_BW_NORMAL_MODE; // Bandwidth
m_bmi.gyro_cfg.power = BMI160_GYRO_NORMAL_MODE; // Power mode
m_bmm.settings.preset_mode= BMM150_PRESETMODE_REGULAR;
rslt = bmm150_set_presetmode(&m_bmm);
handle_potential_error(rslt, "bmm150_set_presetmode");
// It is important that the last write to the BMM150 sets the forced mode.
// This is because the BMI160 writes the last value to the auxiliary sensor
// after every read
m_bmm.settings.pwr_mode = BMM150_FORCED_MODE;
rslt = bmm150_set_op_mode(&m_bmm);
handle_potential_error(rslt, "bmm150_set_op_mode");
m_bmi.aux_cfg.aux_odr = BMI160_AUX_ODR_25HZ; // Aux polling frequency
rslt = bmi160_config_aux_mode(&m_bmi);
handle_potential_error(rslt, "bmi160_config_aux_mode");
uint8_t aux_addr = BMM150_DATA_X_LSB; // BMM150 Mag data starts from register address 0x42
rslt = bmi160_set_aux_auto_mode(&aux_addr, &m_bmi);
handle_potential_error(rslt, "bmi160_set_aux_auto_mode");
rslt = bmi160_set_sens_conf(&m_bmi); // Set configuration
handle_potential_error(rslt, "bmi160_set_sens_conf");
}
I initiate the tests and calibration using the following snippet:
setup_sensor();
test_sensor();
setup_sensor();
calibrate_sensor();