Bosch Sensortec Community

    Showing results for 
    Search instead for 
    Did you mean: 

    BMX160: FOC failure and magnetometer self-test failure

    BMX160: FOC failure and magnetometer self-test failure

    New Poster

    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");
            rslt = bmi160_perform_self_test(BMI160_GYRO_ONLY, &m_bmi);
            handle_potential_error(rslt, "bmi160_perform_self_test; gyroscope"); 
    ////////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; 
   = BMI160_I2C_ADDR;
            m_bmi.interface = BMI160_I2C_INTF;
   =  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 */
   = 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 = 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 
        = 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 
         = 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:




    6 REPLIES 6

    I forgot to clarify that I can get accelerometer, gyroscope and magnetometer data from the device using the FIFO.

    Community Moderator
    Community Moderator

    The delay in the trigger_foc is quite enough actually. 

    I realize there is no delay after change the sensor power mode.  after change the power mode from sleep to normal,  sensor will have a start up time around 55ms.    So you need to wait after change sensor power mode before you trigger FOC command. 

    So you don't need to change delay time in trigger_foc.  but in your main code,  adding around 100ms delay after change power mode. 

    For magnetic self test,  if you are able to get data,  it should be ok.

    maybe we need step by step debug here. 

    1. aux interface should be set as manual mode

    2. after bmm150 init function (here you will read bmm150 chip to verify sensor is there.  means you are able to communicate with bmm150 on aux bus)

    3. start the bmm self test code (host need to write some register into bmm150 then read back some value).

    I put the self test right after init just because in the init function, the aux interface was work as expected.