Monthly Archives: July 2018

Integrating Time, Memory, and Heading Capability, Part IV

Posted 07/26/18,

In my last post on this subject, I described my efforts to troubleshoot an intermittent ‘bad data’ problem I experienced with the Inversense MPU6050/DMP breakout board from DFRobots.  The calculated yaw value would occasionally ‘lose synch with reality’ and start varying wildly.  I finally tracked this down to occasional bad reads from the DMP FIFO; the read would extract bytes from two different packets, producing an invalid yaw value.  The fix for this problem is to monitor the FIFO ‘bytes remaining’ count and reset the FIFO whenever the ‘bytes remaining’ count is not an integral multiple of the packet size.

After demonstrating that I could run the MPU6050 for days (literally) without any bad data occurrences, I thought I was home free in my effort to provide relative heading information for precise turns, but I ran into yet another problem when I tried to integrate the MPU6050 back onto the robot.  This time the problem was a hangup problem; after some tens of minutes, the program would stop responding at all – as if it had gone into an infinite loop somewhere (which is exactly what was happening, but I’m getting ahead of myself…).

This problem turned out to be a ‘simple’ I2C wire-length issue; I was able to demonstrate that the problem would occur any time the I2C ICL/SDA wire length went beyond about 42 cm, and would not occur with wire lengths below about 30 cm.  The problem did not appear to be sensitive to I2C bus speed (at least not for the default 100KHz or for a reduced clock speed of 50KHz) or pullup resistor value – just to wire length.

The rest of this post is a copy of my troubleshooting notes from the effort to track this problem down and solve it.  I have found in the past that when facing a non-trivial problem with multiple possible causal factors, a troubleshooting journal is an absolute must.  In the pre-computer days (you do remember there was a time before ubiquitous computing don’t you?), I used a real MIT engineering notebook for this purpose, and then later on a 3-ring binder into which I added quadrille-ruled sheets covered with my notes and drawings.  Then I moved on to Word documents – nicer because I could include Excel plots, Visio drawings, photos, and other mixed media.  Now that I have graduated to a WordPress blog, I can use it as a repository of my working notes, while also allowing others to see the inner workings of a mad scientist’s mind ;-).

I2C Hangup problem with Inversense MPU6050

Stay tuned,

Frank

 

Integrating Time, Memory, and Heading Capability, Part III

Posted 12 July 2018

In the last installment of this particular saga, I described another chapter in my ongoing effort to add heading knowledge to Wall-E2’s (my autonomous wall-following robot) super powers.  In that post, I described my attempt to utilize the Inversense IMU 6050 6DOF breakout board from DFRobots.  I posted some results that showed problems with vibration screwing up the results, and then getting error-free results using an ‘air pillow’ (a piece of air-filled packing material).  At the time, this led me to believe that the cause of the bad data was motor vibration.  However, when I tried adding some foam vibration dampening material, it didn’t seem to help – I was still getting intermittent stretches of bad data, with or without the motors running.  Clearly I still didn’t understand what was happening.

Once again I ran away from the whole thing, to regroup and let my mind work on the problem for a while; back to basketball, bridge, and general goofing off.

After some more web research and just thinking about what I knew and didn’t know, I started to suspect that what I was seeing was an artifact of the way the sensor(s) communicated with the main controller via the I2C serial interface.  When yaw measurements went bad, they went really bad, rapidly cycling from positive to negative values, and this didn’t make a lot of sense.  Maybe the main controller wasn’t keeping up with the sensor data stream, and  the software was trying to form heading values using bits from two different measurements; this would explain why the heading sign changed from measurement to measurement.  Also, I wasn’t utilizing the INT pin on the IMU6050 module, just pulling data out of the FIFO as rapidly as possible; could that be part of the problem too?

So, I decided to start all over again with the IMU6050 sensor on an ASP plugboard, with a spare Arduino Mega 2560 controller identical to the one being used to run Wall-E2, as shown in the following photo.  I also hooked up the INT pin, and used Jeff Rowberg’s I2CDev materials and MPU6050 example programs as the starting point.

DFRobots Inversense IMU6050 breakout board (board with blue LED, between FRAM and RTC) on an ASP plugboard, controlled by an Arduino Mega 2560

After getting everything going, I ran some long-term tests to see I could produce ‘bad’ yaw readings independent of the robot platform.  And, of course, I couldn’t get the darned thing to fail, no matter how long I ran it.  Shown below is a 20-minute long plot

20-minute run with no observed problems

Next, I tried inserting some delays into the ‘do other stuff’ part of the main loop, to try and simulate the normal robot processing delays.  This had no effect up until the delay reached 40mSec or so, and then I started to see problems very similar to what I had seen before with both the MPU9250 and 6050 sensor setups.

On robot test displaying yaw value and bytes remaining in MPU6050 FIFO

Then I modified the code again to check for FIFO byte lengths that weren’t an integral multiple of the normal packet length (42 in this case), and to reset the FIFO if the condition was detected. This seemed to eliminate the ‘bad data’ effect, regardless of the amount of delay introduced in the processing portion of loop().

About 6 minutes with the motors running. Program modified to reset the FIFO whenever a non-modulo ‘bytes remaining’ condition was detected

Detail view of the last 100 seconds of the previous plot

Summary:

The Invensense MPU6050/DMP/FIFO combination is sensitive to delays in the main  processing loop, even when using the INT line with an Interrupt Service Routine (ISR).  When the main loop processing delays get beyond about 40mSec, the ‘mpu.getFIFOBytes(fifoBuffer, packetSize);’ call will occasionally not remove the correct number of bytes from the FIFO, leaving a non-modulo (packetsize) number of bytes remaining in the FIFO.  When this happens, the next read will get (and process) bytes from two different packets, resulting in wildly varying yaw value outputs.  This condition is (now, after knowing what’s going on) fairly easy to recognize, as the error condition generally causes adjacent yaw values to have different signs, resulting in a classic sawtooth output.

The way to eliminate this artifact is to check for non-modulo (packetsize) FIFO bytes remaining value each time, and reset the FIFO when this happens.  Whatever good data is still in the FIFO will be lost, but the data that you do get will be valid.

I have included below my test program, with the FIFO modulo check and FIFO reset mechanism.  Note that this program also includes my motor control code, which obviously will not work with your setup.

 

Stay tuned,

Frank