I2CDevlib with MPU6050 and Arduino Pro Mini

Hi there,

Does anyone know if the I2CDevlib is compatible with the Arduino Pro Mini running at 8 MHz.

I am currently using it and does not seem to work where it worked with my Uno.

Thanks!

DD

Do you compile it with the defaults as available from GitHub? In this case it uses the Wire library of the Arduino IDE which should be compatible with the Pro Mini given you selected the correct board.

The I2CDevlib is not really recommended, the library's code show errors in the usage of the Wire library that weren't fixed in all the years it exists:

                Wire.beginTransmission(devAddr);
                Wire.write(regAddr);
                Wire.endTransmission();
                Wire.beginTransmission(devAddr);
                Wire.requestFrom(devAddr, (uint8_t)min(length - k, BUFFER_LENGTH));

The second Wire.beginTransmission should be omitted. Return codes (which may show errors) are not handled which may lead to unrecognized problems in a setup where the hardware wiring isn't correct.

I am currently using it and does not seem to work where it worked with my Uno.

Post that code! (don't forget the code tags, that's the </> button in the editor)

Here is the sample of my code:

#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"

// Define display I2C bus with 6 page buffer
U8G2_SSD1306_128X64_NONAME_2_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);

// MPU 6050 status variables
MPU6050 mpu;            // class default I2C address is 0x68
uint8_t mpuIntStatus;   // holds interrupt status byte from MPU
uint16_t packetSize;    // expected DMP packet size (42 bytes)
uint16_t fifoCount;     // number of bytes in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer

// Callback function which determines if MPU interrupt has toggled
int mpu6050_int = 2;    // interrupt pin I/O 2
bool mpuInterrupt = false; // flag which will toggle when interrupt is called/handled
void dmpDataReady() {
  mpuInterrupt = true;
}

// Step Counting Variables
Quaternion q; // quaternion container [w, x, y, z]

// Bootloader
void setup()
{
  Serial.begin(9600);

  // Define Displays I2C address and display boot screen
  u8g2.begin();
  u8g2.firstPage();
  do {
    u8g2.drawXBMP(32, 0, 64, 64, boot);
  } while ( u8g2.nextPage() );

  // setup MPU6050
  mpu.initialize(); // power up device and take out of sleep mode
  mpu.dmpInitialize(); // load DMP flash and configure the DMP
  mpu.setDMPEnabled(true); // turn on the DMP, now that it's ready
  packetSize = mpu.dmpGetFIFOPacketSize(); // get expected DMP packet size

  // setup MPU6050 interrupt
  pinMode(mpu6050_int, INPUT);
  attachInterrupt(digitalPinToInterrupt(mpu6050_int), dmpDataReady, RISING);
  mpuIntStatus = mpu.getIntStatus();

  delay(3000);
}

.....

ddesousa:
Hi there,

Does anyone know if the I2CDevlib is compatible with the Arduino Pro Mini running at 8 MHz.

I am currently using it and does not seem to work where it worked with my Uno.

Thanks!

DD

are you running your pro mini at 3.3V?
Note the the mpu6050 breakout VCC pin requires 5V because of the onboard voltage regulator.
Z

I tested the MPU6050 with an arduino UNO and has it plugged into 3.3V

Post links to the MPU6050 breakout board and the I2C OLED you're using. If you have them, post links to the schematics of the boards.
Also post a wiring diagram of your setup.

bool mpuInterrupt = false; // flag which will toggle when interrupt is called/handled
void dmpDataReady() {
  mpuInterrupt = true;
}

You forgot the volatile declarition for the mpuInterrupt variable. Without it the compiler might optimize relevant code away as it does have a chance to know that it will be called.

I changed that. Still does not work.

I changed that. Still does not work.

I expect your hardware to be the problem as the first two sentences of my last reply adumbrated. You seem to have them completely ignored.

Sorry about that.

I am using the SSD1306 (https://www.amazon.ca/Yellow-Moudle-Display-Arduino-Raspberry/dp/B01N78FUH7/ref=sr_1_2?ie=UTF8&qid=1508949420&sr=8-2&keywords=oled+arduino) with the u8g2 library and the MPU6050 (Fermion: MPU-6050 6 DOF Sensor (Breakout) - DFRobot) with the I2C devlib library.
Both modules work seperatly with their respective libraries.

I cannot post an image right now as I'm currently working from home and the devices are at work. I will try to explain it the best I can. The OLED is connected to SDA, SCL, 3V3, and GND. Another 4 wires connect from the OLED to the MPU so the two devices share all their lines. In addition, there is a wire from the INT pin on the MPU to output 2 on the board.

Dan

I found the problem: you use a software emulation for I2C for the OLED but on the hardware pins: U8G2_SSD1306_128X64_NONAME_2_SW_I2C. This cannot work as the two will conflict in pin usage.

Change

U8G2_SSD1306_128X64_NONAME_2_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);

to

U8G2_SSD1306_128X64_NONAME_2_HW_I2C u8g2(U8G2_R0);

Great catch pylon!

Unfortunately, i already did that.

I have already spoken to the creator of the library and he recommended that too. I did it and the OLED began working but I am still getting the issue where writing to the OLED causes the MPU data to become distorted.

Thanks

ddesousa:
Great catch pylon!

Unfortunately, i already did that.

I have already spoken to the creator of the library and he recommended that too. I did it and the OLED began working but I am still getting the issue where writing to the OLED causes the MPU data to become distorted.

Thanks

How often do you need the data from the MPU6050?
The default dmp fifo buffer update is every 10 ms
Line 305 of MPU6050_6AXIS_MOTIONAPPS20.h sets that rate:

    0x02,   0x16,   0x02,   0x00, 0x01                // D_0_22 inv_set_fifo_rate
    // This very last 0x01 WAS a 0x09, which drops the FIFO rate down to 20 Hz. 0x07 is 25 Hz,
    // 0x01 is 100Hz. Going faster than 100Hz (0x00=200Hz) tends to result in very noisy data.
    // DMP output frequency is calculated easily using this equation: (200Hz / (1 + value))
    // It is important to make sure the host processor can keep up with reading and processing
    // the FIFO output at the desired rate. Handling FIFO overflow cleanly is also a good idea.

This will give you more time do whatever you need between interrupts.

ddesousa:
I tested the MPU6050 with an arduino UNO and has it plugged into 3.3V

this also confused me. The MPU6050 breakout board requires 5V because of the onboard 3.3V regulator. If you supply the MPU6050 board VCC with 3.3V the onboard voltage regulator will not provide 3.3V to the mpu6050 as well as other issues with the i2c bus voltage being even lower.

Hi there.

Thanks for the advice.

I had already changed the frequency to 20 Hz which I believe is a suitable rate.

I also took your advice and set it to 5V. The devices perform the same

ddesousa:
Hi there.

Thanks for the advice.

I had already changed the frequency to 20 Hz which I believe is a suitable rate.

I also took your advice and set it to 5V. The devices perform the same

I was afraid of that, the example code found in the library has a flaw where in it locks in a while loop waiting for good data. this blocks other code from functioning which sounds like your issue.
I have tackled this intensely and somewhere on this forum was my thread that beat it up thoroughly. luckily for you I have that alternate to that example sketch that may be your solution.
This sketch is documented well and functions without corrupted data sets and is divided into functions.
I hope simplifies your coding.
Z

MPU6050_Latest_code.ino (7.98 KB)

I have done something similar with my code. Please take a look and see if you can find a problem. I will take a look at what you posted but after first glance, it does not look very different from what I have.

#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"

// Define display I2C bus with 6 page buffer
U8G2_SSD1306_128X64_NONAME_2_HW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);

// MPU 6050 status variables
MPU6050 mpu;            // class default I2C address is 0x68
uint8_t mpuIntStatus;   // holds interrupt status byte from MPU
uint16_t packetSize;    // expected DMP packet size (42 bytes)
uint16_t fifoCount;     // number of bytes in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer

// Callback function which determines if MPU interrupt has toggled
int mpu6050_int = 2;    // interrupt pin I/O 2
volatile bool mpuInterrupt = false; // flag which will toggle when interrupt is called/handled
void dmpDataReady() {
  mpuInterrupt = true;
}

// Bluetooth Variables
char dateBT[15]; // date info MM/DD/YYYY
char timeBT[15]; // time info HH:MM:SS MM
char callBT[20]; // caller number info
char textBT[20]; // text number info

// General Variables
const int runArraySize = 10;

// Step Counting Variables
Quaternion q; // quaternion container [w, x, y, z]
const double stepDiffMinThreshold = 0.025; // minimum difference between step max and min for considered step
int stepCount = 0;                        // total number of steps taken
double stepMax = 0;                       // peak of quaternion data
double stepMin = 0;                       // trough of quaternion data
double currentQData[3];                   // array storing recent quaternion values

// Battery Variables
const int batteryPin = 1;         // analog 1
const float referenceVolts = 5.0; // the default reference on a 5-volt board

// Bootloader
void setup()
{
  Serial.begin(9600);
  
  // Define Displays I2C address and display boot screen
  u8g2.begin();
  u8g2.firstPage();
  do {
    u8g2.drawXBMP(32, 0, 64, 64, boot);
  } while ( u8g2.nextPage() );

  // setup MPU6050
  Wire.begin();
  mpu.initialize(); // power up device and take out of sleep mode
  pinMode(mpu6050_int, INPUT);
  mpu.dmpInitialize(); // load DMP flash and configure the DMP
  mpu.setDMPEnabled(true); // turn on the DMP, now that it's ready

  // setup MPU6050 interrupt
  attachInterrupt(digitalPinToInterrupt(mpu6050_int), dmpDataReady, RISING);
  mpuIntStatus = mpu.getIntStatus();

  packetSize = mpu.dmpGetFIFOPacketSize(); // get expected DMP packet size
  delay(3000);
}

// Function to update the display with latest information
void updateDisplay()
{
  // if there is an incoming phone call
  if (strlen(callBT) == 10)
  {
    u8g2.setFont(u8g2_font_profont11_tf);
    // print time top left corner
    u8g2.drawStr(0, 10, timeBT);

    u8g2.setFont(u8g2_font_profont22_tf);
    // display call text and phone number
    u8g2.setCursor(40, 38);
    u8g2.print("Call");
    u8g2.drawStr(0, 58, callBT);
  }
  // if there is an incoming text
  else if (strlen(textBT) == 10)
  {
    u8g2.setFont(u8g2_font_profont11_tf);
    // print time top left corner
    u8g2.drawStr(0, 10, timeBT);

    u8g2.setFont(u8g2_font_profont22_tf);
    // display text text and phone number
    u8g2.setCursor(40, 38);
    u8g2.print("Text");
    u8g2.drawStr(0, 58, textBT);
  }
  // if no incoming call or text
  else
  {
    u8g2.setFont(u8g2_font_profont11_tf);
    // display date
    u8g2.drawStr(0, 10, dateBT);

    // display heart rate
    u8g2.setCursor(14, 62);
    u8g2.print(String(heartRate) + " bpm");
    u8g2.drawXBMP(0, 54, 10, 10, heart);

    // display steps
    u8g2.setCursor(78, 62);
    u8g2.print(String(stepCount*2) + " stp");
    u8g2.drawXBMP(64, 54, 10, 10, mountain);

    // display time
    u8g2.setFont(u8g2_font_profont22_tf);
    // center time on display
    if (strlen(timeBT) == 7)
      u8g2.drawStr(20, 38, timeBT);
    else if (strlen(timeBT) == 8)
      u8g2.drawStr(13, 38, timeBT);
  }
  // draw BT logo and display screen
  u8g2.drawXBMP(118, 0, 10, 10, BT);

  // obtain and display battery status
  int battVoltRaw = analogRead(batteryPin);
  float battVolt = (battVoltRaw / 1023.0) * referenceVolts;
  // display full battery
  if (battVolt >= 3.6)
    u8g2.drawXBMP(105, 0, 10, 10, battHigh);
  // display low battery
  if (battVolt < 3.6)
    u8g2.drawXBMP(105, 0, 10, 10, battLow);
}

// Function which reads and parses BT data from mobile
void readBTData()
{
  // save date
  memset(dateBT, 0, strlen(dateBT)); // clear
  Serial.readBytesUntil('|', dateBT, 20);
  str_replace(dateBT, " ", "");
  Serial.read();

  // save time
  memset(timeBT, 0, strlen(timeBT));
  Serial.readBytesUntil('|', timeBT, 20);
  Serial.read();

  // save call notifications and parse number
  memset(callBT, 0, strlen(callBT));
  Serial.readBytesUntil('|', callBT, 20);
  str_replace(callBT, " ", "");
  str_replace(callBT, "(", "");
  str_replace(callBT, ")", "");
  str_replace(callBT, "-", "");
  if (strlen(callBT) == 11)
    str_remove(callBT, 0, 1);
  Serial.read();

  // save text notifications and parse number
  memset(textBT, 0, strlen(textBT));
  Serial.readBytesUntil('\n', textBT, 20);
  str_replace(textBT, " ", "");
  str_replace(textBT, "(", "");
  str_replace(textBT, ")", "");
  str_replace(textBT, "-", "");
  if (strlen(textBT) == 11)
    str_remove(callBT, 0, 1);
  Serial.read();
}

void countSteps()
{
  // get current MPU status
  mpuIntStatus = mpu.getIntStatus(); // get INT_STATUS byte
  fifoCount = mpu.getFIFOCount(); // get current FIFO count

  // check for DMP data ready interrupt
  if (mpuIntStatus & 0x02)
  {
    // wait untill enough data is available
    while (fifoCount < packetSize)
      fifoCount = mpu.getFIFOCount();

    // read a packet from FIFO
    mpu.getFIFOBytes(fifoBuffer, packetSize);
    fifoCount -= packetSize; // track FIFO count tp determine if more data can be read

    // get quaternion values
    mpu.dmpGetQuaternion(&q, fifoBuffer);
  }
  Serial.println(q.w*10);
  // update recent quaternion values
  currentQData[0] = currentQData[1];
  currentQData[1] = currentQData[2];
  currentQData[2] = q.w; 
  // if a peak/max is found
  if(currentQData[1] > currentQData[0] && currentQData[1] > currentQData[2])
  {
    stepMax = currentQData[1];// update peak value      
    double maxMinDiff = stepMax - stepMin; 
    // if a step is detected
    if (maxMinDiff > stepDiffMinThreshold)
    {
        stepCount++;
    }
  }
  // if a trough/min is found
  else if(currentQData[1] < currentQData[0] && currentQData[1] < currentQData[2])
  {
    stepMin = currentQData[1];
  }
}

void loop()
{
  // only read BT data if device is connected
  if (Serial.available() > 0)
  {
    readBTData();
    str_remove(timeBT, strlen(timeBT) - 6, 3); // remove seconds
    u8g2.firstPage();
    do {
      updateDisplay();
    } while ( u8g2.nextPage() );
  }

  // wait for MPU interrupt to process steps
  if (mpuInterrupt || fifoCount > packetSize)
  {
    mpuInterrupt = false; // reset interrupt flag
    countSteps();
  }
}

Don't mind any code besides the setup really

ddesousa:
I have done something similar with my code. Please take a look and see if you can find a problem. I will take a look at what you posted but after first glance, it does not look very different from what I have.

#include <Arduino.h>

#include <U8g2lib.h>
#include <Wire.h>
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"

// Define display I2C bus with 6 page buffer
U8G2_SSD1306_128X64_NONAME_2_HW_I2C u8g2(U8G2_R0, /* clock=/ SCL, / data=/ SDA, / reset=*/ U8X8_PIN_NONE);

// MPU 6050 status variables
MPU6050 mpu;            // class default I2C address is 0x68
uint8_t mpuIntStatus;   // holds interrupt status byte from MPU
uint16_t packetSize;    // expected DMP packet size (42 bytes)
uint16_t fifoCount;     // number of bytes in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer

// Callback function which determines if MPU interrupt has toggled
int mpu6050_int = 2;    // interrupt pin I/O 2
volatile bool mpuInterrupt = false; // flag which will toggle when interrupt is called/handled
void dmpDataReady() {
 mpuInterrupt = true;
}

// Bluetooth Variables
char dateBT[15]; // date info MM/DD/YYYY
char timeBT[15]; // time info HH:MM:SS MM
char callBT[20]; // caller number info
char textBT[20]; // text number info

// General Variables
const int runArraySize = 10;

// Step Counting Variables
Quaternion q; // quaternion container [w, x, y, z]
const double stepDiffMinThreshold = 0.025; // minimum difference between step max and min for considered step
int stepCount = 0;                        // total number of steps taken
double stepMax = 0;                       // peak of quaternion data
double stepMin = 0;                       // trough of quaternion data
double currentQData[3];                   // array storing recent quaternion values

// Battery Variables
const int batteryPin = 1;         // analog 1
const float referenceVolts = 5.0; // the default reference on a 5-volt board

// Bootloader
void setup()
{
 Serial.begin(9600);
 
 // Define Displays I2C address and display boot screen
 u8g2.begin();
 u8g2.firstPage();
 do {
   u8g2.drawXBMP(32, 0, 64, 64, boot);
 } while ( u8g2.nextPage() );

// setup MPU6050
 Wire.begin();
 mpu.initialize(); // power up device and take out of sleep mode
 pinMode(mpu6050_int, INPUT);
 mpu.dmpInitialize(); // load DMP flash and configure the DMP
 mpu.setDMPEnabled(true); // turn on the DMP, now that it's ready

// setup MPU6050 interrupt
 attachInterrupt(digitalPinToInterrupt(mpu6050_int), dmpDataReady, RISING);
 mpuIntStatus = mpu.getIntStatus();

packetSize = mpu.dmpGetFIFOPacketSize(); // get expected DMP packet size
 delay(3000);
}

// Function to update the display with latest information
void updateDisplay()
{
 // if there is an incoming phone call
 if (strlen(callBT) == 10)
 {
   u8g2.setFont(u8g2_font_profont11_tf);
   // print time top left corner
   u8g2.drawStr(0, 10, timeBT);

u8g2.setFont(u8g2_font_profont22_tf);
   // display call text and phone number
   u8g2.setCursor(40, 38);
   u8g2.print("Call");
   u8g2.drawStr(0, 58, callBT);
 }
 // if there is an incoming text
 else if (strlen(textBT) == 10)
 {
   u8g2.setFont(u8g2_font_profont11_tf);
   // print time top left corner
   u8g2.drawStr(0, 10, timeBT);

u8g2.setFont(u8g2_font_profont22_tf);
   // display text text and phone number
   u8g2.setCursor(40, 38);
   u8g2.print("Text");
   u8g2.drawStr(0, 58, textBT);
 }
 // if no incoming call or text
 else
 {
   u8g2.setFont(u8g2_font_profont11_tf);
   // display date
   u8g2.drawStr(0, 10, dateBT);

// display heart rate
   u8g2.setCursor(14, 62);
   u8g2.print(String(heartRate) + " bpm");
   u8g2.drawXBMP(0, 54, 10, 10, heart);

// display steps
   u8g2.setCursor(78, 62);
   u8g2.print(String(stepCount*2) + " stp");
   u8g2.drawXBMP(64, 54, 10, 10, mountain);

// display time
   u8g2.setFont(u8g2_font_profont22_tf);
   // center time on display
   if (strlen(timeBT) == 7)
     u8g2.drawStr(20, 38, timeBT);
   else if (strlen(timeBT) == 8)
     u8g2.drawStr(13, 38, timeBT);
 }
 // draw BT logo and display screen
 u8g2.drawXBMP(118, 0, 10, 10, BT);

// obtain and display battery status
 int battVoltRaw = analogRead(batteryPin);
 float battVolt = (battVoltRaw / 1023.0) * referenceVolts;
 // display full battery
 if (battVolt >= 3.6)
   u8g2.drawXBMP(105, 0, 10, 10, battHigh);
 // display low battery
 if (battVolt < 3.6)
   u8g2.drawXBMP(105, 0, 10, 10, battLow);
}

// Function which reads and parses BT data from mobile
void readBTData()
{
 // save date
 memset(dateBT, 0, strlen(dateBT)); // clear
 Serial.readBytesUntil('|', dateBT, 20);
 str_replace(dateBT, " ", "");
 Serial.read();

// save time
 memset(timeBT, 0, strlen(timeBT));
 Serial.readBytesUntil('|', timeBT, 20);
 Serial.read();

// save call notifications and parse number
 memset(callBT, 0, strlen(callBT));
 Serial.readBytesUntil('|', callBT, 20);
 str_replace(callBT, " ", "");
 str_replace(callBT, "(", "");
 str_replace(callBT, ")", "");
 str_replace(callBT, "-", "");
 if (strlen(callBT) == 11)
   str_remove(callBT, 0, 1);
 Serial.read();

// save text notifications and parse number
 memset(textBT, 0, strlen(textBT));
 Serial.readBytesUntil('\n', textBT, 20);
 str_replace(textBT, " ", "");
 str_replace(textBT, "(", "");
 str_replace(textBT, ")", "");
 str_replace(textBT, "-", "");
 if (strlen(textBT) == 11)
   str_remove(callBT, 0, 1);
 Serial.read();
}

void countSteps()
{
 // get current MPU status
 mpuIntStatus = mpu.getIntStatus(); // get INT_STATUS byte
 fifoCount = mpu.getFIFOCount(); // get current FIFO count

// check for DMP data ready interrupt
 if (mpuIntStatus & 0x02)
 {
   // wait untill enough data is available
   while (fifoCount < packetSize)
     fifoCount = mpu.getFIFOCount();

// read a packet from FIFO
   mpu.getFIFOBytes(fifoBuffer, packetSize);
   fifoCount -= packetSize; // track FIFO count tp determine if more data can be read

// get quaternion values
   mpu.dmpGetQuaternion(&q, fifoBuffer);
 }
 Serial.println(q.w*10);
 // update recent quaternion values
 currentQData[0] = currentQData[1];
 currentQData[1] = currentQData[2];
 currentQData[2] = q.w;
 // if a peak/max is found
 if(currentQData[1] > currentQData[0] && currentQData[1] > currentQData[2])
 {
   stepMax = currentQData[1];// update peak value      
   double maxMinDiff = stepMax - stepMin;
   // if a step is detected
   if (maxMinDiff > stepDiffMinThreshold)
   {
       stepCount++;
   }
 }
 // if a trough/min is found
 else if(currentQData[1] < currentQData[0] && currentQData[1] < currentQData[2])
 {
   stepMin = currentQData[1];
 }
}

void loop()
{
 // only read BT data if device is connected
 if (Serial.available() > 0)
 {
   readBTData();
   str_remove(timeBT, strlen(timeBT) - 6, 3); // remove seconds
   u8g2.firstPage();
   do {
     updateDisplay();
   } while ( u8g2.nextPage() );
 }

// wait for MPU interrupt to process steps
 if (mpuInterrupt || fifoCount > packetSize)
 {
   mpuInterrupt = false; // reset interrupt flag
   countSteps();
 }
}

I spotted this
this is the flaw of the old code. it slams the i2c bus until the FIFO count is met! ouch! nothing can be done until it completes and the data may still be corrupted once retrieved. several assumptions were made in the example code that didn't work quite right.

    // wait untill enough data is available
    while (fifoCount < packetSize)
      fifoCount = mpu.getFIFOCount();

Attaching file that may work... I don't have all your libraries but I did Quickly add your code to my example so you may be able to see how it might fit in.

MPU6050_ddesousa.ino (11.7 KB)

Great! Thanks for your help.

So to be clear, in terms of my code, what do I have to specifically change?

Daniel

ddesousa:
Great! Thanks for your help.

So to be clear, in terms of my code, what do I have to specifically change?

Daniel

If I were to focus on altering your code I would change at a minimum the following

The Change:
Your get DMP from FIFO Buffer code altered to use My capture sequence
Note that once data has become corrupt such as fifo buffer overrun the all the packets will have become corrupt because part of the first packet will be discarded. with no way of detecting the start of a packet we must trash everything. So either we can divide the number of packets by the packet size and have a remainder of Zero or we have corrupted data.

if ((!fifoCount) || (fifoCount % packetSize)) {

( We also must have something to work with. )

If this is true then we must wait till the next packet is received.
else we must have a good packet lets get it. now if for some unknown reason we skipped getting a few, loop through the fifo data till we get the latest (last) packet. You may want to calculate every packet. The modification wouldn't be difficult to handle, The other packets should have complete datasets. you could have up to 24 good packets 1024/42 = 24.38 packets

void countSteps()
{
  /*
  // get current MPU status
  mpuIntStatus = mpu.getIntStatus(); // get INT_STATUS byte
  fifoCount = mpu.getFIFOCount(); // get current FIFO count

  // check for DMP data ready interrupt
  if (mpuIntStatus & 0x02)
  {
    // wait untill enough data is available
    while (fifoCount < packetSize)
      fifoCount = mpu.getFIFOCount();

    // read a packet from FIFO
    mpu.getFIFOBytes(fifoBuffer, packetSize);
    fifoCount -= packetSize; // track FIFO count tp determine if more data can be read
    // get quaternion values
    mpu.dmpGetQuaternion(&q, fifoBuffer);
  }
*/

  fifoCount = mpu.getFIFOCount();
  if ((!fifoCount) || (fifoCount % packetSize)) { // we have failed Reset and wait till next time!
    mpu.resetFIFO();// clear the buffer and start over
    // return; // un-remark if you want to make it clear that we are bailing this routine here
  } else {
    while (fifoCount  >= packetSize) { // Get the packets until we have the latest!
      mpu.getFIFOBytes(fifoBuffer, packetSize); // lets do the magic and get the data
      fifoCount -= packetSize;
    }
    // get quaternion values
    mpu.dmpGetQuaternion(&q, fifoBuffer);
    Serial.println(q.w * 10);
    // update recent quaternion values
    currentQData[0] = currentQData[1];
    currentQData[1] = currentQData[2];
    currentQData[2] = q.w;
    // if a peak/max is found
    if (currentQData[1] > currentQData[0] && currentQData[1] > currentQData[2])
    {
      stepMax = currentQData[1];// update peak value
      double maxMinDiff = stepMax - stepMin;
      // if a step is detected
      if (maxMinDiff > stepDiffMinThreshold)
      {
        stepCount++;
      }
    }
    // if a trough/min is found
    else if (currentQData[1] < currentQData[0] && currentQData[1] < currentQData[2])
    {
      stepMin = currentQData[1];
    }
  }
}

and

// wait for MPU interrupt to process steps
//  if (mpuInterrupt || fifoCount > packetSize)
// we don't need to check the fifoCount a tone over the i2c buss thats why we have the interrupt
  if (mpuInterrupt )
  {
    mpuInterrupt = false; // reset interrupt flag
    countSteps();
  }

Z

Unfortunately, i already did that.

No, you didn't. That's in your code:

U8G2_SSD1306_128X64_NONAME_2_HW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);

that's mine:

U8G2_SSD1306_128X64_NONAME_2_HW_I2C u8g2(U8G2_R0);

Do you see the difference? If you specify the SCL/SDA pins, the will be set as OUTPUTs by the U2G2 code (I know it doesn't make sense but that's because of the highly modularized code). The default value for clock and data (which is used in my case) is U8X8_PIN_NONE and with this value the pins are not touched by pinMode().

Pylon, zhomeslize:

A combination of both of your advice has gotten it to work!!

Thank you so much.

It looks like the FIFO buffer was overflowing alot which was causing a mess on the I2Cbus.