1

I'm trying to understand the logic for one of the example Arduino programs for the MPU6050 IMU module. The entire program can be found here. There is an if() statement inside a while() loop inside the normal Arduiono sketch loop() function, and I'm having real trouble figuring out the logic. The ISR and relevant code section is shown below:

volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
void dmpDataReady() 
{
    mpuInterrupt = true;

}

    void loop() 
    {
        // if programming failed, don't try to do anything
        if (!dmpReady) return;

        // wait for MPU interrupt or extra packet(s) available
        while (!mpuInterrupt && fifoCount < packetSize) 
        {
            if (mpuInterrupt && fifoCount < packetSize) 
            {
                // try to get out of the infinite loop 
                fifoCount = mpu.getFIFOCount();

                //pulse the pin
                digitalWrite(Loop_While_Section_Pin, HIGH);
                delay(1);
                digitalWrite(Loop_While_Section_Pin, LOW);
            }
            // other program behavior stuff here
        }

        // reset interrupt flag and get INT_STATUS byte
        mpuInterrupt = false;
        mpuIntStatus = mpu.getIntStatus();

        // get current FIFO count
        fifoCount = mpu.getFIFOCount();
        if (fifoCount < packetSize) 
        {
            //Lets go back and wait for another interrupt. We shouldn't be here, we got an interrupt from another event
            // This is blocking so don't do it   while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
        }
        // check for overflow (this should never happen unless our code is too inefficient)
        else if ((mpuIntStatus & _BV(MPU6050_INTERRUPT_FIFO_OFLOW_BIT)) || fifoCount >= 1024) {
            // reset so we can continue cleanly
            mpu.resetFIFO();
            //  fifoCount = mpu.getFIFOCount();  // will be zero after reset no need to ask
            Serial.println(F("FIFO overflow!"));

            // otherwise, check for DMP data ready interrupt (this should happen frequently)
        }
        else if (mpuIntStatus & _BV(MPU6050_INTERRUPT_DMP_INT_BIT)) 
        {
            // read all available packets from FIFO
            while (fifoCount >= packetSize) // Lets catch up to NOW, in case someone is using the dreaded delay()!
            { 
                mpu.getFIFOBytes(fifoBuffer, packetSize);
                // track FIFO count here in case there is > 1 packet available
                // (this lets us immediately read more without waiting for an interrupt)
                fifoCount -= packetSize;
                //digitalWrite(Loop_ReadBytesSection_Pin, !digitalRead(Loop_ReadBytesSection_Pin)); //toggle the pin

                //pulse the pin
                digitalWrite(Loop_ReadBytesSection_Pin, HIGH); 
                delay(10);
                digitalWrite(Loop_ReadBytesSection_Pin, LOW); 
            }

    #ifdef OUTPUT_READABLE_YAWPITCHROLL
            // display Euler angles in degrees
            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.println(ypr[2] * 180 / M_PI);
    #endif

    // blink LED to indicate activity
            blinkState = !blinkState;
            digitalWrite(LED_PIN, blinkState);
        }
    }

It appears that the only way the 'if()' condition can be met is if the 'mpuInterrupt' variable managed by the ISR changes from FALSE to TRUE between the 'while()' condition evaluation and the 'if()' condition evaluation, which doesn't make a whole lot of sense to me. In addition, the 'fifoCount' variable is only incremented inside the 'if()' section, which makes the second half of both the 'while()' and 'if()' conditions a little strange too.

I do want to note that this example program DOES WORK, and if I instrument the 'if()' section to pulse a hardware pin whenever it executes, I do see pulses following many (but not all) hardware interrupt occurrences. So I know for sure the 'if()' statement DOES execute - but this seems a very 'Rube Goldbergian' way to go about it.

Any illumination would be appreciated ;-).

starship15
  • 764
  • 4
  • 10
  • at first glance, it looks like the first while statement has a misplaced closing brace ... i think that the closing brace should be placed right after the opening brace – jsotola Oct 01 '19 at 14:57
  • @jsotola That does not make sense either, because fifoCount will also be read shortly after that. I would say, this is simply wrong code and that the case "extra packets available" is not actually covered here. I guess this does not happen often either. – chrisl Oct 01 '19 at 17:13

0 Answers0