Polling instead of interrupt for MPU6050 on GY521

i am an old guy keeping my brain alive with electronics. First coding on a CRC102a in 1955, director of academic computer center in about 1980, programming in C at work in 1992 and a fair amount of Arduino programming more recently.

Hope I'm in the right category. I am using a MPU6050 on a GY521 breakout board with a MEGA2560 R3 and the <MPU6050_light.h> library. It works just fine on a breadboard. Would like to transfer it to a PCB that I have ordered. Unfortunately I forgot to include the Interrupt trace on the PCB. MPU6050 by Electronic Cats on github has an update called MPU6050_6Axis_MotionApps_V6_12.h that does what I want but there is no "Download Zipfile" button on the page.

My question is: would it be easier to try to make a library out of this or just to bite the bullet and draw in the missing interrupt trace by hand on my PCB (the routing is not crowded.)

Thank you.

My Library Simple_MPU6050 can solve that
you will need Jeff's i2cdev library as I extend it with mine.

ZHomeSlice/Simple_MPU6050

The example is as follows:

/* ============================================
  I2Cdev device library code is placed under the MIT license
  Copyright (c) 2021 Homer Creutz
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:
  The above copyright notice and this permission notice shall be included in
  all copies or substantial portions of the Software.
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  THE SOFTWARE.
  ===============================================
*/

/*
 *  Use with any MPU: MPU6050, MPU6500, MPU9150, MPU9155, MPU9250 
 *  Attach the MPU to the I2C buss
 *  Power MPU According to specs of the breakout board. Generic Breakout Version Powers with 5V and has a onboard Voltage regulator.
 *  run the Sketch
 */

#include "Simple_MPU6050.h"
#define MPU6050_DEFAULT_ADDRESS     0x68 // address pin low (GND), default for InvenSense evaluation board

Simple_MPU6050 mpu;

//***************************************************************************************
//******************                Print Funcitons                **********************
//***************************************************************************************
//Gyro, Accel and Quaternion
int PrintAllValues(int16_t *gyro, int16_t *accel, int32_t *quat, uint16_t SpamDelay = 100) {
  Quaternion q;
  VectorFloat gravity;
  float ypr[3] = { 0, 0, 0 };
  float xyz[3] = { 0, 0, 0 };
  mpu.GetQuaternion(&q, quat);
  mpu.GetGravity(&gravity, &q);
  mpu.GetYawPitchRoll(ypr, &q, &gravity);
  mpu.ConvertToDegrees(ypr, xyz);
  Serial.print(F("Yaw "));   Serial.print(xyz[0]);   Serial.print(F(",   "));
  Serial.print(F("Pitch ")); Serial.print(xyz[1]);   Serial.print(F(",   "));
  Serial.print(F("Roll "));  Serial.print(xyz[2]);   Serial.print(F(",   "));
  Serial.print(F("ax "));    Serial.print(accel[0]); Serial.print(F(",   "));
  Serial.print(F("ay "));    Serial.print(accel[1]); Serial.print(F(",   "));
  Serial.print(F("az "));    Serial.print(accel[2]); Serial.print(F(",   "));
  Serial.print(F("gx "));    Serial.print(gyro[0]);  Serial.print(F(",   "));
  Serial.print(F("gy "));    Serial.print(gyro[1]);  Serial.print(F(",   "));
  Serial.print(F("gz "));    Serial.print(gyro[2]);  Serial.print(F("\n"));
  Serial.println();
}

//***************************************************************************************
//******************              Callback Funciton                **********************
//***************************************************************************************

// See mpu.on_FIFO(print_Values); in the Setup Loop
void print_Values (int16_t *gyro, int16_t *accel, int32_t *quat, uint32_t *timestamp) {
  uint8_t Spam_Delay = 100; // Built in Blink without delay timer preventing Serial.print SPAM
  PrintAllValues(gyro, accel, quat, Spam_Delay);
}

//***************************************************************************************
//******************                Setup and Loop                 **********************
//***************************************************************************************

void setup() {
  uint8_t val;
  // join I2C bus (I2Cdev library doesn't do this automatically)
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
  Wire.begin();
  Wire.setClock(400000); // 400kHz I2C clock. Comment this line if having compilation difficulties
#ifdef __AVR__  
  Wire.setWireTimeout(3000, true); //timeout value in uSec
#endif
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
  Fastwire::setup(400, true);
#endif
  // initialize serial communication
  Serial.begin(115200);
  while (!Serial); // wait for Leonardo enumeration, others continue immediately
  Serial.println(F("Start:"));

  // Setup the MPU
    mpu.Set_DMP_Output_Rate_Hz(10);           // Set the DMP output rate from 200Hz to 5 Minutes.
  //mpu.Set_DMP_Output_Rate_Seconds(10);   // Set the DMP output rate in Seconds
  //mpu.Set_DMP_Output_Rate_Minutes(5);    // Set the DMP output rate in Minute
  mpu.SetAddress(MPU6050_DEFAULT_ADDRESS); //Sets the address of the MPU.
  mpu.CalibrateMPU();                      // Calibrates the MPU.
  mpu.load_DMP_Image();                    // Loads the DMP image into the MPU and finish configuration.
  mpu.on_FIFO(print_Values);               // Set callback function that is triggered when FIFO Data is retrieved
  // Setup is complete!
  
}

void loop() {
  static unsigned long FIFO_DelayTimer;
  if ((millis() - FIFO_DelayTimer) >= (99)) { // 99ms insted of 100ms to start polling the MPU 1ms prior to data arriving.
    if( mpu.dmp_read_fifo(false)) FIFO_DelayTimer= millis() ; // false = no interrupt pin attachment required and When data arrives in the FIFO Buffer reset the timer
  }
  // dmp_read_fifo(false) does the following
  // Tests for Data in the FIFO Buffer
  // when it finds data it runs the mpu.on_FIFO(print_Values)
  // the print_Values functin which we set run the PrintAllValues Function
  // When data is caputred dmp_read_fifo will return true.
  // The print_Values function MUST have the following variables available to attach data
  // void print_Values (int16_t *gyro, int16_t *accel, int32_t *quat, uint32_t *timestamp)
  // Variables:
  // int16_t *gyro for the gyro values to be passed to it (The * tells the function it will be a pointer to the value)
  // int16_t *accel for the accel values to be passed to it
  // int32_t *quat for the quaternion values to be passed to it
  // uint32_t *timestamp which will be the micros()value at the time we retrieved the Newest value from the FIFO Buffer.
}

I have the embedded DMP firmware set to add a quaternion packet to the FIFO buffer every 100ms this can be adjusted to as little as 5ms but everyone is used to 10ms using Jeff's MPU6050 library.
mpu.Set_DMP_Output_Rate_Hz(10); // Set the DMP output rate from 200Hz to 5 Minutes.
if you change this you will need to change the blink without delay routine to almost match

  static unsigned long FIFO_DelayTimer;
  if ((millis() - FIFO_DelayTimer) >= (99)) { // 99ms insted of 100ms to start polling the MPU 1ms prior to data arriving.
    if( mpu.dmp_read_fifo(false)) FIFO_DelayTimer= millis() ; // false = no interrupt pin attachment required and When data arrives in the FIFO Buffer reset the timer

you could also just poll the buffer continuously but the i2c consumes a lot of time.

also, note that the dmp_read_fifo function will clear the FIFO buffer and retrieve the next packet if it deems that emptying the buffer will take longer than waiting or if the buffer is likely corrupted and doesn't have a valid packet caused by overflow.

once a packet is retrieved the following occurs:
because you set this callback function here: mpu.on_FIFO(print_Values); // Set callback function that is triggered when FIFO Data is retrieved
the print_Values callback function is run once a valid packet is retrieved.
the callback function is required to have the following values
void print_Values (int16_t *gyro, int16_t *accel, int32_t *quat, uint32_t *timestamp) {
//*gyro pointer to the gyro[3] array with 3 values
//*accel pointer to the accel[3] array with 3 values
//*quat pointer to the quaterniun[4] array with 4 values
// timestamp as to when the values were retrieved.

//Put your code here
}
Let me know if this will work.
Z

Thank you, Z, for the quick response.
Took me a while to find my way around github but managed to download the needed libraries.
Now I am having trouble with a bunch of compile errors. I copied the code from your email and made some minor changes and commented some things out. Here is the code as it is now:

// filename:    Homer_Creutz_code_edited_v00
// date:        20 Aug 2022
// edited by:   Hrolf
/* ============================================
  I2Cdev device library code is placed under the MIT license
  Copyright (c) 2021 Homer Creutz
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:
  The above copyright notice and this permission notice shall be included in
  all copies or substantial portions of the Software.
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  THE SOFTWARE.
  ===============================================
*/

/*
    Use with any MPU: MPU6050, MPU6500, MPU9150, MPU9155, MPU9250
    Attach the MPU to the I2C buss
    Power MPU According to specs of the breakout board. Generic Breakout Version Powers with 5V and has a onboard Voltage regulator.
    run the Sketch
*/
#include <Wire.h>
#include <I2Cdev.h>
#include "Simple_MPU6050.h"

#define MPU6050_DEFAULT_ADDRESS     0x68 // address pin low (GND), default for InvenSense evaluation board

Simple_MPU6050 mpu;

//***************************************************************************************
//******************                Print Functions                **********************
//***************************************************************************************
//Gyro, Accel and Quaternion

void PrintAllValues(int16_t *gyro, int16_t *accel, int32_t *quat, uint16_t SpamDelay = 100)
// made this void instead of int, Hrolf
{
  Quaternion q;
  VectorFloat gravity;
  float ypr[3] = { 0, 0, 0 };
  float xyz[3] = { 0, 0, 0 };
  mpu.GetQuaternion(&q, quat);
  mpu.GetGravity(&gravity, &q);
  mpu.GetYawPitchRoll(ypr, &q, &gravity);
  mpu.ConvertToDegrees(ypr, xyz);
  Serial.print(F("Yaw "));   Serial.print(xyz[0]);   Serial.print(F(",   "));
  Serial.print(F("Pitch ")); Serial.print(xyz[1]);   Serial.print(F(",   "));
  Serial.print(F("Roll "));  Serial.print(xyz[2]);   Serial.print(F(",   "));
  Serial.print(F("ax "));    Serial.print(accel[0]); Serial.print(F(",   "));
  Serial.print(F("ay "));    Serial.print(accel[1]); Serial.print(F(",   "));
  Serial.print(F("az "));    Serial.print(accel[2]); Serial.print(F(",   "));
  Serial.print(F("gx "));    Serial.print(gyro[0]);  Serial.print(F(",   "));
  Serial.print(F("gy "));    Serial.print(gyro[1]);  Serial.print(F(",   "));
  Serial.print(F("gz "));    Serial.print(gyro[2]);  Serial.print(F("\n"));
  Serial.println();
  return; // added by Hrolf
}

//***************************************************************************************
//******************              Callback Function                **********************
//***************************************************************************************

// See mpu.on_FIFO(print_Values); in the Setup Loop
void print_Values (int16_t *gyro, int16_t *accel, int32_t *quat, uint32_t *timestamp)
{
  uint8_t Spam_Delay = 100; // Built in Blink without delay timer preventing Serial.print SPAM
  PrintAllValues(gyro, accel, quat, Spam_Delay);
}

//***************************************************************************************
//******************                Setup and Loop                 **********************
//***************************************************************************************

void setup()
{
  uint8_t val;
  // join I2C bus (I2Cdev library doesn't do this automatically)
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
  Wire.begin();
  //Wire.setClock(400000); // 400kHz I2C clock. Comment this line if having compilation difficulties
#ifdef __AVR__
  Wire.setTimeout(3000); //timeout value in uSec
#endif
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
  Fastwire::setup(400, true);
#endif
  // initialize serial communication
  Serial.begin(115200);
  while (!Serial); // wait for Leonardo enumeration, others continue immediately
  Serial.println(F("Start:"));

  // Setup the MPU
  mpu.Set_DMP_Output_Rate_Hz(10);           // Set the DMP output rate from 200Hz to 5 Minutes.
  //mpu.Set_DMP_Output_Rate_Seconds(10);   // Set the DMP output rate in Seconds
  //mpu.Set_DMP_Output_Rate_Minutes(5);    // Set the DMP output rate in Minute
  mpu.SetAddress(MPU6050_DEFAULT_ADDRESS); //Sets the address of the MPU.
  mpu.CalibrateMPU();                      // Calibrates the MPU.
  mpu.load_DMP_Image();                    // Loads the DMP image into the MPU and finish configuration.
  mpu.on_FIFO(print_Values);               // Set callback function that is triggered when FIFO Data is retrieved
  // Setup is complete!

}

void loop()
{
  static unsigned long FIFO_DelayTimer;
  if ((millis() - FIFO_DelayTimer) >= (99))
  { // 99ms insted of 100ms to start polling the MPU 1ms prior to data arriving.
    if ( mpu.dmp_read_fifo(false)) FIFO_DelayTimer = millis() ; // false = no interrupt pin attachment required and When data arrives in the FIFO Buffer reset the timer
  }
  // dmp_read_fifo(false) does the following
  // Tests for Data in the FIFO Buffer
  // when it finds data it runs the mpu.on_FIFO(print_Values)
  // the print_Values function which we set run the PrintAllValues Function
  // When data is captured dmp_read_fifo will return true.
  // The print_Values function MUST have the following variables available to attach data
  // void print_Values (int16_t *gyro, int16_t *accel, int32_t *quat, uint32_t *timestamp)
  // Variables:
  // int16_t *gyro for the gyro values to be passed to it (The * tells the function it will be a pointer to the value)
  // int16_t *accel for the accel values to be passed to it
  // int32_t *quat for the quaternion values to be passed to it
  // uint32_t *timestamp which will be the micros()value at the time we retrieved the Newest value from the FIFO Buffer.
}

//I have the embedded DMP firmware set to add a quaternion packet to the FIFO buffer every 100ms this can be adjusted to as little as 5ms but everyone is used to 10ms using Jeff's MPU6050 library.
//mpu.Set_DMP_Output_Rate_Hz(10); // Set the DMP output rate from 200Hz to 5 Minutes.
//if you change this you will need to change the blink without delay routine to almost match
//
//static unsigned long FIFO_DelayTimer;
//if ((millis() - FIFO_DelayTimer) >= (99)) { // 99ms insted of 100ms to start polling the MPU 1ms prior to data arriving.
//if( mpu.dmp_read_fifo(false)) FIFO_DelayTimer= millis() ; // false = no interrupt pin attachment required and When data arrives in the FIFO Buffer reset the timer
//
//you could also just poll the buffer continuously but the i2c consumes a lot of time.
//
//also, note that the dmp_read_fifo function will clear the FIFO buffer and retrieve the next packet if it deems that emptying the buffer will take longer than waiting or if the buffer is likely corrupted and doesn't have a valid packet caused by overflow.
//
//once a packet is retrieved the following occurs:
//because you set this callback function here: mpu.on_FIFO(print_Values); // Set callback function that is triggered when FIFO Data is retrieved
//the print_Values callback function is run once a valid packet is retrieved.
//the callback function is required to have the following values
//void print_Values (int16_t *gyro, int16_t *accel, int32_t *quat, uint32_t *timestamp) {
//  //*gyro pointer to the gyro[3] array with 3 values
//  //*accel pointer to the accel[3] array with 3 values
//  //*quat pointer to the quaterniun[4] array with 4 values
//  // timestamp as to when the values were retrieved.
//
//  //Put your code here
//}

and here are the compiler errors:

Arduino: 1.8.10 (Windows 10), Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"

C:\My Elegoo Dir\Homer_Creutz_code_edited_v00\Homer_Creutz_code_edited_v00.ino: In function 'void PrintAllValues(int16_t*, int16_t*, int32_t*, uint16_t)':

C:\My Elegoo Dir\Homer_Creutz_code_edited_v00\Homer_Creutz_code_edited_v00.ino:44:88: warning: unused parameter 'SpamDelay' [-Wunused-parameter]

 void PrintAllValues(int16_t *gyro, int16_t *accel, int32_t *quat, uint16_t SpamDelay = 100)

                                                                                        ^~~

C:\My Elegoo Dir\Homer_Creutz_code_edited_v00\Homer_Creutz_code_edited_v00.ino: In function 'void print_Values(int16_t*, int16_t*, int32_t*, uint32_t*)':

C:\My Elegoo Dir\Homer_Creutz_code_edited_v00\Homer_Creutz_code_edited_v00.ino:73:76: warning: unused parameter 'timestamp' [-Wunused-parameter]

 void print_Values (int16_t *gyro, int16_t *accel, int32_t *quat, uint32_t *timestamp)

                                                                            ^~~~~~~~~

C:\My Elegoo Dir\Homer_Creutz_code_edited_v00\Homer_Creutz_code_edited_v00.ino: In function 'void setup()':

C:\My Elegoo Dir\Homer_Creutz_code_edited_v00\Homer_Creutz_code_edited_v00.ino:85:11: warning: unused variable 'val' [-Wunused-variable]

   uint8_t val;

           ^~~

C:\Program Files (x86)\Arduino\libraries\Simple_MPU6050\Simple_MPU6050.cpp: In member function 'int8_t Simple_MPU6050::GetCurrentFIFOPacket(uint8_t*, uint8_t)':

C:\Program Files (x86)\Arduino\libraries\Simple_MPU6050\Simple_MPU6050.cpp:208:32: error: 'I2CDEVLIB_WIRE_BUFFER_LENGTH' was not declared in this scope

                  uint8_t Trash[I2CDEVLIB_WIRE_BUFFER_LENGTH];

                                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~

In file included from C:\Program Files (x86)\Arduino\libraries\Simple_MPU6050\Simple_MPU6050.h:31:0,

                 from C:\Program Files (x86)\Arduino\libraries\Simple_MPU6050\Simple_MPU6050.cpp:28:

C:\Program Files (x86)\Arduino\libraries\Simple_MPU6050\Simple_MPU6050.cpp:215:40: error: 'Trash' was not declared in this scope

        FIFO_READ((uint8_t)RemoveBytes, Trash);

                                        ^

C:\Program Files (x86)\Arduino\libraries\Simple_MPU6050\MPU_ReadMacros.h:304:91: note: in definition of macro 'FIFO_READ'

 #define FIFO_READ(PacketLength, Data)      MPUi2cReadBytes(0x74, PacketLength, (uint8_t *)Data)  //   Read/Write command provides Read or Write operation for the FIFO.

                                                                                           ^~~~

C:\Program Files (x86)\Arduino\libraries\Simple_MPU6050\Simple_MPU6050.cpp: In member function 'Simple_MPU6050& Simple_MPU6050::load_DMP_Image(int16_t, int16_t, int16_t, int16_t, int16_t, int16_t, int8_t)':

C:\Program Files (x86)\Arduino\libraries\Simple_MPU6050\Simple_MPU6050.cpp:411:133: warning: unused parameter 'Calibrate' [-Wunused-parameter]

 Simple_MPU6050 & Simple_MPU6050::load_DMP_Image(int16_t ax_, int16_t ay_, int16_t az_, int16_t gx_, int16_t gy_, int16_t gz_,int8_t Calibrate) {

                                                                                                                                     ^~~~~~~~~

C:\Program Files (x86)\Arduino\libraries\Simple_MPU6050\Simple_MPU6050.cpp: In member function 'Simple_MPU6050& Simple_MPU6050::load_firmware(uint16_t, const uint8_t*)':

C:\Program Files (x86)\Arduino\libraries\Simple_MPU6050\Simple_MPU6050.cpp:536:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]

   for ( x = 0; x < this_write; x++ ) firmware_chunk[x] = pgm_read_byte_near(pFirmware + x);

                ~~^~~~~~~~~~~~

Multiple libraries were found for "Wire.h"
 Used: C:\Program
Multiple libraries were found for "I2Cdev.h"
 Used: C:\My
Multiple libraries were found for "Simple_MPU6050.h"
 Used: C:\Program
exit status 1
Error compiling for board Arduino/Genuino Mega or Mega 2560.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

Hello,

It depends entirely on your situation.
If polling suits you for various reasons/you can live with the drawbacks (obviously this wouldn't work well on a battery operated device), you can of course do this.
May I suggest instead of drawing the trace by hand (I assume by that you mean using conductive silver paint), to use enameled wire for that?
Specifically for these fixups but also repair jobs in general I do have some 0.2mm enameled copper wire plus UV curing solder mask. You get both for around 15$ in total. You could get a uv light as well (use at least sunglasses then and look away, it takes less than 5 minutes to cure it that way), or just put the mask in the sun for about 4 hours (depending on mask thickness).

Welcome to the forum.

@jremington has a simple solution: put the elapsed time into the calculation: https://github.com/jremington/MPU-6050-Fusion. No special timing needed.

I'm not very fond of the I2Cdev library (that is a understatement).

You should be careful when connecting a 5V I2C bus to a 3.3V I2C bus.
The Arduino Mega has 10k pullup resistors to 5V. A current can flow via those resistors into the SDA and SCL pin of the MPU-6050, that is not allowed. It is also possibly that the entire sensor voltage is lifted and damages it.

To Fix
C:\Program Files (x86)\Arduino\libraries\Simple_MPU6050\Simple_MPU6050.cpp: In member function 'int8_t Simple_MPU6050::GetCurrentFIFOPacket(uint8_t*, uint8_t)':
C:\Program Files (x86)\Arduino\libraries\Simple_MPU6050\Simple_MPU6050.cpp:208:32: error: 'I2CDEVLIB_WIRE_BUFFER_LENGTH' was not declared in this scope uint8_t Trash[I2CDEVLIB_WIRE_BUFFER_LENGTH];

prior to including my library add:
#define I2CDEVLIB_WIRE_BUFFER_LENGTH 32

to fix:
Multiple libraries were found for "Wire.h" Used: C:\Program Multiple libraries were found for "I2Cdev.h" Used: C:\My Multiple libraries were found for "Simple_MPU6050.h" Used: C:\Program

Check to see if you have multiple copies of these libraries in yout library folder the compiler is not understanding which one it should use.

you will want to download the latest libraries from jeff and I just updated my library to help remove some of the warnings

so you will want to download mine again.

I further simplified the code and also checked for errors none arose:
I am looking into an error that is almost irrelevant I am determining what to do about it but I will give you this now and attempt to resolve it as I go.

Z

https://github.com/ZHomeSlice/Simple_MPU6050/blob/master/Examples/Simple_MPU6050_Basic_Example/Simple_MPU6050_Basic_Example.ino

This may help explain what is going on.

Note that the breakout board has pullup resistors attached to the 3.3V supply for you no additional pullup resistors are required

The Arduino Mega is the only board with 10k pullup to 5V for SDA and SCL.
I'm not convinced that the module is according to that schematic.
A Arduino Mega or Uno needs 3.5V at SDA and SCL to see it as a logic high. A pullup to 3.3V can not give that. It will work, but the noise margin became a negative number.

Is a level shifter required between MPU6050 and MEGA as the SDA and SCL lines are of 3.3V logic?

The voltage divided between the 10K and the 4.7 k may not raise the i2c bus voltage substantial enough to harm the mpu6050 I've had no problems using 3.3 volts on the UNO i2c bus. you will likely have no problems.
The i2c communicates by pulling the line to ground.

Z

Is this true when looking at the following Table where VIH = 3.0V?
electricalCharIO

You are right very likely as per following calculation.
V at SDL/SCL point = (5-3.3/(10k + 4.7k))x4.7k + 3.3V ~=3.8V.

Couldn't find where the extra copies of libraries are hiding using Windows search. It shouldn't make any difference anyway if the compiler is smart enough to use the latest and greatest.
Still get a few compiler errors but none fatal so I uploaded to my Mega2560 and ran the code. Result was that it gets caught in an endless loop when trying to calibrate the MPU. Here are the compiler errors:

C:\My Elegoo Dir\Homer_Creutz_code_edited_v02\Homer_Creutz_code_edited_v02.ino: In function 'void setup()':

C:\My Elegoo Dir\Homer_Creutz_code_edited_v02\Homer_Creutz_code_edited_v02.ino:96:27: warning: invalid conversion from 'void (*)(int16_t*, int16_t*, int32_t*) {aka void (*)(int*, int*, long int*)}' to 'void (*)(int16_t*, int16_t*, int32_t*, uint32_t*) {aka void (*)(int*, int*, long int*, long unsigned int*)}' [-fpermissive]

   mpu.on_FIFO(print_Values);               // Set callback function that is triggered when FIFO Data is retrieved

                           ^

In file included from C:\My Elegoo Dir\Homer_Creutz_code_edited_v02\Homer_Creutz_code_edited_v02.ino:35:0:

C:\Program Files (x86)\Arduino\libraries\Simple_MPU6050/Simple_MPU6050.h:154:22: note:   initializing argument 1 of 'Simple_MPU6050& Simple_MPU6050::on_FIFO(void (*)(int16_t*, int16_t*, int32_t*, uint32_t*))'

     Simple_MPU6050 & on_FIFO(void (*CB)(int16_t *, int16_t *, int32_t *, uint32_t *));

                      ^~~~~~~

Thank you
Hrolf

Hi,
Thanks for your reply. I have lots of enameled magnet wire so that is not an issue. However, I have always found it hard to remove enough enamel to get good solderability. About the only thing that works is to scrape and scrape with a knife blade.

I have a 0.1mm enameled wire of which it is very difficult for me to get the coating off. I feel like there is some difference with the coatings. I can't rule out user error but I wouldn't give up on trying!

Make some major changes to the Simple_MPU6050 library. I've fixed most if not all the warnings.
I've also changed to my Simple_Wire library and veered away from Jeff's i2cdev library.
I'm curious if you can compile this to work with your board now.
Re-download it and Check it out:
ZHomeSlice/Simple_MPU6050

Z

@zhomeslice A Wire.requestFrom() should not have Wire.beginTransmission() and Wire.endTransmission() around it :bug: You can remove those.
I call those common mistake #2 and common mistake #3.

You inherit your Simple_Wire from TwoWire, but the Stream class on top of TwoWire has also a function called readBytes(): Stream.readBytes() - Arduino Reference
Your function name "ReadBytes()" might be confusing (although I seen no problem with it).

A repeated start between setting the register address and reading the register data is often used for the MPU-6050.

A little background information:
The Stream::readBytes() has a timeout, because it is not meant for I2C. That is weird, and there is no nice solution for it. Image using the Stream::readBytes() as a Wire.readBytes() inside a interrupt in Slave mode. When something is wrong, the timeout will crash the Arduino :man_facepalming:

The undocumented extra long Wire.requestFrom() is useful and does work and is likely to stay in the library, but it remains undocumented :man_facepalming:

I call those common mistake #2 and common mistake #3.
Fixed and works great!!!
Thanks!

ReadBytes() vs Stream::readBytes()
Dang I've created several macros that use ReadBytes()
example:
#define FIFO_READ(PacketLength, Data) ReadBytes(0x74, PacketLength, (uint8_t *)Data) // Read/Write command provides Read or Write operation for the FIFO.
The idea is to create a large number of macros that do exactly what they describe.
example:

#define PWR_MGMT_1_READ(Data)                               ReadByte(0x6B, (uint8_t *)Data)  //  Read PWR_MGMT_1 
#define PWR_MGMT_1_READ_H_RESET(Data)                       ReadBit(0x6B, 1, 7, (uint8_t *)Data)  //   1   Reset the internal registers and restores the default settings. Write a 1 to set the reset, the bit will auto clear.
#define PWR_MGMT_1_READ_SLEEP(Data)                         ReadBit(0x6B, 1, 6, (uint8_t *)Data)  //   When set, the chip is set to sleep mode (After OTP loads, the PU_SLEEP_MODE bit will be written here)
#define PWR_MGMT_1_READ_CYCLE(Data)                         ReadBit(0x6B, 1, 5, (uint8_t *)Data)  //   When set, and SLEEP and STANDBY are not set, the chip will cycle between sleep and taking a single sample at a rate determined by LP_ACCEL_ODR register
#define PWR_MGMT_1_READ_GYRO_STANDBY(Data)                  ReadBit(0x6B, 1, 4, (uint8_t *)Data)  //   When set, the gyro drive and pll circuitry are enabled, but the sense paths are disabled. This is a low power mode that allows quick enabling of the gyros.
#define PWR_MGMT_1_READ_PD_PTAT(Data)                       ReadBit(0x6B, 1, 3, (uint8_t *)Data)  //   Power down internal PTAT voltage generator and PTAT ADC
#define PWR_MGMT_1_READ_CLKSEL(Data)                        ReadBit(0x6B, 3, 2, (uint8_t *)Data)  //   Clock Source Select

Each of these would have been a function now they are a single line macro using the product registry map for the names of the macros.

Since my goal is to somewhat hide all other functions behind the Simple_Wire class but let them be available if they are ever needed I'm not going to change ReadBytes for now even though it could be confusing if readBytes were to resurface.

Thanks again for all the information Defiantly saving your post for future reference!!!
Z

Using your "example" code, I get the following compile errors:

Arduino: 1.8.10 (Windows 10), Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"

C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c: In function '__vector_39':

C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:447:49: warning: this statement may fall through [-Wimplicit-fallthrough=]

       twi_masterBuffer[twi_masterBufferIndex++] = TWDR;

                                                 ^

C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:448:5: note: here

     case TW_MR_SLA_ACK:  // address sent, ack received

     ^~~~

C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:529:9: warning: this statement may fall through [-Wimplicit-fallthrough=]

       if(0 == twi_txBufferLength){

         ^

C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c:534:5: note: here

     case TW_ST_DATA_ACK: // byte sent, ack returned

     ^~~~

C:\Program Files (x86)\Arduino\libraries\Simple_MPU6050\Simple_MPU6050.cpp: In constructor 'Simple_MPU6050::Simple_MPU6050(uint8_t)':

C:\Program Files (x86)\Arduino\libraries\Simple_MPU6050\Simple_MPU6050.cpp:55:5: error: 'setWireTimeout' was not declared in this scope

     setWireTimeout(3000, true); //timeout value in uSec

     ^~~~~~~~~~~~~~

C:\Program Files (x86)\Arduino\libraries\Simple_MPU6050\Simple_MPU6050.cpp:55:5: note: suggested alternative: 'setTimeout'

     setWireTimeout(3000, true); //timeout value in uSec

     ^~~~~~~~~~~~~~

     setTimeout

C:\Program Files (x86)\Arduino\libraries\Simple_MPU6050\Simple_MPU6050.cpp: In member function 'Simple_MPU6050& Simple_MPU6050::AKM_Init()':

C:\Program Files (x86)\Arduino\libraries\Simple_MPU6050\Simple_MPU6050.cpp:859:21: error: 'magmagcalMPU' was not declared in this scope

  if(!ReadSuccess()){magmagcalMPU

                     ^~~~~~~~~~~~

C:\Program Files (x86)\Arduino\libraries\Simple_MPU6050\Simple_MPU6050.cpp:859:21: note: suggested alternative: 'magcalMPU'

  if(!ReadSuccess()){magmagcalMPU

                     ^~~~~~~~~~~~

                     magcalMPU

In file included from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:28:0,

                 from C:\Program Files (x86)\Arduino\libraries\Simple_MPU6050\Simple_MPU6050.cpp:24:

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/WString.h:38:74: error: expected primary-expression before ')' token

 #define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))

                                                                          ^

C:\Program Files (x86)\Arduino\libraries\Simple_MPU6050\Simple_MPU6050.cpp:860:16: note: in expansion of macro 'F'

   Serial.print(F("Failed to Find Magnetometer"));

                ^

Multiple libraries were found for "Simple_Wire.h"
 Used: C:\Program
 Not used: C:\Program
Multiple libraries were found for "Wire.h"
 Used: C:\Program
Multiple libraries were found for "Simple_MPU6050.h"
 Used: C:\Program
 Not used: C:\Program
exit status 1
Error compiling for board Arduino/Genuino Mega or Mega 2560.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

Hrolf

I haven't tried it myself, but some people use a solder pot to tin wire ends. Don't know if it would work with your O.1 mm enameled magnet wire. I haven't had much luck burning off the enamel with a tinned soldering iron.
Hrolf