Bosch Sensortec Community

    cancel
    Showing results for 
    Search instead for 
    Did you mean: 
    SOLVED

    BMX160 Magnetometer data not changing

    Established Member

    Re: BMX160 Magnetometer data not changing

    Hi

    After setting my DRDY & TAP INT correctly, according to the solution I figured out on this post, I went back to the MAG settings.
    Here is my updated init code:

    /*wrapper function to match the signature of bmm150.read */
    int8_t bmm150_aux_read(uint8_t id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
    {
      /* Discarding the parameter id as it is redundant*/
      return bmi160_aux_read(reg_addr, reg_data, len, &bmi);
    }
    
    /*wrapper function to match the signature of bmm150.write */
    int8_t bmm150_aux_write(uint8_t id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
    {
      printf("bmm_W: reg=%02x, val=%02x\r\n", reg_addr, ((uint8_t *)reg_data)[0] );
      /* Discarding the parameter id as it is redundant */
      return bmi160_aux_write(reg_addr, reg_data, len, &bmi);
    }
    
    uint8_t aux_addr = BMM150_DATA_X_LSB;   /* In BMM150 Mag data starts from register address 0x42 */
    
    // --------------- Init BMX160 ---------------------
    bmi.id = BMI160_I2C_ADDR;
    bmi.interface = BMI160_I2C_INTF;
    bmi.read = I2C_0_readDataBlock;
    bmi.write = performDimWrite;
    bmi.delay_ms = delay_miliSec;
    
    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_miliSec;
    
    rslt_ = bmi160_init(&bmi);
    printf("bmi160_init:%i\r\n", rslt_);
    
    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;
    
    rslt_ = bmi160_aux_init(&bmi);
    printf("bmi160_aux_init:%i\r\n", rslt_);
    
    rslt_ = bmm150_init(&bmm);
    printf("bmm150_init:%i\r\n", rslt_);
    
    //// --------------- Acc & Gryo ---------------------
    ////printf("Init:AccGyro\r\n");
    //// Configure accel and gyro sensors in normal mode
    bmi.accel_cfg.odr = BMI160_ACCEL_ODR_50HZ;
    bmi.accel_cfg.range = BMI160_ACCEL_RANGE_4G;
    bmi.accel_cfg.bw = BMI160_ACCEL_BW_NORMAL_AVG4;
    bmi.accel_cfg.power = BMI160_ACCEL_NORMAL_MODE;
    
    bmi.gyro_cfg.odr = BMI160_GYRO_ODR_50HZ;
    bmi.gyro_cfg.range = BMI160_GYRO_RANGE_125_DPS;
    bmi.gyro_cfg.bw = BMI160_GYRO_BW_NORMAL_MODE;
    bmi.gyro_cfg.power = BMI160_GYRO_SUSPEND_MODE;
    
    
    struct bmi160_int_settg bmi_int_config;
    // Configure sensor interrupt (Data Ready)
    printf("Init:DataReady\r\n");
    /* Select the Interrupt channel/pin */
    bmi_int_config.int_channel = BMI160_INT_CHANNEL_1;// Interrupt channel/pin 1
    /* Select the interrupt channel/pin settings */
    bmi_int_config.int_pin_settg.output_en = BMI160_ENABLE;// Enabling interrupt pins to act as output pin
    bmi_int_config.int_pin_settg.output_mode = BMI160_DISABLE;// Choosing push-pull mode for interrupt pin
    bmi_int_config.int_pin_settg.output_type = BMI160_ENABLE;// Choosing active High output
    bmi_int_config.int_pin_settg.edge_ctrl = BMI160_ENABLE;// Choosing level triggered output
    bmi_int_config.int_pin_settg.input_en = BMI160_DISABLE;// Disabling interrupt pin to act as input
    bmi_int_config.int_pin_settg.latch_dur =BMI160_LATCH_DUR_NONE;// non-latched output
    /* Select the Interrupt type */
    bmi_int_config.int_type = BMI160_ACC_GYRO_DATA_RDY_INT;// Choosing Data Ready interrupt
    /* Set the Data Ready interrupt */
    rslt_ = bmi160_set_int_config(&bmi_int_config, &bmi); /* sensor is an instance of the structure bmi160_dev */
    printf("bmi160_set_int_config:%i\r\n", rslt_);
    
    // Configure sensor interrupt (Tap)
    printf("Init:Tap\r\n");
    /* Select the Interrupt channel/pin */
    bmi_int_config.int_channel = BMI160_INT_CHANNEL_2;// Interrupt channel/pin 2
    /* Select the interrupt channel/pin settings */
    bmi_int_config.int_pin_settg.output_en = BMI160_ENABLE;// Enabling interrupt pins to act as output pin
    bmi_int_config.int_pin_settg.output_mode = BMI160_DISABLE;// Choosing push-pull mode for interrupt pin
    bmi_int_config.int_pin_settg.output_type = BMI160_ENABLE;// Choosing active High output
    bmi_int_config.int_pin_settg.edge_ctrl = BMI160_ENABLE;// Choosing level triggered output
    bmi_int_config.int_pin_settg.input_en = BMI160_DISABLE;// Disabling interrupt pin to act as input
    bmi_int_config.int_pin_settg.latch_dur = BMI160_LATCH_DUR_NONE;// non-latched output
    /* Select the Interrupt type: Tap */
    bmi_int_config.int_type = BMI160_ACC_SINGLE_TAP_INT;// Choosing Step Detector interrupt
    /* Select the Step Detector interrupt parameters, Kindly use the recommended settings for step detector */
    bmi_int_config.int_type_cfg.acc_tap_int.tap_en = BMI160_ENABLE;// 1-enable, 0-disable the detector
    bmi_int_config.int_type_cfg.acc_tap_int.tap_data_src=BMI160_DISABLE; // use pre-filter
    bmi_int_config.int_type_cfg.acc_tap_int.tap_dur = 1;  // not applicable to single tap
    bmi_int_config.int_type_cfg.acc_tap_int.tap_quiet = BMI160_DISABLE;  // 30/20ms
    bmi_int_config.int_type_cfg.acc_tap_int.tap_shock = BMI160_DISABLE;  // 50/75ms
    bmi_int_config.int_type_cfg.acc_tap_int.tap_thr = 10; // 0-31: 125mg/2 = 62.5mg per bit (4g range)
    /* Set the Tap Detector interrupt */
    rslt_ = bmi160_set_int_config(&bmi_int_config, &bmi); /* sensor is an instance of the structure bmi160_dev */
    printf("bmi160_set_int_config:%i\r\n", rslt_);
    
    
    /* Set the sensor configuration */
    rslt_ = bmi160_set_sens_conf(&bmi);
    printf("bmi160_set_sens_conf:%i\r\n", rslt_);
    
    /*  Set the Power mode  */
    rslt_ = bmi160_set_power_mode(&bmi);
    printf("bmi160_set_power_mode:%i\r\n", rslt_);
      
    
    // --------------- Mag ---------------------
    //printf("Init:Mag\r\n");
    // from <a href="https://community.bosch-sensortec.com/t5/MEMS-sensors-forum/BMX160-magnetometer-problem/td-p/7628/page/2" target="_blank">https://community.bosch-sensortec.com/t5/MEMS-sensors-forum/BMX160-magnetometer-problem/td-p/7628/page/2</a>
    bmm.settings.pwr_mode = BMM150_NORMAL_MODE;
    rslt_ = bmm150_set_op_mode(&bmm);
    printf("bmm150_set_op_mode:%i\r\n", rslt_);
    
    bmm.settings.preset_mode = BMM150_PRESETMODE_ENHANCED;
    rslt_ = bmm150_set_presetmode(&bmm);
    printf("bmm150_set_presetmode:%i\r\n", rslt_);
    
    bmi.aux_cfg.aux_odr = BMI160_AUX_ODR_50HZ;
    rslt_ = bmi160_config_aux_mode(&bmi);
    printf("bmi160_config_aux_mode:%i\r\n", rslt_);
    
    bmm.settings.pwr_mode = BMM150_FORCED_MODE;
    rslt_ = bmm150_set_op_mode(&bmm);
    printf("bmm150_set_op_mode:%i\r\n", rslt_);
    
    // set aux/mag to auto mode
    rslt_ = bmi160_set_aux_auto_mode(&aux_addr, &bmi);
    printf("bmi160_set_aux_auto_mode:%i\r\n", rslt_);

     

    I have changed my read code to poll the mag_drdy bit to check for new data. This bit is only set once right after init completes.

    In an effort to see what is begin written to the internal BMM150 (contained in the BMX160), I put a printf at the bmm150_aux_write function.
    Here is the full output from the above init code:

    bmi160_init:0
    bmi160_aux_init:0
    bmm_W: reg=4b, val=01
    bmm150_init:0
    Init:DataReady
    bmi160_set_int_config:0
    Init:Tap
    bmi160_set_int_config:0
    bmi160_set_sens_conf:0
    bmi160_set_power_mode:0
    bmm_W: reg=4c, val=00
    bmm150_set_op_mode:0
    bmm_W: reg=4c, val=00
    bmm_W: reg=51, val=07
    bmm_W: reg=52, val=1a
    bmm150_set_presetmode:0
    bmi160_config_aux_mode:0
    bmm_W: reg=4c, val=02
    bmm150_set_op_mode:0
    bmi160_set_aux_auto_mode:0

     And here is the declutted version only showing the registers being written to the BMM150:

    bmm_W: reg=4b, val=01
    bmm_W: reg=4c, val=00
    bmm_W: reg=4c, val=00
    bmm_W: reg=51, val=07
    bmm_W: reg=52, val=1a
    bmm_W: reg=4c, val=02

     

    I've relooked at the example on the BMX160 GitHub page, but I'm still not getting measurement data from the BMX160's MAG.

    I'm getting desparate at all the examples I've tried are not giving any results.

    Has anyone been able to get the BMX160's MAG working at the same data rate as the ACC? I'll even accept a slower output rate just to verify my setup.
    Could you please post example code?

    Thanks

    Established Member

    Re: BMX160 Magnetometer data not changing

    Hi rdehart,

    this might be a dumb suggestion, but did you check the hardware connections? Are VDD and VDDIO connected to your power source?

    Kind regards,

    Marko Njirjak

    Highlighted
    Established Member

    Re: BMX160 Magnetometer data not changing

    Hi Marko

    Yes. I confirmed both VDD & VDDIO are connected to the voltage source.

    I also scoped the SCLA line and the clock is rising fast enough for 100kHz and not ringing.

    It seems the hardware is fine, since the ACC data is coming through.

    Thanks for the thought

    Established Member

    Re: BMX160 Magnetometer data not changing

    Just to check, I am going to try 2 things (not sure if these would affect MAG data):

    1. Enable the GYRO sensor. I disabled it in my previous code, but could it be that both the ACC & GYRO need to be enabled for the MAG to work?
    2. Reduce the I2C clk speed. I have been testing at 100kHz. Could it be that the BMX160 needs to operate at a slower I2C clock speed? From what I read in the datasheet, 100kHz should be fine, but maybe there is datasheet erata that I haven't seen?
    Community Moderator
    Community Moderator

    Re: BMX160 Magnetometer data not changing

    1: Enabling the gyroscope has no impact. Accel, Gyro and Aux have different power modes, I can confirm that.
    2: I also doubt that the i2c bus be the issue here. I would mostly focus on making sure the correct registers are set to the correct values. The best is always a logic analyzer log.

    Can you post the logic traces from both primary bus and secondary bus ? If you don't have physical access, please insert traces functions for all i2c read and writes to the primary bus.

    To confirm the hardware too, you can post your schematic snippet here, we can review it.
    Icon--AD-black-48x48Icon--address-consumer-data-black-48x48Icon--appointment-black-48x48Icon--back-left-black-48x48Icon--calendar-black-48x48Icon--center-alignedIcon--Checkbox-checkIcon--clock-black-48x48Icon--close-black-48x48Icon--compare-black-48x48Icon--confirmation-black-48x48Icon--dealer-details-black-48x48Icon--delete-black-48x48Icon--delivery-black-48x48Icon--down-black-48x48Icon--download-black-48x48Ic-OverlayAlertIcon--externallink-black-48x48Icon-Filledforward-right_adjustedIcon--grid-view-black-48x48IC_gd_Check-Circle170821_Icons_Community170823_Bosch_Icons170823_Bosch_Icons170821_Icons_CommunityIC-logout170821_Icons_Community170825_Bosch_Icons170821_Icons_CommunityIC-shopping-cart2170821_Icons_CommunityIC-upIC_UserIcon--imageIcon--info-i-black-48x48Icon--left-alignedIcon--Less-minimize-black-48x48Icon-FilledIcon--List-Check-grennIcon--List-Check-blackIcon--List-Cross-blackIcon--list-view-mobile-black-48x48Icon--list-view-black-48x48Icon--More-Maximize-black-48x48Icon--my-product-black-48x48Icon--newsletter-black-48x48Icon--payment-black-48x48Icon--print-black-48x48Icon--promotion-black-48x48Icon--registration-black-48x48Icon--Reset-black-48x48Icon--right-alignedshare-circle1Icon--share-black-48x48Icon--shopping-bag-black-48x48Icon-shopping-cartIcon--start-play-black-48x48Icon--store-locator-black-48x48Ic-OverlayAlertIcon--summary-black-48x48tumblrIcon-FilledvineIc-OverlayAlertwhishlist