Bosch Sensortec Community

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

    BNO055 unreliable calibration & heading readings

    BNO055 unreliable calibration & heading readings

    Digisolve
    Established Member

    BNO055 unreliable calibration & heading readings

    I'm having difficulty with reliable heading in DNOF mode.  I find it can drifts as much as +/- 20 degrees.

    There are many questions I have regarding this. But, as they are all related, I will put them all here in a number list:

    1. Power cycling calibration status

    I find power cycling effects the accuracy / reliability of the calibration status.

    • I calibrate the unit so all 4 calibration status (ACC GYRO MAG SYS) read 3, then save the OFFSET & RADIUS regs to NV storage.
    • I then power-down the compass (remove the power)
    • I then power-up the compass & restore the OFFSET & RADIUS registers.
    • I then check the calibration status & it is no longer calibrated. In some instances NONE of the 4 are 3

    2. Power cycling heading reading

     I find power cycling effects the accuracy / reliability of the heading reading.

    • I calibrate & save as detailed above.
    • I then power-down the compass (removed the power)
    • I then power-up the compass in different orientations & restore the OFFSET & RADIUS registers
    • I read the heading & it is usually around 0 degrees regardless of the orientation

    Always powered-up

    I have changed my design to try the compass always powered-up while the battery is connected. This makes an improvement in both cases above, but this is not how I want the design.

    I even put the compass into suspend mode on power-down & then back into normal mode at power-up.

    3. When / how often should the calibration data to read / restored?

    If I have to adopt the always powered-up approach, then the compass will be powered for long periods of time. How often should I read the OFFSET & RADIUS registers into NV storage?

    4. Heading drift

    I find that the heading drifts. IF I orient the compass in one direction, not change any compass settings, but just turn thru 360 degrees, or move the compass in some random way, the heading can be up to 30 degrees wrong.

    5. Absolute heading

    I find that the compass does not point north to match my magnetic compass, of my iPhone compass. (NB my magnetic compass & iPhone compass match each other photos attached)

    This is was a fully calibrated BNO055 with all 4 CALIB STAT read 3’s

    26 REPLIES 26

    BSTRobin
    Community Moderator
    Community Moderator

    Hi Digisolve,

    If current sensor status is suspend mode or power-down, and you want to reuse the sensor, it is recommended that you do soft reset for sensor and wait for tens of milliseconds before configuring the sensor.
    Test it and see if it has improvement.

    Digisolve
    Established Member

    Please can you be more specific as I find if I reset & configure the device from power moved, restore the cal data (OFFSET & RADIUS regs) then the CAL STATUS usually starts back at 0x00 & the heading readings are completely wrong showing 0 degrees regardness of the direction it's pointing

    If I run my BNO055_sleep(TRUE) instead of removing power from the BNO055  & then run BNO055_sleep(FALSE) I get much better results. However, Ideally I want to remove the power completely when not in use to maximise the battery life.

    When the battery is insterted I run BNO055_init() & BNO055_sleep(TRUE). This puts the unit in an off state, but still with the BNO055 powered-up

    When the user turns the unit on I run BNO055_sleep(FALSE) & start to use the unit.

    However, I find from a battery instartion, I need to always calibrate as the CAL STATUS is usually 0x00 (then soon changes to 0x30 as the GYRO cals quite quickly) but never 0xFF

    Once calibrated I can place in suspend power mode then back to normal power mode & the cal status & heading readings restore too.

    This is a very slow process for tech support, so a comprehensive responce would be greatly appreciated

    Here is my code (sorry but pasting it in lost the tabulation):

    void bno055_init(void)
    {
    Delay(TICK_100MS);

    COMPASS_RESET = 0;
    Delay(TICK_10MS);
    COMPASS_RESET = 1;

    Delay(7*TICK_100MS); // wait compass POR

    /* switch back to page 0 */
    BNO055_I2C_Write(BNO055_PAGE_ID_ADDR, PAGE0);

    // Delay(TICK_10MS);

    /* read chip IDs (for debug only)*/
    BNO055_I2C_Read(BNO055_CHIP_ID_ADDR);
    BNO055_I2C_Read(BNO055_ACCEL_REV_ID_ADDR);
    BNO055_I2C_Read(BNO055_MAG_REV_ID_ADDR);
    BNO055_I2C_Read(BNO055_GYRO_REV_ID_ADDR);
    BNO055_I2C_Read(BNO055_SW_REV_ID_LSB_ADDR);
    BNO055_I2C_Read(BNO055_SW_REV_ID_MSB_ADDR);
    BNO055_I2C_Read(BNO055_BL_REV_ID_ADDR);

    /* Wait till restart */
    while(BNO055_I2C_Read(BNO055_SELFTEST_RESULT_ADDR) != 0x0F )
    {
    Delay(TICK_10MS);
    }

    /* Set to config mode */
    BNO055_I2C_Write(BNO055_OPR_MODE_ADDR, BNO055_OPERATION_MODE_CONFIG);

    /* Set to normal power mode */
    BNO055_I2C_Write(BNO055_PWR_MODE_ADDR, BNO055_POWER_MODE_NORMAL);

    /* Set the output units */
    BNO055_I2C_Write(BNO055_UNIT_SEL_ADDR, 0x00);

    // use external clock //
    BNO055_I2C_Write(BNO055_SYS_TRIGGER_ADDR, 0x80);
    Delay(TICK_10MS);

    while(BNO055_I2C_Read(BNO055_SYS_CLK_STAT_ADDR) & 1)
    {
    Delay(TICK_10MS);
    }

    if((BNO055_I2C_Read(BNO055_SYS_TRIGGER_ADDR) & 0x80) == 0)
    while(1); // !!! EXTERNAL CLOCK SELECTION FAILED

    /* Set the axis map */
    BNO055_I2C_Write(BNO055_AXIS_MAP_CONFIG_ADDR, xyz_table[XYZ_MODE].map);
    BNO055_I2C_Write(BNO055_AXIS_MAP_SIGN_ADDR, xyz_table[XYZ_MODE].sign);

    // Load calibration Profile //
    if(inhibit_profile == TRUE)
    {
    inhibit_profile = FALSE;
    }
    else
    {
    BNO055_Load_Calibration_Profile();
    }

    /* Set the requested operating mode (see section 3.3) */
    BNO055_I2C_Write(BNO055_OPR_MODE_ADDR, OPERATION_MODE);
    Delay(TICK_10MS);
    }

    void BNO055_sleep(BOOL sleep_flg)
    {
    if(sleep_flg)
    {
    BNO055_I2C_Write(BNO055_OPR_MODE_ADDR, BNO055_OPERATION_MODE_CONFIG);
    Delay(3*TICK_10MS);
    BNO055_I2C_Write(BNO055_PWR_MODE_ADDR, BNO055_POWER_MODE_SUSPEND);
    }
    else
    {
    BNO055_I2C_Write(BNO055_PWR_MODE_ADDR, BNO055_POWER_MODE_NORMAL);
    BNO055_I2C_Write(BNO055_OPR_MODE_ADDR, OPERATION_MODE);
    Delay(TICK_10MS);
    }
    Delay(TICK_10MS);
    }



    void BNO055_Load_Calibration_Profile(void)
    {
    S16 profile_data[sizeof(NvBuff.CompassProfile)/sizeof(NvBuff.CompassProfile[0])];
    U8 flash_loop ;

    for(flash_loop = 0; flash_loop < sizeof(profile_data)/sizeof(profile_data[0]); flash_loop++)
    {
    profile_data[flash_loop] = NvBuff.CompassProfile[flash_loop];
    }

    BNO055_I2C_Write(BNO055_OPR_MODE_ADDR, BNO055_OPERATION_MODE_CONFIG);
    Delay(3*TICK_10MS);

    BNO055_I2C_WriteArray(BNO055_CAL_DATA_START, (U8*)profile_data, sizeof(profile_data));

    BNO055_I2C_Write(BNO055_OPR_MODE_ADDR, OPERATION_MODE);
    Delay(TICK_10MS);
    }

     

    Digisolve
    Established Member

    Please can I get some feedback. My client is chasing me daily. Thank you

    BSTRobin
    Community Moderator
    Community Moderator

    Hi Digisolve,

    For your question 1 & 2: you cann't power off the mag when you use the NDOF mode. If you do that, the algorithm output should be wrong.

    For your question 3: the mag calibration is always on, and it is keeping calibrating, and the value keep changes. So there is no fixed period for mag offset and radius update.

    For your question 4 & 5: recommend you to do SIC first and then check the heading value.

    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