Bosch Sensortec Community

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

    Issue when compare 2 bmi160 data

    Issue when compare 2 bmi160 data

    TTN
    New Poster

    Hi,

    We want to compare 2 bmi160 data to identify some motion feature.

    each custom board have the a bmi160 sensor the data readout by spi ,which print by uart.

    the firmware part we set both sensor in same config as below

     

    static void Spi_sensor_Sensor_init( void ) {
    
        /* You may assign a chip select identifier to be handled later */
        s_spi_bmi160_sensor.id = 0 ;
        s_spi_bmi160_sensor.interface = BMI160_SPI_INTF ;
        s_spi_bmi160_sensor.read = Spi_read_transfer ;              //Spi_read_transfer or spi_read
        s_spi_bmi160_sensor.write = Spi_write_transfer ;    //Spi_write_transfer or spi_write
        s_spi_bmi160_sensor.delay_ms = Spi_delay_ms ;
    		
        int8_t rslt = BMI160_OK ;
        rslt = bmi160_init( &s_spi_bmi160_sensor ) ;
    	
        if ( rslt == 0 ) {
                SEGGER_RTT_printf( 0,"bmi160 init success ! \n", rslt ) ; 	
              } // if
        else 
                SEGGER_RTT_printf( 0,"Error : bmi160 init fail ! \n", rslt ) ; 
    
        /* After the above function call, accel_cfg and gyro_cfg parameters in the device 
        structure are set with default values, found in the datasheet of the sensor */
    
        rslt = BMI160_OK ;
    
        /* Select the Output data rate, range of accelerometer sensor */
        s_spi_bmi160_sensor.accel_cfg.odr = BMI160_ACCEL_ODR_200HZ ;
        s_spi_bmi160_sensor.accel_cfg.range = BMI160_ACCEL_RANGE_2G ;
        s_spi_bmi160_sensor.accel_cfg.bw = BMI160_ACCEL_BW_OSR4_AVG1 ;
        
        /* Select the power mode of accelerometer sensor */
        s_spi_bmi160_sensor.accel_cfg.power = BMI160_ACCEL_NORMAL_MODE ;
    
        /* Select the Output data rate, range of Gyroscope sensor */
        s_spi_bmi160_sensor.gyro_cfg.odr = BMI160_GYRO_ODR_200HZ ;
        s_spi_bmi160_sensor.gyro_cfg.range = BMI160_GYRO_RANGE_2000_DPS ;
        s_spi_bmi160_sensor.gyro_cfg.bw = BMI160_GYRO_BW_NORMAL_MODE ;
    
        /* Select the power mode of Gyroscope sensor */
        s_spi_bmi160_sensor.gyro_cfg.power = BMI160_GYRO_NORMAL_MODE ;
    
        /* Set the sensor configuration */
        rslt = bmi160_set_sens_conf( &s_spi_bmi160_sensor ) ;
    
        /* Select the power mode */
        s_spi_bmi160_sensor.accel_cfg.power = BMI160_ACCEL_NORMAL_MODE ;
        s_spi_bmi160_sensor.gyro_cfg.power = BMI160_GYRO_NORMAL_MODE ;  
    
        /*  Set the Power mode  */
        rslt = bmi160_set_power_mode( &s_spi_bmi160_sensor ) ;
        nrf_delay_ms( 10 ) ; // delay_10ms
        
        /*  Set the calibration value  */	
        /*
        rslt = start_foc(&s_spi_bmi160_sensor);								
        SEGGER_RTT_printf(0,"foc rslt=%d",rslt);
        */
        struct bmi160_offsets sensor_offset;
        rslt = bmi160_get_offsets(&sensor_offset,&s_spi_bmi160_sensor);	
        SEGGER_RTT_printf(0,"calibration value: ax=%d,ay=%d,az=%d,gx=%d,gy=%d,gz=%d\n",sensor_offset.off_acc_x,sensor_offset.off_acc_y,sensor_offset.off_acc_z,sensor_offset.off_gyro_x,sensor_offset.off_gyro_y,sensor_offset.off_gyro_z);
    
    } // Spi_sensor_Sensor_init()
    
    
    static void Spi_get_data( void ) {
        // get bmi160 raw data
        //define counter
        uint32_t begin = 0;
        uint32_t end = 0;
        //begin = app_timer_cnt_get();
        struct bmi160_sensor_data accel ;
        struct bmi160_sensor_data gyro ;          
    
        int8_t rslt = BMI160_OK ;
        spi_xfer_done = false ;
        rslt = bmi160_get_sensor_data( ( BMI160_ACCEL_SEL | BMI160_GYRO_SEL | BMI160_TIME_SEL), &accel, &gyro, &s_spi_bmi160_sensor ) ; 
          if ( rslt != 0 )
                  SEGGER_RTT_printf(0, "ERROR : get bmi160 data fail !" ) ; 
        nrf_delay_ms( 5 ) ; // delay_5ms
    
        s_spi_ori_data[ 0 ] = accel.x ;
        s_spi_ori_data[ 1 ] = accel.y ;
        s_spi_ori_data[ 2 ] = accel.z ;
        s_spi_ori_data[ 3 ] = gyro.x ;
        s_spi_ori_data[ 4 ] = gyro.y ;
        s_spi_ori_data[ 5 ] = gyro.z ;
    
       SEGGER_RTT_printf(0,"ax = %d, ay = %d, az = %d,gx = %d, gy = %d, gz = %d\n", accel.x, accel.y, accel.z, gyro.x, gyro.y, gyro.z) ;
       SEGGER_RTT_printf(0,"ACC and Gyro SensorTime= %u \n",accel.sensortime);
    
    } // Spi_get_data()
    
    int main(void){   
    	
            //Spi_init();
            Spi_pin_init();
            Spi_sensor_Sensor_init();
    
            while(1)
            {
                Spi_get_data();
            }
    }

     

    We fix the 2 board on the same place and move in the same way to record the data.

    TTN_0-1634103766907.png

    the pic above  x (index)/y (gyro.z), we can see the raw data difference grows over time.

    TTN_1-1634105118608.png

    when we align two sensortime(ms) in the same point, we find  the sensortime difference also grows over time.

    how can we config our system to make sure to avoid this issue?

    Any suggestion?

    the raw data is in the appendix. 

    7 REPLIES 7

    BSTRobin
    Community Moderator
    Community Moderator

    Hello ilo,

    You could see the previous table ODR had +/-1% accuracy. If the ODR is 50 Hz, the data is not updated accurately for 20 ms each time.

    Thank you Robin.

    I had a follow up question. Currently we are using BMI 160 sample index and samplying frequency to get time stamps of certain motion events that we detect. For eg, if the event happens at 300th sample and sampling frequency is 50hz, it happened after 6seconds from a reference point.

    Judging from your previous reply, can I assume that this method is not going to give an accurate answer and the error is going to accumulate as time progresses? 

    Also, is there any other method to locate the time stamp of an event except the CPU time?

    BSTRobin
    Community Moderator
    Community Moderator

    Hello ilo,

    Yes, the error is going to accumulate as time progresses.

    It could be corrected periodically by referring to the local time. For example, after a few seconds, compare the local time with the accumulated time.

    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