06-19-2019 11:36 PM - edited 06-20-2019 01:03 AM
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
Solved! Go to Solution.
06-21-2019 12:28 PM
Hi Marko,
That is a very long post, with hopefully a very simple answer
ts_dataxyzf32 accRawData;
bsx_get_accrawdata(&accRawData);
printf("ACC X: %d, Y: %d, Z: %d\n", accRawData.x, accRawData.y, accRawData.z);
The structure contains floats, but your printf %d expects integers. Most compilers would issue a warning. try using %f instead.
With the correct data type for your printf function, I expect it will be much easier to debug 😀
06-21-2019 02:21 PM
Hi o_o,
this is brilliant, I totally overlooked the data type. This solved everything, thank you very much! 🙂
Just to add one more thing for anyone else who might end up here. At first I modified printf function to look like you said, but it didn't print anything. Turns out you have to enable floating point numbers in printf for this to work (I'm using Segger Embedded Studio, but it probably needs to be done in all sorts of IDEs).
Once again, thank you very much!
Kind regards,
Marko Njirjak
06-21-2019 02:25 PM
09-13-2019 01:38 AM
Hi Guys,
Need your help to proceed further on this...
I am new to BMX160 sensor.. I have downloaded driver from https://github.com/BoschSensortec/BMI160_driver and using SPI (10 MhZ clock) interface.
I only modified CHIP ID to 0xD8 and hucked my SPI read/write functions.
I see bmi160_init(), bmi160_set_sens_conf() are success but I call bmi160_get_sensor_data() I get all zeros for both ACCEL and Gyro.
I have Bosch BMX160 Shuttle Board (28 pins), I have connected 4 SPI and 2 Vdd, Vddio and one GND pin.
I am able to read/write registers even using driver APIs as well.
Could you please help me to identifiy what could be missing/wrong?