Bosch Sensortec Community

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

    BMX160 Magnetometer data not changing

    Highlighted
    Established Member

    BMX160 Magnetometer data not changing

    Hi

    I've been able to get the BMX160 setup to update the Acc & Mag at 50Hz.
    I followed the setup in the BMX160 datasheet, Table 16. Only difference is the ODR = 0x07 and REPXY and REPZ are set for to the high accuracy preset.

    I have enabled Data Ready on INT1 pin.

    When I receive an interrupt from INT1, I check the STATUS (0x1B) register and can confirm that both drdy_acc and drdy_mag are set (value=0xB0).
    I then do a block ready from DATA_0 to DATA_19 and confirm that the Acc data is still correct.
    However the Mag data does not change. I get an initial non-zero measurement, but then nothing changes further.

    Why is the Mag data not changing?
    Is there some setting I'm missing in the Mag setup?

    Thanks

    20 REPLIES 20
    Community Moderator
    Community Moderator

    Re: BMX160 Magnetometer data not changing

    Did you find this article already ?

    There is an important note:

    /* 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 */
    bmm.settings.pwr_mode = BMM150_FORCED_MODE;
    rslt = bmm150_set_op_mode(&bmm);

     


    @rdehart wrote:

    Hi

    I've been able to get the BMX160 setup to update the Acc & Mag at 50Hz.

    Only difference is the ODR = 0x07 and REPXY and REPZ are set for to the high accuracy preset.

    Note that High accuracy preset takes a longer time to sample and maximum datarate is 20Hz in that mode. I recommend to use the "Enhanced regular" preset if you need 50Hz data

    Established Member

    Re: BMX160 Magnetometer data not changing

    Thanks for the tip o_o
    Unfortunately I had no success setting the Magenetometer to "Enhanced Regular", "Regular" or "Low Power" presets.

    Here is my full initialisation of the sensor.

    Any thoughts?

    // --------------- 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 ---------------------
    //// 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_OSR4_AVG1;
    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_OSR4_MODE;
    bmi.gyro_cfg.power = BMI160_GYRO_SUSPEND_MODE;
    
    rslt_ = bmi160_set_sens_conf(&bmi);
    printf("bmi160_set_sens_conf:%i\r\n", rslt_);
    
    
    // Configure sensor interrupt (Data Ready)
    /* Select the Interrupt channel/pin */
    bmi_int_config.int_channel = BMI160_INT_CHANNEL_1;// Interrupt channel/pin 1
    /* Select the Interrupt type */
    bmi_int_config.int_type = BMI160_ACC_GYRO_DATA_RDY_INT;// Choosing Data Readay interrupt
    /* 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
    /* 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 type: Tap */
    bmi_int_config.int_type = BMI160_ACC_SINGLE_TAP_INT;// Choosing Step Detector interrupt
    /* 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 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_ENABLE; // use pre-filter
    bmi_int_config.int_type_cfg.acc_tap_int.tap_dur = 0b001;
    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 = 0b11111; // 125mg/2 = 62.5mg per bit (4g range)
    // Setup INT_TAP[0] correctly
    rslt_ = 0b00000111;
    performDimWrite(BMI160_I2C_ADDR, BMI160_INT_TAP_0_ADDR, &rslt_, 1 );
    // Setup INT_TAP[1] correctly
    rslt_ = 0b00001111;
    performDimWrite(BMI160_I2C_ADDR, BMI160_INT_TAP_1_ADDR, &rslt_, 1 );
    
    /* Set the Step 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_);
    
    // correct INT channel for Tap. Bug in library
    // disable int1_s_tap
    I2C_0_readDataBlock(BMI160_I2C_ADDR, BMI160_INT_MAP_0_ADDR ,  &rslt_, 1);
    rslt_ = rslt_ & 0b11011111;
    performDimWrite(BMI160_I2C_ADDR, BMI160_INT_MAP_0_ADDR, &rslt_, 1 );
    // enable int2_s_tap
    I2C_0_readDataBlock(BMI160_I2C_ADDR, BMI160_INT_MAP_2_ADDR ,  &rslt_, 1);
    rslt_ = rslt_ | 0b00100000;
    performDimWrite(BMI160_I2C_ADDR, BMI160_INT_MAP_2_ADDR, &rslt_, 1 );
    
    // --------------- 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>
    // from datasheet p.25
    rslt_ = 0x19; performDimWrite(BMI160_I2C_ADDR, BMI160_COMMAND_REG_ADDR, &rslt_, 1 );
    _delay_ms(2);
    rslt_ = 0x80; performDimWrite(BMI160_I2C_ADDR, BMI160_AUX_IF_1_ADDR, &rslt_, 1 );
    rslt_ = 0x01; performDimWrite(BMI160_I2C_ADDR, BMI160_AUX_IF_3_ADDR, &rslt_, 1 );
    rslt_ = 0x4B; performDimWrite(BMI160_I2C_ADDR, BMI160_AUX_IF_2_ADDR, &rslt_, 1 );
    rslt_ = 0x04; performDimWrite(BMI160_I2C_ADDR, BMI160_AUX_IF_3_ADDR, &rslt_, 1 );
    rslt_ = 0x51; performDimWrite(BMI160_I2C_ADDR, BMI160_AUX_IF_2_ADDR, &rslt_, 1 );
    rslt_ = 0x52; performDimWrite(BMI160_I2C_ADDR, BMI160_AUX_IF_3_ADDR, &rslt_, 1 );
    rslt_ = 0x52; performDimWrite(BMI160_I2C_ADDR, BMI160_AUX_IF_2_ADDR, &rslt_, 1 );
    rslt_ = 0x02; performDimWrite(BMI160_I2C_ADDR, BMI160_AUX_IF_3_ADDR, &rslt_, 1 );
    rslt_ = 0x4C; performDimWrite(BMI160_I2C_ADDR, BMI160_AUX_IF_2_ADDR, &rslt_, 1 );
    rslt_ = 0x42; performDimWrite(BMI160_I2C_ADDR, BMI160_AUX_IF_1_ADDR, &rslt_, 1 );
    rslt_ = 0x07; performDimWrite(BMI160_I2C_ADDR, BMI160_AUX_ODR_ADDR, &rslt_, 1 );
    rslt_ = 0x00; performDimWrite(BMI160_I2C_ADDR, BMI160_AUX_IF_1_ADDR, &rslt_, 1 );
    rslt_ = 0x19; performDimWrite(BMI160_I2C_ADDR, BMI160_COMMAND_REG_ADDR, &rslt_, 1 );
    _delay_ms(2);
    
    
    bmm.settings.pwr_mode = BMM150_FORCED_MODE;
    rslt_ = bmm150_set_op_mode(&bmm);
    printf("bmm150_set_op_mode:%i\r\n", rslt_);

     

    and here is my read code:

      I2C_0_readDataBlock( BMI160_I2C_ADDR, BMI160_AUX_DATA_ADDR, &raw_data, 20 );
      
      // Convert raw Acc data to "g"
      *accX = ACC_CONVERT_TO_G * (float)( raw_data[7] );
      *accY = ACC_CONVERT_TO_G * (float)( raw_data[8] );
      *accZ = ACC_CONVERT_TO_G * (float)( raw_data[9] );
      
      // Convert raw Mag data to "gauss"
      *magX = MAG_CONVERT_TO_GAUSS * (float)( raw_data[0] );
      *magY = MAG_CONVERT_TO_GAUSS * (float)( raw_data[1] );
      *magZ = MAG_CONVERT_TO_GAUSS * (float)( raw_data[2] );

     

    Thanks

    Community Moderator
    Community Moderator

    Re: BMX160 Magnetometer data not changing

    As general rule we try to help our customer to implement the Sensor API, rather than rewriting your own with direct register access. I am not quite sure why your magnetometer data configuration is a hexadecimal blob rather than using the API functions...

    Anyhow, you seem to be missing the key function call to start the auxiliary sensor automatic sampling:

    From the sample code on our GitHub:

     

    uint8_t bmm150_data_start = BMM150_DATA_X_LSB;
    bmi.aux_cfg.aux_odr = BMI160_AUX_ODR_100HZ;
    rslt = bmi160_set_aux_auto_mode(&bmm150_data_start, &bmi);

     

     

    From the forum thread that you pointed in your comment:

     

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

     

     

    One thing that I am curious about is this bit:

    // correct INT channel for Tap. Bug in library
    // disable int1_s_tap

     

    Can you explain the bug you found in our sensor API ?

    o_o

    Established Member

    Re: BMX160 Magnetometer data not changing

    Hi o_o

    I added your suggeted code after the datasheet's raw implementation:

    uint8_t bmm150_data_start = BMM150_DATA_X_LSB;
    bmi.aux_cfg.aux_odr = BMI160_AUX_ODR_100HZ;
    rslt = bmi160_set_aux_auto_mode(&bmm150_data_start, &bmi);

    The result was that now the AUX data values reads as 0 on all axes. (previously they had a value). Also, the drdy_mag flag was nog being set.
    So it seems to be getting "worse".

    I understand that you prefer only to support the API. I reverted to the BMX160 datasheet as the API implementation was not producing favourable results.
    So I am happy to switch back to the API implementation.

    After the TAP detection setup, I have changed the raw hex writing implementation with the following (see the comment about the thread reference to pick up where the code changes)

      // --------------- 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.preset_mode = BMM150_PRESETMODE_REGULAR;
      rslt_ = bmm150_set_presetmode(&bmm);
      printf("bmm150_set_presetmode:%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_);
    
      bmi.aux_cfg.aux_odr = BMI160_AUX_ODR_50HZ; // 7; /* Represents polling rate in 50 Hz*/
      rslt_ = bmi160_config_aux_mode(&bmi);
      printf("bmi160_config_aux_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_);
    
      /* Reading data from BMI160 data registers */
      rslt_ = bmi160_read_aux_data_auto_mode(mag_data, &bmi);
      printf("bmi160_read_aux_data_auto_mode:%i\r\n", rslt_);

     The result is the same as before.
    No drdy_mag flag being set.
    Data reads as 0 on all axes.

    I seem to be working backwards 😮

    Any thoughts on why I'm getting no data now?
    I am under the impression that I am missing something fundamental.
    Am I initialising the sensor in the correct order?
    I tried to init the DRDY and TAP settings after the MAG init, but no change? Does this order matter?

     

    I don't want to cloudy the waters with other issues, so I have created this separate issue regarding the possible bug in the API.
    https://community.bosch-sensortec.com/t5/MEMS-sensors-forum/Possible-bug-in-BMX160-API-for-TAP-setti...

    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