04-24-2020 03:57 PM
Hi everyone
Following the BMI160_driver I was able to receive data from gyro and accel of BMX160 sensor. Now I try to apply Fast Offset Compensation to calibrate the output data. Following the BMI160_API I implemented the snippet below but it returns error -11 which means BMI160_FOC_FAILURE. The error code is returning from the trigger_foc(offset, dev) function (line 2512 bmi160.c file) and going on step further I found that the reason for error -11 is due to the fact that foc_status = 0 and never becomes 1 as you can see at the image below. I do not know either what does it means or how to fix it...
struct bmi160_foc_conf foc_conf; // na - FOC configuration structure
struct bmi160_offsets offset; // na - Structure to store the offsets
foc_conf.acc_off_en = BMI160_ENABLE; // na - Enable offset compensation for accel
// na - FOC configurations - Datasheet pg51
foc_conf.foc_acc_x = BMI160_FOC_ACCEL_0G; // na - x axes is 0g relative to the earth graviry
foc_conf.foc_acc_y = BMI160_FOC_ACCEL_0G; // na - y axes is 0g relative to the earth graviry
foc_conf.foc_acc_z = BMI160_FOC_ACCEL_POSITIVE_G; // na - z axes is 1g relative to the earth graviry
foc_conf.foc_gyr_en = BMI160_ENABLE; // na - Enable FOC for gyro
foc_conf.gyro_off_en = BMI160_ENABLE; // na - Enable offset compensation for gyro
rslt = bmi160_start_foc(&foc_conf, &offset, &sensor);
if (rslt == BMI160_OK) {
NRF_LOG_INFO("FOC DONE SUCCESSFULLY ");
NRF_LOG_INFO("OFFSET VALUES AFTER FOC : ");
NRF_LOG_INFO("OFFSET VALUES ACCEL X : %d ", offset.off_acc_x);
NRF_LOG_INFO("OFFSET VALUES ACCEL Y : %d ", offset.off_acc_y);
NRF_LOG_INFO("OFFSET VALUES ACCEL Z : %d ", offset.off_acc_z);
NRF_LOG_INFO("OFFSET VALUES GYRO X : %d ", offset.off_gyro_x);
NRF_LOG_INFO("OFFSET VALUES GYRO Y : %d ", offset.off_gyro_y);
NRF_LOG_INFO("OFFSET VALUES GYRO Z : %d ", offset.off_gyro_z);
} else {
NRF_LOG_INFO("FOC FAILED");
}
The strange thing is that if I bypass the if(rslt == BMI) statement, then some results are printed for some of the axis (but I do not know if they are correct) as you can see below
Any advice from the experts?
Thanks in advance
Nick
04-25-2020 02:55 AM
If the foc_rdy is always 1, can you check the reigster 0x02 after time out?
Only for the printed offset value, looks fine but it is not just simple answer. you can also compare the data before and after FOC to see if data quality becomes good or not.
In case, please also print out the related register content (power_CONF, FOC_CONF, others used in the FOC function) for further debug.
04-26-2020 10:33 AM
Hi Vincent,
Thank you for your support!!
Well, I figured out that if I increase the timeout period then foc_status becomes 1 after 525ms. This is quite strange and I cannot understand the reason. The datasheet says " Foc_rdy is "0" while the measurement is in progress. Accelerometer and gyroscope values are measured with preset filter settings. This will take a maximum time of 250ms". In my case, it means that are needed 525ms to take the measurement?
Also, following your advice, I printed out the register content (after the timeout) from FOC_CONF(0x69), ERR_REG(0x02), STATUS(0x1B).
From the images below you can see the results. The first screenshot is for timeout <10 (10 x 25ms step) and you can see that after 250ms, foc_status is still 0 and is returned the error -11. FOC_CONF = 01111101 and ERR_REG = 10000000 based on the datasheet looks fine but STATUS = 11110000
After increasing the timeout (timeout<30 -> 25ms * 30 =750ms) I saw that foc_status became 1 after 25ms * 21 = 525ms. There was change neither to FOC_CONF nor to ERR_REG but now the STATUS = 00111000
I cannot understand this behavior 😕 Maybe this is somehow related to my settings? These are my setting
sensor.id = BMI160_I2C_ADDR; //0x68
sensor.interface = BMI160_I2C_INTF; //0x00
sensor.read = Acc_i2c_Read;
sensor.write = Acc_i2c_Write;
sensor.delay_ms = Acc_delay_ms;
bmm150.dev_id = BMM150_DEFAULT_I2C_ADDRESS; //0x10
bmm150.intf = BMM150_I2C_INTF;
bmm150.read = bmm150_aux_read;
bmm150.write = bmm150_aux_write;
bmm150.delay_ms = Acc_delay_ms;
bmi160_init(&sensor)
sensor.aux_cfg.aux_sensor_enable = BMI160_ENABLE; // auxiliary sensor enable
sensor.aux_cfg.aux_i2c_addr = BMI160_AUX_BMM150_I2C_ADDR; // auxiliary sensor address
sensor.aux_cfg.manual_enable = BMI160_ENABLE; // setup mode enable
sensor.aux_cfg.aux_rd_burst_len = BMI160_AUX_READ_LEN_2; // burst read of 2 byte
bmi160_aux_init(&sensor);
bmm150_init(&bmm150);
sensor.accel_cfg.odr = BMI160_ACCEL_ODR_100HZ; // na - output data rate - Configure accel to measure at 100Hz
sensor.accel_cfg.range = BMI160_ACCEL_RANGE_2G; // na - range
sensor.accel_cfg.bw = BMI160_ACCEL_BW_NORMAL_AVG4; // na - bandwidth
sensor.accel_cfg.power = BMI160_ACCEL_NORMAL_MODE; // na - powermode
// na - configure Gyro sensor
sensor.gyro_cfg.odr = BMI160_GYRO_ODR_100HZ; // na - output data rate - Configure gyro to measure at 100Hz
sensor.gyro_cfg.range = BMI160_GYRO_RANGE_500_DPS; // na - range
sensor.gyro_cfg.bw = BMI160_GYRO_BW_NORMAL_MODE; // na - bandwidth
sensor.gyro_cfg.power = BMI160_GYRO_NORMAL_MODE; // na - powermode
bmi160_set_sens_conf(&sensor);
bmm150.settings.preset_mode = BMM150_PRESETMODE_REGULAR;
bmm150_set_presetmode(&bmm150);
bmm150.settings.pwr_mode = BMM150_NORMAL_MODE;
bmm150_set_op_mode(&bmm150);
sensor.aux_cfg.aux_odr = BMI160_AUX_ODR_100HZ;
bmi160_config_aux_mode(&sensor);
bmi160_set_aux_auto_mode(&aux_addr, &sensor);
Lastly, some measurements before FOC
Thanks for the support
Nick
05-04-2020 07:49 PM
Could someone from the moderators assist me?