Bosch Sensortec Community

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

    BMX160 Magnetometer data not changing

    BMX160 Magnetometer data not changing

    rdehart
    Established Member

    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

    22 REPLIES 22

    o_o
    Contributor

    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

    rdehart
    Established Member

    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

    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

    rdehart
    Established Member

    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