Reading from Wire inside an ISR

I am trying to read data from a Wire (connected to a gyroscope) from inside a function called from an interrupt service routine. I am using the FlexiTimer2 library from Arduino Playground - FlexiTimer2.

The problem I am having is that whenever this function (my function I'm attaching to the interrupt) is called, the code locks up. I beleive this is due to my Wire.something() function calls, since removing them and just using some Serial.print()s allows it to work properly.

My code:

void timerTask() {
  Serial.print("Gyro X: ");
  
  int buff[10];
  Wire.beginTransmission(ADDRESS_GYRO); //start transmission to ACC 
  Wire.write(0x1B);        //sends address to read from
  Wire.endTransmission(); //end transmission
  
  Wire.beginTransmission(ADDRESS_GYRO); //start transmission to ACC
  Wire.requestFrom(ADDRESS_GYRO, G_TO_READ);    // request 6 bytes from ACC
  
  int i = 0;
  while(Wire.available())    //ACC may send less than requested (abnormal)
  { 
    buff[i] = Wire.read(); // receive a byte
    i++;
  }
  Wire.endTransmission(); //end transmission
    
    
  Serial.print(buff[0]);
  Serial.print("\r\n");
}

And I assign my fuction to the interrupt handler here:

FlexiTimer2::set(500, timerTask);
    FlexiTimer2::start();

Is there a way for me to use Wire functions from within an interrupt, or is this not possible?

My ultimate goal is to query the gyro every so many milliseconds to get an accurate picture of how far I've rotated since I started.

Thanks for taking the time to read this...

 Wire.beginTransmission(ADDRESS_GYRO); //start transmission to ACC
  Wire.requestFrom(ADDRESS_GYRO, G_TO_READ);    // request 6 bytes from ACC
  
  int i = 0;
  while(Wire.available())    //ACC may send less than requested (abnormal)
  { 
    buff[i] = Wire.read(); // receive a byte
    i++;
  }
  Wire.endTransmission(); //end transmission

You don't need Wire.beginTransmission and Wire.endTransmission around Wire.requestFrom.

Wire.requestFrom returns the number of bytes read.

You shouldn't be doing Serial.print inside an ISR, and the Wire library uses interrupts which is why it doesn't work.

Better is to set a flag, check that flag in the loop function, and do your stuff there.

I see... I was starting to suspect the Wire lib using interrupts was the problem.

Thanks!

Rather than guess about how the Wire library works remember you have the source code for it - just have a look
at it's description and comments and code!

Actually for the Wire library you'd need to look at <install>/libraries/Wire/utility/twi.c to discover the use of interrupts,
so perhaps not the most straightforward example.

Built in libraries are either at <install>/libraries/... or a few (including HardwareSerial) are at <install>/hardware/arduino/cores/arduino/...

Even if the code means nothing the big comments at the top of a library file can be very informative.

or is this not possible?

It is generally not possible / advisable.

The issue is with re-entrancy: you have no way of knowing that before an isr is fired, if that very (wire) function is being called.

There are solutions around it but they fundamentally don't alter the picture:

  1. don't call a function from within the isr;
  2. if you have to, make sure that that function isn't called anywhere else.

Yes, I didn't think to look at the included source for the libs...

I have an alternative solution that involves not using the interrupt to handle my Wire calls (keeping track of time in my main loop with if/else and doing what I need to there)..

Thanks for the responses.