Describe the bug
The IMU ODR is 25 Hz as documented, but the setup achieved to reach this ODR is incorrect.
When calling this function in EmotiBit.cpp setup:
|
BMI160.setGyroRate(BMI160GyroRate::BMI160_GYRO_RATE_100HZ); |
There is a problem because the function name setGyroRate is duplicated across two classes in the EmotiBit_BMI160 library.
BMI160.cpp
/** Set gyroscope output data rate.
* @param rate New output data rate
* @see getGyroRate()
* @see BMI160_GYRO_RATE_25HZ
* @see BMI160_RA_GYRO_CONF
*/
void BMI160Class::setGyroRate(uint8_t rate) {
reg_write_bits(BMI160_RA_GYRO_CONF, rate,
BMI160_GYRO_RATE_SEL_BIT,
BMI160_GYRO_RATE_SEL_LEN);
}
CurieIMU.cpp
void CurieIMUClass::setGyroRate(int rate)
{
BMI160GyroRate bmiRate;
if (rate <= 25) {
bmiRate = BMI160_GYRO_RATE_25HZ;
} else if (rate <= 50) {
bmiRate = BMI160_GYRO_RATE_50HZ;
} else if (rate <= 100) {
bmiRate = BMI160_GYRO_RATE_100HZ;
} else if (rate <= 200) {
bmiRate = BMI160_GYRO_RATE_200HZ;
} else if (rate <= 400) {
bmiRate = BMI160_GYRO_RATE_400HZ;
} else if (rate <= 800) {
bmiRate = BMI160_GYRO_RATE_800HZ;
} else if (rate <= 1600) {
bmiRate = BMI160_GYRO_RATE_1600HZ;
} else {
bmiRate = BMI160_GYRO_RATE_3200HZ;
}
BMI160Class::setGyroRate(bmiRate);
}
CurieIMUClass inherits from BMI160Class and redefines setGyroRate. This redefined function expects its parameter to be the ODR in Hz, not an enum. But the decimal value for BMI160_GYRO_RATE_100HZ is 8, defined here. So the setup call is setting the ODR to 25 Hz even when passing the 100 Hz enum. In fact, a 100 Hz enum is used for the accelerometer and magnetometer setup as well.
|
BMI160.setAccelRate(BMI160AccelRate::BMI160_ACCEL_RATE_100HZ); |
|
BMI160.setMagRate(BMI160MagRate::BMI160_MAG_RATE_100HZ); |
However, the ODR remains at 25 Hz on this channels (and there are no problems with accel/mag setup function redefinitions). Why don't these run at 100 Hz? The reason is that the IMU is set to headerless mode and the FIFO is enabled for all channels.
|
// Setup the FIFO |
|
BMI160.setAccelFIFOEnabled(true); |
|
_imuFifoFrameLen += 6; |
|
BMI160.setGyroFIFOEnabled(true); |
|
_imuFifoFrameLen += 6; |
|
BMI160.setMagFIFOEnabled(true); |
|
_imuFifoFrameLen += 8; |
|
BMI160.setFIFOHeaderModeEnabled(false); |
In this specific configuration, all IMU channels need to have the same ODR (page 24 of the BMI160 datasheet):
In headerless mode no header byte is used and the frames consist only of data bytes. The data bytes will always be sensor data. Only regular frames with the same ODR for all sensors are supported and no external interrupt flags are possible.
Because the gyro was being set to 25 Hz behind the scenes, it limited the frame output to that rate even though the accel and mag were set at 100 Hz.
Expected behavior
Looking at the setup functions, the IMU ODR should be 100 Hz as 100 Hz enums are being used. The code should be changed to use 25 Hz enums while preserving the 25 Hz ODR. This makes changing the ODR more straightforward if users wish to do so.
Additional details
- EmotiBit firmware version: observed on v1.14.3, but stems from this PR.
Describe the bug
The IMU ODR is 25 Hz as documented, but the setup achieved to reach this ODR is incorrect.
When calling this function in EmotiBit.cpp setup:
EmotiBit_FeatherWing/EmotiBit.cpp
Line 675 in 47f981c
There is a problem because the function name
setGyroRateis duplicated across two classes in theEmotiBit_BMI160library.BMI160.cpp
CurieIMU.cpp
CurieIMUClassinherits fromBMI160Classand redefinessetGyroRate. This redefined function expects its parameter to be the ODR in Hz, not an enum. But the decimal value forBMI160_GYRO_RATE_100HZis 8, defined here. So the setup call is setting the ODR to 25 Hz even when passing the 100 Hz enum. In fact, a 100 Hz enum is used for the accelerometer and magnetometer setup as well.EmotiBit_FeatherWing/EmotiBit.cpp
Line 668 in 47f981c
EmotiBit_FeatherWing/EmotiBit.cpp
Line 729 in 47f981c
However, the ODR remains at 25 Hz on this channels (and there are no problems with accel/mag setup function redefinitions). Why don't these run at 100 Hz? The reason is that the IMU is set to headerless mode and the FIFO is enabled for all channels.
EmotiBit_FeatherWing/EmotiBit.cpp
Lines 742 to 749 in 47f981c
In this specific configuration, all IMU channels need to have the same ODR (page 24 of the BMI160 datasheet):
Because the gyro was being set to 25 Hz behind the scenes, it limited the frame output to that rate even though the accel and mag were set at 100 Hz.
Expected behavior
Looking at the setup functions, the IMU ODR should be 100 Hz as 100 Hz enums are being used. The code should be changed to use 25 Hz enums while preserving the 25 Hz ODR. This makes changing the ODR more straightforward if users wish to do so.
Additional details