Page 1 of 1
Forum

Welcome to the Tweaking4All community forums!
When participating, please keep theĀ Forum RulesĀ in mind!

Topics for particular software or systems: Start your topic link with the name of the application or system.
For exampleĀ “MacOS X – Your question“, or “MS Word – Your Tip or Trick“.

Please note that switching to another language when reading a post willĀ not bring you to the same post, in Dutch, as there is no translation for that post!



problem using MPU-6...
 
Share:
Notifications
Clear all

[Solved] problem using MPU-6050 Accel/Gyro with ESP32

98 Posts
3 Users
3 Reactions
29.8 K Views
 tvr4
(@tvr4)
Estimable Member
Joined: 5 years ago
Posts: 122
Topic starter  

You may be right.Ā  Interesting post and it sounds very similar to the issue I have.

Unfortunately the developer has not responded on their gihhub page
https://github.com/ElectronicCats/mpu6050

I did post an issue about 4 days ago but no reply.
If another library is the answer I will do that.Ā  But I used the Electronic Cats library because it supported the ESP32


   
ReplyQuote
 tvr4
(@tvr4)
Estimable Member
Joined: 5 years ago
Posts: 122
Topic starter  

I received a reply this morning.Ā  It is what I though the problem was related to.Ā  But the additional info and link will be very helpful

"You may have more luck askingĀ here

Here is the description of the function you are using, so if you empty the FIFO buffer it will return 0 and you will be stucked in your while loop.

`// FIFO_COUNT* registers

/** Get current FIFO buffer size.

  • This value indicates the number of bytes stored in the FIFO buffer. This
  • number is in turn the number of bytes that can be read from the FIFO buffer
  • and it is directly proportional to the number of samples available given the
  • set of sensor data bound to be stored in the FIFO (register 35 and 36).
  • @returnĀ Current FIFO buffer size
    */
    uint16_t MPU6050::getFIFOCount() {
    I2Cdev::readBytes(devAddr, MPU6050_RA_FIFO_COUNTH, 2, buffer);
    return (((uint16_t)buffer[0]) << 8) | buffer[1];
    }`"

   
ReplyQuote
 tvr4
(@tvr4)
Estimable Member
Joined: 5 years ago
Posts: 122
Topic starter  

Got now where with the library developer.Ā  I received a message from Electronic Cats and all they did was quote the library function and suggest I contact the developer of the original library.Ā 

Here is the message from Electronic Cats"

"You may have more luck asking here

Here is the description of the function you are using, so if you empty the FIFO buffer it will return 0 and you will be stuck in your while loop.

`// FIFO_COUNT* registers

/** Get current FIFO buffer size.

  • This value indicates the number of bytes stored in the FIFO buffer. This
  • number is in turn the number of bytes that can be read from the FIFO buffer
  • and it is directly proportional to the number of samples available given the
  • set of sensor data bound to be stored in the FIFO (register 35 and 36).
  • @return Current FIFO buffer size
    */
    uint16_t MPU6050::getFIFOCount() {
    I2Cdev::readBytes(devAddr, MPU6050_RA_FIFO_COUNTH, 2, buffer);
    return (((uint16_t)buffer[0]) << 8) | buffer[1];
    }`"

I then posted an issue on the github page they recommended and that went nowhere.Ā  All they did was say the library code was flawed but offered nothing to suggest how to fix it.Ā 
Here is that response:
"

The code your referencing is flawed

This attached version gets the latest FIFO packed in the most efficient way possible. This can be spammed to get the packed when it becomes available so you can ignore interrupts (if you don't need the extra processing time). it also handles overflow etc.

Copied from: MPU6050.cpp line 2744 ~2782

/** Get latest byte from FIFO buffer no matter how much time has passed.
 * ===                  GetCurrentFIFOPacket                    ===
 * ================================================================
 * Returns 1) when nothing special was done
 *         2) when recovering from overflow
 *         0) when no valid data is available
 * ================================================================ */
 int8_t MPU6050::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 = 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
                 resetFIFO(); // Fixes any overflow corruption
                 fifoC = 0;
                 while (!(fifoC = 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 = 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); // Buffer Length is different than the packet length this will efficiently clear the buffer
                         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);
     getFIFOBytes(data, length); //Get 1 packet
     return 1;
} 
"

   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 12 years ago
Posts: 2864
 

That's just "great" ... so they basically leave you with flawed code and do not want to help? 😞Ā 

Does the code "Copied from: MPU6050.cpp line 2744 ~2782" work?


   
ReplyQuote
 tvr4
(@tvr4)
Estimable Member
Joined: 5 years ago
Posts: 122
Topic starter  

@hans

Absolutely correct.Ā  They have yet to answer

I did try the supposed good code and it generated more errors during compile than I have ever seen.Ā Ā 


   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 12 years ago
Posts: 2864
 

Alright so we're screwed on that one.

What you could consider, after reading a packet of data: Fully reset the MPU. There may be a hard reset and a soft reset of the MPU (not: fifo reset).
Not sure how fast that will go though and I'm not sure if the calibration steps are needed, and I'd try a soft reset first.
I did find this "reset" function for the library you're using (it says to add a 50ms delay).
Or maybe this way (source);

mpu.initialize();

This is what I ended up doing with the cheap Ethernet shield ... but in the end, I stopped using it all together since the ESP8266 offered a solid WiFi.
In the end this may not be optimal of course ... then again; it may work just fine.


   
ReplyQuote
 tvr4
(@tvr4)
Estimable Member
Joined: 5 years ago
Posts: 122
Topic starter  

You can't use the mpu.initialize since it would cause you to loose all offsets.Ā  The initialize does not just startup the MPU it also spends a few seconds to test and generate offsets.Ā  This would not be possible during the main loop execution.Ā 


   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 12 years ago
Posts: 2864
 

I was already afraid that would be the case 😞Ā 

Does the same go for the "reset()" function?

Or maybe a something like toggling "setFIFOEnabled()"? (setFIFOEnabled(false); setFIFOEnabled(true);)
Or play with some of the fifo related functions? (I'm honestly just guessing right now)


   
ReplyQuote
 tvr4
(@tvr4)
Estimable Member
Joined: 5 years ago
Posts: 122
Topic starter  

I am not familiar with the reset function.Ā  But toggling the FIFO enabled is interesting.

Unfortunately the people who wrote the libraries do not seem to want to reply or support their code.Ā  I am learning more each time I tinker with something.Ā  But I am not there yet and have never dug into a library code.

When this issue first started I contacted the MPU6050 manufacturer to get some insight into how to properly read the FIFO.Ā  They also never replied


   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 12 years ago
Posts: 2864
 

It is indeed unfortunate that you're left with a not quite OK working library and no support.
I do understand that some developers abandon their products, but I would have expected to have at least one person respond 😞Ā 
I had the same experience with thatcheapp Ethernet shield.

Unfortunately, I do not have an MPU 6050 so I cannot do any experiments, but I'd most certainly would try a few of these documented functions.Ā 
You just may get lucky (fingers crossed!).


   
ReplyQuote
 tvr4
(@tvr4)
Estimable Member
Joined: 5 years ago
Posts: 122
Topic starter  

Very interesting resource !

I will definitely investigate furtherĀ 

I will let you know how it goes

Thanks


   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 12 years ago
Posts: 2864
 

Cool! Fingers crossed! 👍Ā 


   
ReplyQuote
 tvr4
(@tvr4)
Estimable Member
Joined: 5 years ago
Posts: 122
Topic starter  

I received a reply today but I amĀ  not sure how to apply it.Ā  The function they quoted is based on the MPU6050 library by jrowberg (I was using the lib by Electronic Cats which is based on the jrowberg library)

The poster was helpful and even posted an example.Ā  However I may need to recode the sketch to use the different library.Ā 
It may take some work but If it works, hey why not.

The deciding issue will be if the jrowberg library is compatible with the ESP32.Ā  I posted a reply and advise what the response is.

Here is the post:

"I am not using an interrupt but am confused when you mentioned "This can be spammed to get the packed when it becomes available""
without interrupts, you will need to manage overflow, and depending upon your sequence manage no data.

This is a simplified summery of what is going on:

  do {
         if ((fifoC = getFIFOCount())  > length) { // this gets the fifo count and checks to see if we have more than 1 packet
... clean up the extra data and or fix the overflow coruption
         }
         if (!fifoC) return 0; // Called too early no data or we timed out after FIFO Reset
         // We (should) have 1 packet
     } while (fifoC != length); // proof our assumption
     getFIFOBytes(data, length); //Get 1 packet
     return 1;

because we check for a packet here
if (!fifoC) return 0; // Called too early no data or we timed out after FIFO Reset
we return 0 (zero) allowing your code to do something else if you get zero from this function you can just ask it again and again until you get a 1(one) as a return and now you have 1 packet of data loaded ready to process.

I believe you will find this simple.
This function "GetCurrentFIFOPacket" is located in the MPU6050.cpp library you are referencing here.
The latest example code uses it. if you haven't downloaded all the updates and fixed that have occurred on this library you might want to do that first to avoid errors.

Added function to your code you provided above

//BEGIN MPU6050 Code
// Replace with this until you arrive at your code below.
if(mpu.GetCurrentFIFOPacket(fifoBuffer, packetSize) ){// gets the latest packet if available and runs your code else this will skips your code because there is nothing new to process.

// YOUR CODE
     // display quaternion values x y z
        mpu.dmpGetQuaternion(&q, fifoBuffer);
        //USE THIS FOR LIVE ACCEL DATA DISPLAY
        Serial.print("G-Force\t");
        //Serial.print(q.w);
        //Serial.print("\t");
        Serial.print(q.x);
        Serial.print("\t");
        Serial.print(q.y);
        Serial.print("\t");
        Serial.println(q.z);

        //calculate Max Accel X,Y,Z
         if (abs(q.x) > abs(MaxGx))
          {
            MaxGx = q.x;
          }
         else
          {
            MaxGx = MaxGx;
          }

        if (abs(q.y) > abs(MaxGy))
          {
            MaxGy = q.y;
          }
         else
          {
            MaxGy = MaxGy;
          }

        if (abs(q.z) > abs(MaxGz))
          {
            MaxGz = q.z;
          }
           else
          {
            MaxGz = MaxGz;
          }

         //Display LIVE ACCEL G data on OLED
          //oled.setCursor(0,5);
          //oled.clearToEOL();
          //oled.println("ACCEL  X     Y     Z");
          //oled.setCursor(0,6);
          //oled.clearToEOL();
          //oled.setCursor(20,6);
          //oled.print(q.x,2);
          //oled.setCursor(60,6);
          //oled.print(q.y,2);
          //oled.setCursor(95,6);
          //oled.println(q.z,2);

          //DISPLAY MAX G on OLED
          oled.setCursor(0,5);
          oled.println("MaxG   X     Y     Z");
          oled.setCursor(0,6);
          oled.clearToEOL();
          oled.setCursor(20,6);
          oled.print(MaxGx);
          oled.setCursor(60,6);
          oled.print(MaxGy);
          oled.setCursor(95,6);
          oled.println(MaxGz);
          oled.setCursor(0,7);
          oled.println ("TEMP = " + String(tempF,1) + " F");
}

Your request was simpler than most so I provided an example


   
ReplyQuote
 tvr4
(@tvr4)
Estimable Member
Joined: 5 years ago
Posts: 122
Topic starter  

We are back to waiting for Electronic Cats.Ā  The developer from the jrowberg original MPU6050 library suggested that they need to add the new function to their library.Ā  The read FIFO function Electronic Cats uses now is flawed.

I will keep you posted


   
ReplyQuote
 tvr4
(@tvr4)
Estimable Member
Joined: 5 years ago
Posts: 122
Topic starter  

We made some progress.Ā  Someone from the jrowberg library github page provided a function to paste into my code.Ā  The function is based on their library but does not require a library modification.Ā  I still have yet to hear from Electronic Cats about their library.

The code works and reads data from the MPU6050. However at seemingly random periods the data will freeze and stop changing. The rest of the code keeps running but the accelerometer data freezes. I will let you know what we find.

Here is the function:

//BEGIN FUNCTION GetCurrentFIFOPacket
// Get the latest byte from FIFO buffer no matter how much time has passed.
// === GetCurrentFIFOPacket ===
// ================================================================
// Returns 1) when nothing special was done
// 2) when recovering from overflow
// 0) when no valid data is available
// ======================
//
int8_t GetCurrentFIFOPacket(uint8_t * data, uint8_t length) { // overflow proof
  LoopCounter++;

  int16_t fifoC;
  // This section of code is for when we allowed more than 1 packet to be acquired
  uint32_t BreakTimer = micros();

  Serial.println("Function Loops=" + String(LoopCounter));

  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); // Buffer Length is different than the packet length this will efficiently clear the buffer
            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);
  //ORIG LINE mpu.getFIFOBytes(data, length); //Get 1 packet
  mpu.getFIFOBytes(fifoBuffer, packetSize);
  return 1;
}  
  

It is called from my main loop using this statement:

 if(GetCurrentFIFOPacket(fifoBuffer, packetSize) )
{
// gets the latest packet if available and runs your code else this will skip your code because there is
// nothing new to process.
}

   
ReplyQuote
Page 4 / 7
Share: