Bosch Sensortec Community

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

    BMX160 BSX Lite library integration problem

    BMX160 BSX Lite library integration problem

    mnjirjak
    Established Member

    Hello,

    I am working with BMX160 shuttleboard. Some time ago I got all three sensor to retrieve data using Bosch Sensortec drivers (BMI160 + BMM150). Here's a sample data:

    ACC X: -16140, Y: 27, Z: -551
    GYRO X: 7, Y: 3, Z: -5
    MAG X : 37 Y : -12 Z : 6

    After that, my goal was to integrate Bosch BSX Lite library into my project. I have downloaded the package, read the documentation, included header files and also included static library libalgobsx.a. First I initialized the library:

     

     

    BSX_U8 bsxLibConfAcc[] = {37,0,3,1,0,9,12,150,0,16,60,0,1,0,1,0,176,4,82,3,0,0,64,65,1,1,1,1,2,2,2,3,3,1,1,180,115};
    BSX_U8 bsxLibConfMag[] = {39,0,2,1,20,5,20,5,196,9,6,9,112,23,0,0,128,61,205,204,76,63,0,0,224,64,1,1,1,1,1,1,1,1,1,1,1,134,84};
    BSX_U8 bsxLibConfGyro[] = {14,0,1,1,3,9,12,136,19,16,1,1,129,46};
    BSX_U8 bsxLibConf[] = {116,6,1,1,...,114,8,0,13,226,109};// <- this one is really long so I skipped a few numbers here
    
    initParam_t s_input;
    
    s_input.accelspec = (BSX_U8 *)&bsxLibConfAcc;
    s_input.magspec = (BSX_U8 *)&bsxLibConfMag;
    s_input.gyrospec = (BSX_U8 *)&bsxLibConfGyro;
    s_input.usecase = (BSX_U8 *)&bsxLibConf;
    
    bsx_init(&s_input);

     

     

    I checked the return value and it turns out the library successfully intializes.

    After that I put it in working mode:

     

     

    ts_workingModes s_workingmodes;
    ts_HWsensorSwitchList HWsensorSwitchList;
    
    s_workingmodes.opMode = BSX_WORKINGMODE_NDOF_GEORV_FMC_OFF;
    bsx_set_workingmode(&s_workingmodes);
    bsx_get_hwdependency(s_workingmodes, &HWsensorSwitchList);

     

     

    and fed raw data:

     

     

    libraryInput_ts.acc.data.x = accel_data.x;
    libraryInput_ts.acc.data.y = accel_data.y;
    libraryInput_ts.acc.data.z = accel_data.z;
    libraryInput_ts.acc.time_stamp = accel_data.sensortime*39; // <- timestamp resolution on BMX160 is 39us, hence multiplying by 39
    
    libraryInput_ts.gyro.data.x = gyro_data.x;
    libraryInput_ts.gyro.data.y = gyro_data.y;
    libraryInput_ts.gyro.data.z = gyro_data.z;
    libraryInput_ts.gyro.time_stamp = accel_data.sensortime*39;
    
    libraryInput_ts.mag.data.x = bmm.data.x;
    libraryInput_ts.mag.data.y = bmm.data.y;
    libraryInput_ts.mag.data.z = bmm.data.z;
    libraryInput_ts.mag.time_stamp = accel_data.sensortime*39;
    
    bsx_dostep(&libraryInput_ts);

     

     

    All timestamps were the same just to conduct the test.

    Later, I tried fetching accelerometer data from the library:

     

     

    ts_dataxyzf32 accRawData;
    bsx_get_accrawdata(&accRawData);
    
    printf("ACC X: %d, Y: %d, Z: %d\n", accRawData.x, accRawData.y, accRawData.z);

     

     

    and ended up with this:

    ACC X: 1072424997, Y: -1073741824, Z: 1077961752
    ACC X: 1072467675, Y: 1073741824, Z: 1077961223
    ACC X: 1072467675, Y: 1073741824, Z: 1077961223
    ACC X: 1072455123, Y: 0, Z: 1077962400
    ACC X: 1072455123, Y: 0, Z: 1077962400
    ACC X: 1072438804, Y: -1610612736, Z: 1077962164

    It's worth noting that I checked all returns values and every single one was OK. Now, the documentation says that bsx_get_accrawdata returns "...raw accelerometer data (x,y and z direction) in m/s^2." Unfortunately I did not get anything even remotly accurate.

    I couldn't get it to work so I downloaded BMF055 example for Atmel Studio and checked the source code. I tried copying the code and adapting it to BMX160. Unfortunately the result was the same.

    The documentation says that library should be fed "...LSB values and time stamps in microseconds." I'm a bit puzzled by the LSB part. Does the driver already return values in the desired form or should I preform some sort of conversion? It's worth mentioning that I have already tried all sorts of conversions, including nibble swap and reversing bit order.

    Another thing is that when I try to fetch raw gyroscope data with bsx_get_gyrorawdata_rps, I end up with pretty much the same numbers as with bsx_get_accrawdata, which I think should not be happening.

    My sensors are configured through the driver as follows:

     

     

    // Initialization
    bmi.id = 0;
    bmi.interface = BMI160_SPI_INTF;
    bmi.read = spi_read_transfer;
    bmi.write = spi_write_transfer;
    bmi.delay_ms = delay;
    
    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;
    
    bmi160_init(&bmi);
      
    bmi.aux_cfg.aux_sensor_enable = BMI160_ENABLE;
    bmi.aux_cfg.aux_i2c_addr = bmm.dev_id;
    bmi.aux_cfg.manual_enable = BMI160_ENABLE;
    bmi160_aux_init(&bmi);
    bmm150_init(&bmm);
    
    // Setup
    //Acc
    bmi.accel_cfg.power = BMI160_ACCEL_NORMAL_MODE;
    bmi.accel_cfg.bw = BMI160_ACCEL_BW_NORMAL_AVG4;
    bmi.accel_cfg.range = BMI160_ACCEL_RANGE_2G;
    bmi.accel_cfg.odr = BMI160_ACCEL_ODR_50HZ;
    
    //Gyro
    bmi.gyro_cfg.odr = BMI160_GYRO_ODR_50HZ;
    bmi.gyro_cfg.range = BMI160_GYRO_RANGE_500_DPS;
    bmi.gyro_cfg.bw = BMI160_GYRO_BW_NORMAL_MODE;
    bmi.gyro_cfg.power = BMI160_GYRO_NORMAL_MODE;
    
    //Mag
    bmm.settings.preset_mode = BMM150_PRESETMODE_REGULAR;
    bmm150_set_presetmode(&bmm);
    bmm.settings.pwr_mode = BMM150_FORCED_MODE;
    bmm150_set_op_mode(&bmm);
    bmi.aux_cfg.aux_odr = 6;
    bmi160_config_aux_mode(&bmi);
    
    uint8_t aux_addr = 0x42;
    bmi160_set_aux_auto_mode(&aux_addr, &bmi);
    bmi160_set_sens_conf(&bmi);

     

     

    but I also tried lots of different configurations regarding range, frequency, etc. Should the output from the library be scaled by some means? Is it possible that I'm getting correct values but just have to process them? Are there any restrictions? Should I convert sensor data to SI units before feeding it to the library or is the data provided by the driver enough?

    All in all, I tried integrating BSX Lite library into my BMX160 project, but ended up with funny output from the library. I have a lot of questions, but for the sake of the argument I'm just going to ask what am I doing wrong and what should I do for the library to work?

     

    Kind regards,

    Marko Njirjak

    10 REPLIES 10

    Hi neerajverma,

    if I'm not mistaken, all the sensors are asleep by default. You first have to initialize them and turn them on before you can fetch data. Maybe this is where the problem lies. This is the configuration that I use:

    a) initialization

     

    bmi.id = 0;
    bmi.interface = BMI160_SPI_INTF;
    bmi.read = spi_read_transfer;
    bmi.write = spi_write_transfer;
    bmi.delay_ms = delay;
    
    bmi160_init(&bmi);

     

     

    b) turning sensors on

     

    //Acc
    bmi.accel_cfg.power = BMI160_ACCEL_NORMAL_MODE;
    bmi.accel_cfg.bw = BMI160_ACCEL_BW_NORMAL_AVG4;
    bmi.accel_cfg.range = BMI160_ACCEL_RANGE_4G;
    bmi.accel_cfg.odr = BMI160_ACCEL_ODR_200HZ;
    
    //Gyro
    bmi.gyro_cfg.odr = BMI160_GYRO_ODR_200HZ;
    bmi.gyro_cfg.range = BMI160_GYRO_RANGE_1000_DPS;
    bmi.gyro_cfg.bw = BMI160_GYRO_BW_NORMAL_MODE;
    bmi.gyro_cfg.power = BMI160_GYRO_NORMAL_MODE;
    
    bmi160_set_sens_conf(&bmi);

     

     

    c) fetching data

     

    bmi160_get_sensor_data((BMI160_TIME_SEL | BMI160_ACCEL_SEL | BMI160_GYRO_SEL), &accel_data, &gyro_data, &bmi);

     

     

    To clarify, 'spi_read_transfer', 'spi_write_transfer' and 'delay' are master-chip specific functions for spi transfers and delay. 'bmi' is a structure of type bmi160_dev, 'accel_data' and 'gyro_data' are of type bmi160_sensor_data.

    In my project I also use the magnetometer, but I removed those parts of code to minimize confusion.

    Disclamer: I'm not a Bosch employee, so this is just a guess.

    Kind regards,

    Marko Njirjak

    Hi neerajverma,

     

    If you are having issues getting started with BMX160, I would recommend to start your own thread and provide a link to this one in your description, and why the solution here does not work for you.

     

    Since this thread is marked as "solved" it is confusing to continue the discussion of more issues here.

    Ok, sure. let me start new thread.

    Lashca_Pieterse
    New Poster

    Good day, 

    I am using the bmi160 and bmm150...I have used this post as a reference to develop my bsxLite fusion .

    I was hoping someone could shed some light on feeding the fusion library.  When using the struct "libraryinput_t" to feed the library, do i set the relevant variable i create to my sensor struct "bmi160_sensordata"? I have attached a screenshot of my code.

     

    Hi Lashca_Pieterse,

    BSX fusion library is a standalone piece of software that accepts accelerometer, gyroscope and magnetometer measurements on one end and gives filtered data on the other end. With that in mind, you first need to fetch the data, preferably through Bosch drivers and than feed it to the library. The library accepts LSB format, which means that the data you fetch through Bosch drivers is pretty much tailored to your needs.

    Your code looks fine, the only thing that is missing is the data fetch before feeding it to the library. Here's an example for fetching accelerometer and gyroscope data:

     

    bmi160_get_sensor_data((BMI160_TIME_SEL | BMI160_ACCEL_SEL | BMI160_GYRO_SEL), &accel_data, &gyro_data, &bmi);

     

    P.S. You're missing magnetometer timestamp. For now, you can set is a gyroscope or accelerometer timestamp.

    Kind regards,

    Marko Njirjak

    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