I am using the BMX160 for an inclinometer application.
1. I am seeing out of bounds readings when trying to do a 6 point max/min calibration to find the axis offsets.
I have the device set up as follows:
/* Select the Output data rate, range of accelerometer sensor */ sensor.accel_cfg.odr = BMI160_ACCEL_ODR_200HZ; sensor.accel_cfg.range = BMI160_ACCEL_RANGE_2G; sensor.accel_cfg.bw = BMI160_ACCEL_BW_NORMAL_AVG4;
I would expect the max/min value in 2G mode to be around the listing below (+/-) 17039.
However, if the unit is bumped or spun too fast when finding the max values for each axis, I get very large, seemingly invalid values greater than +/-22000.
Is there a way to cap the values at +/- 2g only or a register that indicates the reading overflowed the G setting? Is there some sort of setup issue I need to fix?
2. Is there any specific setup/bandwidth recommended for an inclinometer application? I am off around 3 degrees at 60 degrees. I would expect using a 3 axis incline calculation with good offset calibration that I should be able to get within 1 degree right?
I know for 1 axis, it becomes much less sensitive past 30-45 degrees. Should I be switching the axis as I move past 45 degrees? I thought using the other two axis helped mitigate this issue...
xcom = (x_max + x_min) / 2; xpp = x_max - x_min; x = ((float)m_axis_data.x - xcom) / ((float)xpp); ycom = (y_max + y_min) / 2; ypp = y_max - y_min; y = ((float)m_axis_data.y - ycom) / ((float)ypp); zcom = (z_max + z_min) / 2; zpp = z_max - z_min; z = ((float)m_axis_data.z - zcom) / ((float)zpp);
float x2 = (float)x * (float)x;
float y2 = (float)y * (float)y;
float z2 = (float)z * (float)z;
result = (float)y / sqrtf(x2 + z2);
3. Is there a better calibration I should be doing? It needs to be fairly simple for production.
For your description, you could configure sensor by paying attention to the following points to test it.
1.Set sensor to normal mode, and disable acc_us in register ACC_CONF(0x40);
2.Set acc_bwp to NORMAL_AVG4 or CIC_AVG8;
3.If the unit is bumped or spun too fast, you could set sensor range to 4G or 8G range.
BST Robin - Thanks for the response!
1. I read out the ACCEL_CONF register and verified that acc_us register is off.
uint8_t acc_conf; bmi160_get_regs(BMI160_ACCEL_CONFIG_ADDR, &acc_conf, 1, &sensor); NRF_LOG_INFO("ACC_CONF is 0x%X", acc_conf);
ACC_CONF is 0x29
2. CIC_AVG8 didn't seem to improve the "over-range" reading issue.
3. I don't think increasing the range will help me as my goal is to find the real +/-1 G reading for each axis. This will allow me to calculate the offsets for each axis. We have used this method in the past with other accelerometers with success.
The device is slowly rotated such that all axis will reach their max/min +/- 1 G zenith. The code then saves the max/min for each axis and uses this to find the offsets. If it bumped or rotated too fast I get very large positive and negative spikes and there doesn't seem to be any way for me to tell this not a real max/min.
My concern is the bumps or spins are causing the BMX160 to output data over the 2G range I have it set in. It is like I am getting 4G+ readings even though I am in 2G mode (I have read back the RANGE register to verify I am in 2G). I was hoping there was some setup issue that would cap the data to only 2 G or a way to tell my data "overflowed" the range setting...
Thanks again for the help!
As you said you set 2G range and got values greater than +/-22000, wonder the bumps or spins are causing the BMX160 to output data over the 2G range. So suggest you test it with 4G range, see max/min value.