01-19-2022 01:18 PM
Hi,
I have a project where I'm trying to use 2 different BMX160 sensors to get the relative movement of one device to the other.
I have managed to get sensors readings from BSXLite to each sensor (ID 0x68, and 0x69) seperately, meaning the sensore data flow is working well, but when trying to get 2 sensors output seprately from BSXLite library, I get error = -5 for the second sensor.
I am using 2 different instances for BSXLite library, so I assume each call to bsxlite_do_step function should be done on different BSXLite object.
I didnt see information regarding if it is possible to run BSXLite library on 2 different sensors in parallel so maybe it is not possible,
Have anyone tried this before?
see code below:
static int8_t FingerImu_Init(struct bmi160_dev *pBmi, bsxlite_instance_t *p_instance)
{
/* Initialize your host interface to the BMI160 */
int8_t rslt;
//struct bmm150_settings bmm_settings;
rslt = bmi160_init(pBmi);
/* Check rslt for any error codes */
/* Configure the BMI160's auxiliary interface for the BMM150 */
pBmi->aux_cfg.aux_sensor_enable = BMI160_ENABLE;
//pBmi->aux_cfg.aux_i2c_addr = bmm.chip_id;
pBmi->aux_cfg.aux_i2c_addr = BMM150_DEFAULT_I2C_ADDRESS;
pBmi->aux_cfg.manual_enable = BMI160_ENABLE; /* Manual mode */
pBmi->aux_cfg.aux_rd_burst_len = BMI160_AUX_READ_LEN_3; /* 8 bytes */
rslt |= bmi160_aux_init(pBmi);
/* Check rslt for any error codes */
//rslt |= bmm150_init(&bmm);
/* Check rslt for any error codes */
/* Configure the accelerometer */
pBmi->accel_cfg.odr = BMI160_ACCEL_ODR_100HZ;
pBmi->accel_cfg.range = BMI160_ACCEL_RANGE_2G;
pBmi->accel_cfg.bw = BMI160_ACCEL_BW_NORMAL_AVG4;
pBmi->accel_cfg.power = BMI160_ACCEL_NORMAL_MODE;
/* Configure the gyroscope */
pBmi->gyro_cfg.odr = BMI160_GYRO_ODR_100HZ;
pBmi->gyro_cfg.range = BMI160_GYRO_RANGE_2000_DPS;
pBmi->gyro_cfg.bw = BMI160_GYRO_BW_NORMAL_MODE;
pBmi->gyro_cfg.power = BMI160_GYRO_NORMAL_MODE;
rslt |= bmi160_set_sens_conf(pBmi);
/* Check rslt for any error codes */
//rslt = bmi160_aux_init(&bmi);
/* Check rslt for any error codes */
// rslt |= BMX160_SetMagConfig();
// gyroRange = setGyroRange(pBmi->gyro_cfg.range);
// accRange = setAccelRange(pBmi->accel_cfg.range);
// rslt = bmm150_init(&bmm);
/* Check rslt for any error codes */
struct bmi160_foc_conf foc_conf = {
.foc_gyr_en = BMI160_ENABLE,
.foc_acc_x = BMI160_FOC_ACCEL_0G,
.foc_acc_y = BMI160_FOC_ACCEL_0G,
.foc_acc_z = BMI160_FOC_ACCEL_POSITIVE_G,
.acc_off_en = BMI160_ENABLE,
.gyro_off_en = BMI160_ENABLE
};
struct bmi160_offsets offset = {0};
rslt |= bmi160_start_foc(&foc_conf, &offset, pBmi);
if(rslt == BMI160_OK)
{
rslt |= bmi160_set_offsets(&foc_conf, &offset, pBmi);
}
/* Configure the magnetometer. The regular preset supports up to 100Hz in Forced mode */
//bmm_settings.preset_mode = BMM150_PRESETMODE_REGULAR;
//rslt |= bmm150_set_presetmode(&bmm_settings, &bmm);
/* It is important that the last write to the BMM150 sets the forced mode.
* This is because the BMI160 writes the last value to the auxiliary sensor
* after every read */
//bmm_settings.pwr_mode = BMM150_POWERMODE_FORCED;
//rslt |= bmm150_set_op_mode(&bmm_settings, &bmm);
uint8_t bmm150_data_start = BMM150_REG_DATA_X_LSB;
pBmi->aux_cfg.aux_odr = BMI160_AUX_ODR_100HZ;
rslt |= bmi160_set_aux_auto_mode(&bmm150_data_start, pBmi);
rslt |= bsxlite_init(p_instance);
return rslt;
}
static int8_t FingerImu_ReadSensorData(struct bmi160_dev *pBmi, bsxlite_instance_t *p_instance,
FingImuAxis_t *pCurAxisSet, int32_t *pSensorTime)
{
int8_t rslt;
float32_t cur_pitch = 0;
float32_t cur_yaw = 0;
bsxlite_out_t bsxlite_fusion_out;
vector_3d_t accel_in, gyro_in;
struct bmi160_sensor_data gyro_data, accel_data;
rslt = bmi160_get_sensor_data(BMI160_ACCEL_SEL | BMI160_GYRO_SEL | BMI160_TIME_SEL,
&accel_data, &gyro_data, pBmi);
if(rslt != BMI160_OK)
{
send_text_msg("FingerImu Error: rslt(%d)\n", rslt);
}
else
{
accel_in.x = (float32_t)accel_data.x*ACC_RES;
accel_in.y = (float32_t)accel_data.y*ACC_RES;
accel_in.z = (float32_t)accel_data.z*ACC_RES;
gyro_in.x = (float32_t)gyro_data.x*GYRO_RES;
gyro_in.y = (float32_t)gyro_data.y*GYRO_RES;
gyro_in.z = (float32_t)gyro_data.z*GYRO_RES;
/** library api call: doStep **/
rslt |= bsxlite_do_step(p_instance,
*pSensorTime,
&accel_in,
&gyro_in,
&bsxlite_fusion_out);
if(rslt == BMI160_OK)
{
cur_pitch = bsxlite_fusion_out.orientation.pitch*180/PI;
cur_yaw = bsxlite_fusion_out.orientation.yaw*180/PI > 180?
-(360 - bsxlite_fusion_out.orientation.yaw*180/PI):
bsxlite_fusion_out.orientation.yaw*180/PI;
pCurAxisSet->Pitch = AVG(cur_pitch, pCurAxisSet->Pitch, 10);
pCurAxisSet->Yaw = AVG(cur_yaw, pCurAxisSet->Yaw, 10);
}
(*pSensorTime) += 10000;
}
return rslt;
}
void FingerImu_Loop(void)
{
FingImuAxis_t CurCIAxisSet = {0};
FingImuAxis_t CurBodyAxisSet = {0};
int32_t ci_sensor_time = 0, body_sensor_time = 0;
bsxlite_instance_t ci_instance = 0x00;
bsxlite_instance_t body_insance = 0x01;
int8_t rslt = FingerImu_Init(&bmi_ci, &ci_instance);
rslt |= FingerImu_Init(&bmi_body, &body_insance);
if(rslt == BMX160_OK)
{
gFingImuHandle.is_init = TRUE;
}
//while(rslt != 0) {
for(;;)
{
/* Wait for 100ms for the FIFO to fill */
osDelay(10);
rslt |= FingerImu_ReadSensorData(&bmi_ci, &ci_instance, &CurCIAxisSet, &ci_sensor_time);
rslt |= FingerImu_ReadSensorData(&bmi_body, &body_insance, &CurBodyAxisSet, &body_sensor_time);
//FingerImu_AdaptiveCalbration();
if(rslt < 0 )
{
send_text_msg("Finger IMU Error(%d)\n", rslt);
}
MsgBody_Tx_Fast.ref_cmd[0] = CurCIAxisSet.Pitch;
MsgBody_Tx_Fast.ref_cmd[1] = CurCIAxisSet.Yaw;
MsgBody_Tx_Fast.ref_cmd[2] = CurBodyAxisSet.Pitch;
MsgBody_Tx_Fast.ref_cmd[3] = CurBodyAxisSet.Yaw;
}
}
Solved! Go to Solution.
01-19-2022 02:32 PM
Hello levijo,
In you code, the following two line code call the same function FingerImu_Init(). In this function FingerImu_Init(), how do you access different sensors?
int8_t rslt = FingerImu_Init(&bmi_ci, &ci_instance);
rslt |= FingerImu_Init(&bmi_body, &body_insance);
If you want to access data from different sensors, the I2C address should be set to two different addresses.
01-20-2022 11:32 AM
Hi Levijo,
Multi-instance is not supported for BSXLite as described in the integration guide, page 8, Table 1.
Regards,
kgoveas
01-25-2022 04:43 PM
Hi Robin,
I have 2 different BSX160 sensors, one is set to default address 0x68, and the other is set to 0x69.
Anyhow, I did some more digging and I found that multiple instances are not supported by the BSXLite (it is supported by the BSXFull).
I tried several times to get the BSXFull library from sales team but so far without success,
Can you please help me to get the BSXFull library? I'm will to pay for it, sign NDA, whatever is required.
I'm really stuck with this project.
see below code:
/*! @brief This structure containing relevant bmi160 info */
struct bmi160_dev bmi_ci = {
.id = BMI160_1_I2C_ADDR,//0x68
.chip_id = 0,
.intf = BMI160_I2C_INTF,//i2c
.read = BMI160_ReadMulti,
.write = BMI160_WriteMulti,
.delay_ms = osDelay,
};
struct bmi160_dev bmi_body = {
.id = BMI160_2_I2C_ADDR,//0x69
.chip_id = 0,
.intf = BMI160_I2C_INTF,//i2c
.read = BMI160_ReadMulti,
.write = BMI160_WriteMulti,
.delay_ms = osDelay,
};