GY-86 data output issues with Arduino Rocket Data logger

Does anyone have a simple test for GY-86 IMU. Racking my brain trying to figure out why the output is wrong on this sketch. I built this entire project with no issues according to the cal_mac projects instructable. The SD card module works great, the blue tooth module works great, the GY-86 is giving me some odd data. The whole project was done on a breadboard with a genuine Arduino UNO. I get data via blue tooth on my phone and via serial on the computer. However, it is parsed as follows: NAN,-134.30,-97684,2053,6007. The first 3 values are obviously wrong. The last 2 are correct. I'm not sure if this is a code problem or a defective IMU. The hardware all seems correct. Any suggestions? Possibly one of the libraries is coded wrong? MPU6050, I2Cdev, MS5611. I have also replaced the the GY-86 IMU but the new one yields the same results. I'm really stuck. I have run the Arduino Debug but the results are a little confusing to me.
I am using all the updated library files:
MS5611
MPU6050
I2C_dev
Sketch: rocket_data_logger.ino
Arduino Uno - Genuine Release 3
Arduino IDE: 1.8.11

I've include copies of the log files and sketch.

Rocket_data_logger.ino (3.69 KB)

Arduino Debug log.txt (69.1 KB)

C complile and upload log.txt (21.6 KB)

Serial output.txt (513 Bytes)

If you post your code as described in the forum guidelines more members will see it.

#include <Wire.h>
#include <MS5611.h>
#include "I2Cdev.h"
#include "MPU6050.h"
#include <SPI.h>
#include <SD.h>
unsigned long time;
const int chipSelect = 4;
// Mark's version
// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
// is used in I2Cdev.h
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif
MPU6050 accelgyro;
//MPU6050 accelgyro(0x69); // <-- use for AD0 high
#define OUTPUT_READABLE_ACCELGYRO
int16_t ax, ay, az;
int16_t gx, gy, gz;

MS5611 ms5611;
double referencePressure;
#define LED_PIN 13
bool blinkState = false;

void setup()
{
// join I2C bus (I2Cdev library doesn't do this automatically)
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
Wire.begin();
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
Fastwire::setup(400, true);
#endif

Serial.begin(9600);

// Initialize MS5611 sensor
Serial.println("Initialize MS5611 Sensor");

while(!ms5611.begin())
{
Serial.println("Could not find a valid MS5611 sensor, check wiring!");
delay(500);
}

// Get reference pressure for relative altitude
referencePressure = ms5611.readPressure();

// Check settings
checkSettings();

// initialize device
// Serial.println("Initializing I2C devices...");
accelgyro.initialize();

// verify connection
// Serial.println("Testing device connections...");
// Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
pinMode(LED_PIN, OUTPUT);

// Serial.print("Initializing SD card...");
if (!SD.begin(chipSelect)) {// see if the card is present and can be initialized:
// Serial.println("Card failed, or not present");
// don't do anything more:
return;
}
// Serial.println("card initialized.");

}

void checkSettings()
{
// Serial.print("Oversampling: ");
// Serial.println(ms5611.getOversampling());
}
void loop()
{

// read raw accel measurements from device
accelgyro.getAcceleration(&ax, &ay, &az);

// Read raw pressure and temp values
uint32_t rawTemp = ms5611.readRawTemperature();
uint32_t rawPressure = ms5611.readRawPressure();

// Read true temperature & Pressure
double realTemperature = ms5611.readTemperature();
long realPressure = ms5611.readPressure();

// Calculate altitude
float absoluteAltitude = ms5611.getAltitude(realPressure);
float relativeAltitude = ms5611.getAltitude(realPressure, referencePressure);

//change variables to strings
String comma = String (',');
String absalt = String (ms5611.getAltitude(realPressure)); //absoloute altitude in meters.
String temp = String ( ms5611.readTemperature()); //real temp in degrees, may over read initially, will take time for sensor to stabilize.
String realpressure = String (ms5611.readPressure()); // pressure in pascals
String accelXraw = String (ax); // raw accel in X. Divide by 2048 to get a "G" reading.
String timer = String (millis()); //puts a millis time stamp on each string.
//make a big string containing above strings
String Baro_data = String (absalt + comma + temp + comma + realpressure + comma + accelXraw + comma + timer) ;

Serial.println (Baro_data);
//delay(500);
File dataFile= SD.open("datalog.txt", FILE_WRITE);
// if the file is available, write to it:
if (dataFile) {
dataFile.println(Baro_data);//put Baro_data on the SD card
dataFile.close();

if (millis() > 10000) //change this number to change alarm delay (1s = 1000ms)
{tone (8,1000); // change the second number to alter the tone of the peizo alarm

}
else{ noTone(8);}

}}

else{ noTone(8);}

This is one reason that the forum guidelines ask that code be put inside code tags (unless your Arduino actually has a smiley face pin).

Are you aware of the potential pitfalls of using the String class?

Yes I am. I didn't write the code.

Have you tried the GY86 MPU by itself using examples from the MPU6050 library to make sure that it works?
How is the MPU wired to the Uno board?

I tried one stand-alone Arduino sketch. But could not get that to work either. The GY-86 is wired as follows:

5V
GND
SCL - PIN A5
SDA - PIN A4
INTA - PIN D2

I tried one stand-alone Arduino sketch.

One of the library examples?

How long are the wires from the MPU to the Uno?

When you tried the MPU standalone what were the results? "Did not work" conveys no useful information.

Yes. One of the library examples. Wires are 3" from the breadboarded IMU to the UNO.

When you tried the MPU standalone what were the results?

You get help faster when you answer questions.

Let's see if the MPU is recognized by the I2C bus and if it can communicate. Load and run this I2C scanner. It will tell you the devices that it sees on the bus. Does your MPU show up?
Note serial monitor baud rate 115200.

// I2C scanner by Nick Gammon.  Thanks Nick.

#include <Wire.h>

void setup() {
  Serial.begin (115200); //*****  make sure serial monitor baud matches *****

  // Leonardo: wait for serial port to connect
  while (!Serial) 
    {
    }

  Serial.println ();
  Serial.println ("I2C scanner. Scanning ...");
  byte count = 0;
  
  Wire.begin();
  for (byte i = 1; i < 120; i++)
  {
    Wire.beginTransmission (i);
    if (Wire.endTransmission () == 0)
      {
      Serial.print ("Found address: ");
      Serial.print (i, DEC);
      Serial.print (" (0x");
      Serial.print (i, HEX);
      Serial.println (")");
      count++;
      delay (1);  // maybe unneeded?
      } // end of good response
  } // end of for loop
  Serial.println ("Done.");
  Serial.print ("Found ");
  Serial.print (count, DEC);
  Serial.println (" device(s).");
}  // end of setup

void loop() {}

Actually the results were the same. NAN (not a number) for the Altimeter, -134 for the temperature and -97684 for the pressure.

2C scanner. Scanning ...
Found address: 104 (0x68)
Found address: 119 (0x77)
Done.
Found 2 device(s).

It only found 2. But there is four devices on the GY-86.

The test program I ran yielded these results:

rawTemp = 0, realTemp = -142.10 *C
rawPressure = 0, realPressure = -76807 Pa
absoluteAltitude = nan m, relativeAltitude = 0.00 m

I believe the register address for the MPU6050 is 0x68. The 0x77 is for the MS5611 The HMC883L does not show up. Only 3 devices on the chip.

NAN (not a number) for the Altimeter, -134 for the temperature and -97684 for the pressure.

So it is not the MPU6050 that is the trouble, it is the ms5611 pressure sensor?

Its I2C address is, according to the data sheet, 0x76 or 0x77 so it looks like it is on the bus. And 0x77 is the library default address.

#define MS5611_ADDRESS                (0x77)

Has that sensor worked, stand alone, with an example from the MS5611 library (MS5611_simple.ino)?

You are correct. The MPU6050 works fine. It's the MS5611 that does not seem to be yeilding any data.

It looks like it is a code issue with the MS5611.cpp file. I commented out every iteration of the following line:
Wire.endTransmission(); and I receive data from the MS5611. But the same data repeats and does not change. So it looks like it doesn't refresh the data stream. I have restored all the Wire.endTransmission() except one. It appears that some data is coming in:
44330.00,20.00,0,2120,861
first is absolute altitude in meters - not crrect and does not change
second is temperature in Celsius - correct but does not change
third is pressure in pascals - not correct but now reads zero and does not chnage
fourth is acceleration - this is correct and changes but is data from MPU6050
fifth is UP-time in milliseconds - correct and changes but is data from MPU6050.

So the MS5611.cpp library file is the culprit. How do we debug that?

Looking through the code. it looks like the 20 degrees Celsius reading is just a formula and not data from the MS5611. Starting to think that the second GY-86 IMU is bad.

Here's another interesting piece of information. The GY-86 board that I purchased doesn't look exactly like the one in the project. After researching, it looks like all the sensors are the same except the barometric pressure sensor. It is slightly smaller and only has one sampling hole. It looks a lot like a BMP180 instead of an MS5611. Otherwise, the boards are identical. oh no.....