MPU6050 sharing an arduino with Stepper Motors

Hi there,
I am working on the motor and position control for a robot as part of a much larger project. In order to track the orientation of the robot, I am using an MPU6050 with an Arduino (currently on an uno for testing, but the main project will use a mega).

After significantly more searching than I expected, I found this code for the gyroscope and am using it in its default configuration.

This code works great, but it seems as though it has to run continuously in order to work. If there is any sort of delay then it gives an error (FIFO Overflow on line 272) and wont display any data. As the delay gets longer, eventually no data points are displayed. I tested this simply by adding a delay() function at the end of the main loop to simulate time used running other I2C functions (the arduino will be a slave to a raspberry pi), running the stepper motors, etc..

For sanity's sake, I would like to have as few microcontrollers (read: 1) on the bot as possible, but I also need to connect the stepper motor drivers and (ideally) several ultrasonic sensors to the board and control all of them simultaneously. I thought an interrupt function would work but from what I have read, I2C doesn't work well in interrupt functions (I may be wrong about this, not super sure). My question is then, how can I have this sensor on an arduino and still run stepper motors and other sensors without making the gyroscope useless.

Hope this makes sense, happy to clarify if needed. Thanks in advance!

Try this out:

uint8_t GetCurrentFIFOPacket(uint8_t *data, uint8_t length) { // overflow proof
  int16_t fifoC;
  // This section of code is for when we allowed more than 1 packet to be acquired
  uint32_t BreakTimer = micros();
  do {
    if ((fifoC = mpu.getFIFOCount())  > length) {

      if (fifoC > 200) { // if you waited to get the FIFO buffer to > 200 bytes it will take longer to get the last packet in the FIFO Buffer than it will take to  reset the buffer and wait for the next to arrive
        mpu.resetFIFO(); // Fixes any overflow corruption
        fifoC = 0;
        while (!(fifoC = mpu.getFIFOCount()) && ((micros() - BreakTimer) <= (11000))); // Get Next New Packet
      } else { //We have more than 1 packet but less than 200 bytes of data in the FIFO Buffer
        uint8_t Trash[BUFFER_LENGTH];
        while (fifoC = mpu.getFIFOCount() > length) { // Test each time just in case the MPU is writing to the FIFO Buffer
          fifoC = fifoC - length; // Save the last packet
          uint16_t  RemoveBytes;
          while (fifoC) { // fifo count will reach zero so this is safe
            RemoveBytes = min((int)fifoC, BUFFER_LENGTH);
            mpu.getFIFOBytes(Trash, (uint8_t)RemoveBytes);
            fifoC -= RemoveBytes;
          }
        }
      }
    }
    if (!fifoC) return 0; // Called too early no data or we timed out after FIFO Reset
    // We have 1 packet
    if ((micros() - BreakTimer) > (11000)) return 0;
  } while (fifoC != length);
  mpu.getFIFOBytes(data, length); //Get 1 packet
  return 1;
}

It is a Catch-all no Overflow worries MPU6050 get the latest reading function. Now you can use it with or without detecting the interrupt.
Returns 1 if it got data returns 0 if it doesn’t

use the boiler pate link you shared with us and replace the loop function with this one for using without interrupts

// ================================================================
// ===                    MAIN PROGRAM LOOP                     ===
// ================================================================

void loop() {
// Place non blocking code here if possible delaying longer than about 70ms will cause a longr delay  up to 10ms when retrieving the packet as the FIFO buffer gets quite large 
  if (!GetCurrentFIFOPacket(fifoBuffer, packetSize)) return;
// Triggers every 10ms
  mpu.dmpGetQuaternion(&q, fifoBuffer);
  mpu.dmpGetGravity(&gravity, &q);
  mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
  Serial.print(" ypr\t");
  Serial.print(ypr[0] * 180 / M_PI);
  Serial.print("\t");
  Serial.print(ypr[1] * 180 / M_PI);
  Serial.print("\t");
  Serial.print(ypr[2] * 180 / M_PI);
  Serial.println();
  return;
}

Or if you would like interrupt handling
Use this main loop:

//================================================================
// ===                    MAIN PROGRAM LOOP                     ===
// ================================================================

void loop() {
// Place non blocking code here if possible delaying longer than about 70ms will cause a longr delay  up to 10ms when retrieving the packet as the FIFO buffer gets quite large 
  if (mpuInterrupt && !GetCurrentFIFOPacket(fifoBuffer, packetSize)){
     // Interrupt Miss fire happens every other time.
     mpuInterrupt = false;
     return;
  }
// Triggers every 10ms
  mpuInterrupt = false;
  mpu.dmpGetQuaternion(&q, fifoBuffer);
  mpu.dmpGetGravity(&gravity, &q);
  mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
  Serial.print(" ypr\t");
  Serial.print(ypr[0] * 180 / M_PI);
  Serial.print("\t");
  Serial.print(ypr[1] * 180 / M_PI);
  Serial.print("\t");
  Serial.print(ypr[2] * 180 / M_PI);
  Serial.println();
  return;
}

Just so you know Jeff and I and several others were involved with the mighty task of creating an overflow proof MPU6050 function. I will shortly submit a pull request to include this as I believe it has been proven reliable.
Let me know what you think.
The related discussion if you care to dig through 133 posts of discovering the best solution.
Z