Polling vs Interrupt with MPU6050 (GY-521) and Arduino

Posted 04 October 2019,

In my last post I described my Arduino Mega test program to interface with the popular Invensense MPU6050 IMU and it’s GY-521 clone.  In this post I describe the interface configuration for using a polling strategy rather than relying on the IMU6050’s interrupt signal.  A polling strategy can be very useful as it is much simpler, and saves a pin connection from the MPU6050 to the controller; all that is required is +V, GND, SDA & SCL, as shown below:

With this wiring setup, the control program is shown below:

In the above program, the interrupt service routine (ISR) and the accompanying ‘attachInterrupt()’ setup function have been removed as they are no longer needed for the polling arrangement.  Instead, the program calls ‘mpu.dmpPacketAvailable()’ every time through the loop, and if a packet is available, GetIMUHeadingDeg() is called to read the packet and return a yaw value.  The rest of the code in the loop() function is the place holder for the ‘other stuff’ that the program does when it isn’t paying attention to the IMU.

In this test program, I have set this section up to execute every 100 Msec, but in my robot programs I usually set it up for a 200 Msec interval; 5 cycles/sec is plenty fast enough for a wheeled robot that uses only the IMU yaw information for turn management.

So far, this arrangement seems very stable; I have been running it now for several hours without a hiccup.

Stay tuned,

Frank

 

 

2 thoughts on “Polling vs Interrupt with MPU6050 (GY-521) and Arduino

  1. Max

    Hello, could you please explain to me what the global_fifo_count is doing? Could the FIFO not just be reset directly after the line “global_fifo_count = mpu.getFIFOCount();”?

    Reply
    1. paynterf Post author

      Max,

      The global_fifo_count variable was just there so I could watch the machinery in progress – it’s not needed for an actual implementation. For instance, here are the functions I use in all my projects:

      float UpdateIMUHdgValDeg()
      {
      //Purpose: Get latest yaw (heading) value from IMU
      //Inputs: None. This function should only be called after mpu.dmpPacketAvailable() returns TRUE
      //Outputs:
      // returns true if successful, otherwise false
      // IMUHdgValDeg updated on success
      //Plan:
      //Step1: check for overflow and reset the FIFO if it occurs. In this case, wait for new packet
      //Step2: read all available packets to get to latest data
      //Step3: update IMUHdgValDeg with latest value
      //Notes:
      // 10/08/19 changed return type to boolean
      // 10/08/19 no longer need mpuIntStatus
      // 10/21/19 completely rewritten to use Homer’s algorithm
      // 05/05/20 changed return type to float vs bool.

      int flag = GetCurrentFIFOPacket(fifoBuffer, packetSize, MAX_GETPACKET_LOOPS); //get the latest mpu packet

      if (flag != 0) //0 = error exit, 1 = normal exit, 2 = recovered from an overflow
      {
      // display Euler angles in degrees
      mpu.dmpGetQuaternion(&q, fifoBuffer);
      mpu.dmpGetGravity(&gravity, &q);
      mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);

      //compute the yaw value
      IMUHdgValDeg = ypr[0] * 180 / M_PI;
      }

      return IMUHdgValDeg;//05/05/20 now returns updated value for use convenience
      }

      uint8_t GetCurrentFIFOPacket(uint8_t* data, uint8_t length, uint16_t max_loops)
      {
      mpu.resetFIFO();
      delay(1);
      //int countloop = 0;

      fifoCount = mpu.getFIFOCount();
      GetPacketLoopCount = 0;

      //gl_pSerPort->printf(“In GetCurrentFIFOPacket: before loop fifoC = %d\t”, fifoCount);
      while (fifoCount < packetSize && GetPacketLoopCount < max_loops) { GetPacketLoopCount++; fifoCount = mpu.getFIFOCount(); delay(2); } //gl_pSerPort->printf(“In GetCurrentFIFOPacket: after loop fifoC = %d, loop count = %d\n”, fifoCount, GetPacketLoopCount);

      if (GetPacketLoopCount >= max_loops)
      {
      return 0;
      }

      //if we get to here, there should be exactly one packet in the FIFO
      mpu.getFIFOBytes(data, packetSize);
      return 1;
      }

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *