I am currently using an Arduino MKR ZERO to gather IMU data from three MKR IMU SHIELD boards (BNO055 IMU). I have utilized the <Adafruit_ZeroTimer.h> library to set a timer interrupt with a period of 10ms. To connect the three IMUs for data reading, I employed a TCA9548A multiplexer.
During the timer interrupt service, I stored the data in IMU_buf[]:
#include <MKRIMU.h>
void timer_ISR(void)
{
#include <MKRIMU.h>
void timer_ISR(void)
{
// interrupt interval
interrupt_interval = millis() - last_time_ms;
IMU_buf[IMU_buf_indx++] = static_cast<float>(interrupt_interval);
last_time_ms = millis();
// Reading the IMU data
IMU_start = micros();
for (uint8_t i = 0; i < 3; i++) // loop over each I2C channel
{
tcaselect(i); // select channel i
// Get IMU data.
IMU.readAcceleration(Ax, Ay, Az);
IMU.readGyroscope(Gx, Gy, Gz);
IMU_buf[IMU_buf_indx++] = Ax;
IMU_buf[IMU_buf_indx++] = Ay;
IMU_buf[IMU_buf_indx++] = Az;
IMU_buf[IMU_buf_indx++] = Gx;
IMU_buf[IMU_buf_indx++] = Gy;
IMU_buf[IMU_buf_indx++] = Gz;
}
IMU_reading_time = micros() - IMU_start;
IMU_buf[IMU_buf_indx++] = static_cast<float>(IMU_reading_time );
}
}
// select the desired channel on the I2C multiplexer
void tcaselect(uint8_t i)
{
if (i > 7)
return; // make sure input i is not larger than 7
Wire.beginTransmission(TCAADDR);
Wire.write(1 << i);
Wire.endTransmission();
}
I anticipated collecting approximately 1000 pieces of data over 10s. However, I ended up with about 2500 data in that same timeframe. Upon inspecting the interrupt_interval, I observed that it was only around 3~4 ms, whereas I was expecting an interval of 10 ms.
Subsequently, I removed the IMU data reading codes and retained only the following code:
void timer_ISR(void)
{
// interrupt interval
interrupt_interval = millis() - last_time_ms
IMU_buf[IMU_buf_indx++] = static_cast<float>(interrupt_interval );
last_time_ms = millis();
}
After this modification, the interrupt_interval precisely became 10 ms. This suggests that the timer I set up was functioning correctly and that introducing the IMU reading codes is what led to the discrepancy. My hypothesis is that the speed of IMU data reading might be too slow, which in turn could be blocking the interrupt service. However, I'm unsure as to why this would result in an increased data rate instead of a decrease.
Additionally, I checked the IMU_reading_time and found that it usually fluctuated between 500~2000us, which doesn't seem like a substantial amount of time.
PS: I also experimented with directly connecting just one IMU to the Arduino. This caused the interrupt interval to decrease to 8ms, which is still not the desired duration (10ms).
Could you kindly offer some guidance on this matter? Thank you in advance for your help!