Bosch Sensortec Community

    cancel
    Showing results for 
    Search instead for 
    Did you mean: 

    BHI260AP Calibration Problem

    BHI260AP Calibration Problem

    Erion
    New Poster

    Hello, I have a problem to calibrate BHI260AP.

    I got the calibration profile with uint8_t array from bhy2_get_calibration_profile.

     

    I tried to adapt the calibration to the sensor before getting data, but it looks that it doesn't work.

    The reason that I say like it is,

     

    The arrays from bhy2_get_calibration_profile "before bhy2_set_calibration_profile" and "after bhy2_set_calibration_profile" is same.

    And the adapted calib_profile and the array "after bhy2_set_calibration_profile" is different. I thought that those two must be same before getting data.

     

    I leave the code under the question. calib_acc is calib profile to adapt, readed_acc is sensor's profile after adapted.

    I modified the example quartonian.c

    How can I solve this problem?

    Best regard,

     

    setup_interfaces(true, intf); /* Perform a power on reset */
    printf("INITIALIZE BHY\n");

    #ifdef BHY2_USE_I2C
    rslt = bhy2_init(BHY2_I2C_INTERFACE, bhy2_i2c_read, bhy2_i2c_write, bhy2_delay_us, BHY2_RD_WR_LEN, NULL, &bhy2);
    #else
    rslt = bhy2_init(BHY2_SPI_INTERFACE, bhy2_spi_read, bhy2_spi_write, bhy2_delay_us, BHY2_RD_WR_LEN, NULL, &bhy2);
    #endif
    printf("INITIALIZE BHY ERR %d\n",rslt);
    print_api_error(rslt, &bhy2);

    rslt = bhy2_soft_reset(&bhy2);
    print_api_error(rslt, &bhy2);
    printf("bhy2_soft_reset %d\n", rslt);

    rslt = bhy2_get_product_id(&product_id, &bhy2);
    print_api_error(rslt, &bhy2);
    printf("bhy2_get_product_id %d\n", rslt);


    /* Check for a valid product ID */
    if (product_id != BHY2_PRODUCT_ID)
    {
    printf("Product ID read %X. Expected %X\r\n", product_id, BHY2_PRODUCT_ID);
    }
    else
    {
    printf("BHI260/BHA260 found. Product ID read %X\r\n", product_id);
    }

     


    /* Check the interrupt pin and FIFO configurations. Disable status and debug */
    hintr_ctrl = BHY2_ICTL_DISABLE_DEBUG;

    hintr_ctrl = 0;

    rslt = bhy2_set_host_interrupt_ctrl(hintr_ctrl, &bhy2);
    print_api_error(rslt, &bhy2);
    rslt = bhy2_get_host_interrupt_ctrl(&hintr_ctrl, &bhy2);
    print_api_error(rslt, &bhy2);

    printf("Host interrupt control\r\n");
    printf(" Wake up FIFO %s.\r\n", (hintr_ctrl & BHY2_ICTL_DISABLE_FIFO_W) ? "disabled" : "enabled");
    printf(" Non wake up FIFO %s.\r\n", (hintr_ctrl & BHY2_ICTL_DISABLE_FIFO_NW) ? "disabled" : "enabled");
    printf(" Status FIFO %s.\r\n", (hintr_ctrl & BHY2_ICTL_DISABLE_STATUS_FIFO) ? "disabled" : "enabled");
    printf(" Debugging %s.\r\n", (hintr_ctrl & BHY2_ICTL_DISABLE_DEBUG) ? "disabled" : "enabled");
    printf(" Fault %s.\r\n", (hintr_ctrl & BHY2_ICTL_DISABLE_FAULT) ? "disabled" : "enabled");
    printf(" Interrupt is %s.\r\n", (hintr_ctrl & BHY2_ICTL_ACTIVE_LOW) ? "active low" : "active high");
    printf(" Interrupt is %s triggered.\r\n", (hintr_ctrl & BHY2_ICTL_EDGE) ? "pulse" : "level");
    printf(" Interrupt pin drive is %s.\r\n", (hintr_ctrl & BHY2_ICTL_OPEN_DRAIN) ? "open drain" : "push-pull");

    /* Configure the host interface */
    hif_ctrl = 0;
    rslt = bhy2_set_host_intf_ctrl(hif_ctrl, &bhy2);
    print_api_error(rslt, &bhy2);

    /* Check if the sensor is ready to load firmware */
    rslt = bhy2_get_boot_status(&boot_status, &bhy2);
    print_api_error(rslt, &bhy2);

    if (boot_status & BHY2_BST_HOST_INTERFACE_READY)
    {
    upload_firmware(boot_status, &bhy2);

    rslt = bhy2_get_kernel_version(&version, &bhy2);
    print_api_error(rslt, &bhy2);
    if ((rslt == BHY2_OK) && (version != 0))
    {
    printf("Boot successful. Kernel version %u.\r\n", version);
    }


    rslt = bhy2_register_fifo_parse_callback(BHY2_SYS_ID_META_EVENT, parse_meta_event, NULL, &bhy2);
    print_api_error(rslt, &bhy2);
    rslt = bhy2_register_fifo_parse_callback(BHY2_SYS_ID_META_EVENT_WU, parse_meta_event, NULL, &bhy2);
    print_api_error(rslt, &bhy2);
    rslt = bhy2_register_fifo_parse_callback(QUAT_SENSOR_ID, parse_quaternion, NULL, &bhy2);
    print_api_error(rslt, &bhy2);

    rslt = bhy2_get_and_process_fifo(work_buffer, WORK_BUFFER_SIZE, &bhy2);
    print_api_error(rslt, &bhy2);
    }
    else
    {
    printf("Host interface not ready. Exiting\r\n");

    close_interfaces(intf);

    return 0;
    }

    char* file_acc = "/home/unistrrel/COINES/v2.7.0/examples/bhy2/examples/euler_cal/calib_acc_f.txt";
    char* file_gyro = "/home/unistrrel/COINES/v2.7.0/examples/bhy2/examples/euler_cal/calib_gyro_f.txt";
    char* file_mag = "/home/unistrrel/COINES/v2.7.0/examples/bhy2/examples/euler_cal/calib_mag_f.txt";
    char* file_sic = "/home/unistrrel/COINES/v2.7.0/examples/bhy2/examples/euler_cal/sic_mat_f.txt";

    FILE* f_acc;
    FILE* f_gyro;
    FILE* f_mag;
    FILE* f_sic;
    f_acc = fopen(file_acc, "r");
    f_gyro = fopen(file_gyro, "r");
    f_mag = fopen(file_mag, "r");
    f_sic = fopen(file_sic, "r");
    char read_acc[300];
    char read_gyro[1000];
    char read_mag[2000];
    char read_sic[300];
    fgets(read_acc, 300, f_acc);
    fgets(read_gyro, 1000, f_gyro);
    fgets(read_mag, 2000, f_mag);
    fgets(read_sic, 300, f_sic);

    fclose(f_acc);
    fclose(f_gyro);
    fclose(f_mag);
    fclose(f_sic);

    char* mat_acc = strtok(read_acc, " ");
    for (int i = 0; i < 72; i++) {
    calib_acc[i] = atoi(mat_acc);
    mat_acc = strtok(NULL, " ");
    }
    char* mat_gyro = strtok(read_gyro, " ");
    for (int i = 0; i < 200; i++) {
    calib_gyro[i] = atoi(mat_gyro);
    mat_gyro = strtok(NULL, " ");
    }
    char* mat_mag = strtok(read_mag, " ");
    for (int i = 0; i < 408; i++) {
    calib_mag[i] = atoi(mat_mag);
    mat_mag = strtok(NULL, " ");
    }
    char* mat_sic = strtok(read_sic, " ");
    for (int i = 0; i < 72; i++) {
    calib_sic[i] = atoi(mat_sic);
    mat_sic = strtok(NULL, " ");
    }


    rslt = bhy2_set_calibration_profile(BHY2_PHYS_SENSOR_ID_ACCELEROMETER, calib_acc, 72, &bhy2);
    print_api_error(rslt, &bhy2);
    rslt = bhy2_set_calibration_profile(BHY2_PHYS_SENSOR_ID_GYROSCOPE, calib_gyro, 200, &bhy2);
    print_api_error(rslt, &bhy2);
    rslt = bhy2_set_calibration_profile(BHY2_PHYS_SENSOR_ID_MAGNETOMETER, calib_mag, 408, &bhy2);
    print_api_error(rslt, &bhy2);
    rslt = bhy2_set_sic_matrix(calib_sic, 72, &bhy2);
    print_api_error(rslt, &bhy2);

     


    /* Update the callback table to enable parsing of sensor data */
    rslt = bhy2_update_virtual_sensor_list(&bhy2);
    print_api_error(rslt, &bhy2);

    float sample_rate = 100.0; /* Read out data measured at 100Hz */
    uint32_t report_latency_ms = 0; /* Report immediately */
    rslt = bhy2_set_virt_sensor_cfg(QUAT_SENSOR_ID, sample_rate, report_latency_ms, &bhy2);
    print_api_error(rslt, &bhy2);


    uint8_t init_readed_acc[72];
    uint32_t act_len = 200;
    uint8_t readed_acc[72];

    rslt = bhy2_get_calibration_profile(BHY2_PHYS_SENSOR_ID_ACCELEROMETER, init_readed_acc, 72, &act_len, &bhy2);
    rslt = bhy2_get_calibration_profile(BHY2_PHYS_SENSOR_ID_ACCELEROMETER, readed_acc, 72, &act_len, &bhy2);
    print_api_error(rslt, &bhy2);

    for (int i = 0; i < 72; i++)
    {
    printf("[%d]: %d %d\n", i, calib_acc[i], readed_acc[i]);

    }

     

    1 REPLY 1

    BSTRobin
    Community Moderator
    Community Moderator

    Hi Erion,

    In callback function, you can call bhy2_get_calibration_profile() function to save calibration profile until accuracy reach to 3.
    After next power on, you can call bhy2_set_calibration_profile() function to set previous saved calibration profile to BHI260.
    I uploaed a example on STM32 for your reference. I hope it will be helpful for you.

    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