0

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!

JING
  • 25
  • 4
  • 2
    ISR is supposed to be as short as possible. Sensor reading could take multiple clock cycles or even multiple ms. – hcheung Jul 30 '23 at 02:09
  • Thank you. It appears that the I2C communication is interfering with the normal operation of the ISR for unknown reasons. Additionally, the IMU_reading_time measurements proved to be incorrect. I have moved the IMU reading code into the main() function and the interrupt works fine now. – JING Jul 30 '23 at 23:41

0 Answers0