Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MPU6050 getting stuck in FIFO Loop #16

Closed
tonyvr4 opened this issue Sep 5, 2020 · 17 comments
Closed

MPU6050 getting stuck in FIFO Loop #16

tonyvr4 opened this issue Sep 5, 2020 · 17 comments
Assignees
Labels
Bug Something isn't working

Comments

@tonyvr4
Copy link

tonyvr4 commented Sep 5, 2020

This is based on previously closed issue #13

I have been testing the use of the MPU6050 without interrupt in my GPS-Accelerometer Data logger.
I had to add a line to reset the FIFO before reading the FIFO since it was giving corrupted data.

For some reason it gets stuck in this loop on occasion, I have not determined why. The code was from the DMP6 example

// wait for MPU extra packet(s) available
while (fifoCount < packetSize) {
if (fifoCount < packetSize) {
// try to get out of the infinite loop
Serial.println("In FIFO Loop"); //for troubleshooting
fifoCount = mpu.getFIFOCount();
}
}

@tonyvr4
Copy link
Author

tonyvr4 commented Sep 9, 2020

Anyone?

@sylvanoMTL
Copy link

sylvanoMTL commented Sep 9, 2020

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];
}

@tonyvr4
Copy link
Author

tonyvr4 commented Sep 9, 2020

Thank you very much for the link and the info. I will follow this up on the link you provided

@tonyvr4
Copy link
Author

tonyvr4 commented Sep 11, 2020

I received a reply on the github pafe you mentioned. However I do not know what to do with it.
Does this mean that there is a problem with the library itself?

Here is the reply:
"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;
    }

@tonyvr4
Copy link
Author

tonyvr4 commented Sep 15, 2020

Any suggestion on how to fix this?

@tonyvr4
Copy link
Author

tonyvr4 commented Sep 17, 2020

I received a message from the jrowberg github regarding this issue. They mentioned the function needs to be added.
Here is their response

"ask to see if someone there can add this function. This is the function that they should add."

`/** 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;
    }

your alternative is to make this function a local function in your code. this version is not part of the MPU6050 class
NOTE: this has not been tested and may contain errors!!!

/** 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
    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 = mpugetFIFOCount()) && ((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);
    mpu.getFIFOBytes(data, length); //Get 1 packet
    return 1;
    }

`

@sylvanoMTL
Copy link

Interesting.
I put the link from the issue you opened on the i2cdevlib MPU6050 library
This may avoid a double discussion.

@sabas1080 sabas1080 added the Bug Something isn't working label Sep 22, 2020
@sabas1080 sabas1080 self-assigned this Sep 22, 2020
@sabas1080
Copy link
Member

I'm going to review this in a few days

@tonyvr4
Copy link
Author

tonyvr4 commented Oct 1, 2020

No progress on this issue. The function works for a while but the data freezes, or stops updating, after a short period.
Not sure how to troubleshoot or where to go from here

@sabas1080
Copy link
Member

Hi @tonyvr4

I have not been able to work on this, for some other projects, if you want to send the solution in a pullrequest it is welcome.

We remind you that the support for this library is free and as free software, we do not have a support with time limit, I hope you can understand us

@tonyvr4
Copy link
Author

tonyvr4 commented Oct 2, 2020

I really appreciate the update and completely understand the limitations of free support. The reason I updated this issue is because I am working a lot and have limited time at the moment. So I did not want anyone to get upset if it took a bit to reply.

I have never done a pull request but will give it a try. Thanks

@tonyvr4
Copy link
Author

tonyvr4 commented Nov 6, 2020

It seems that this issue is more involved than I thought. I do not want to abandon the project so I am looking at alternatives.

Can I get acceleration from GPS somehow?

If not then are there other accelerometer modules that will work ?

@tonyvr4
Copy link
Author

tonyvr4 commented Dec 12, 2020

Any updates on this issue? I was ready to wire up a usable version of this project but can not continue due to the I2C freeze issue

@tonyvr4
Copy link
Author

tonyvr4 commented Jun 25, 2021

Any updates on this issue?

@whyameye
Copy link

whyameye commented Dec 8, 2023

I've also experienced this issue and best I can tell it seems to be some sort of overflow that's happening somewhere, perhaps internally with the MPU6050 FIFO buffer. It seems to be related to the rate at which I read the FIFO but writing simplified code slowing down my FIFO reads did not reproduce the issue. In any case, my workaround for now is to slow down the FIFO rate. I can submit a PR to set that rate in DMP initialization.

@sabas1080
Copy link
Member

@whyameye We welcome your contributions to solve or minimize this problem.

@xpeqex
Copy link
Member

xpeqex commented Dec 21, 2023

@tonyvr4

We will close this issue now. We have made a new release including the FIFO rate changes mentioned by @whyameye (thank you!) in PR #69, so this should be fixed now.

Nevertheless, feel free to contact us back if there are any other queries.

Enjoy the holidays! 🎄

@xpeqex xpeqex closed this as completed Dec 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Something isn't working
Projects
None yet
Development

No branches or pull requests

6 participants
@whyameye @sabas1080 @tonyvr4 @sylvanoMTL @xpeqex and others