Issues with IMU over i2C at the same time as GPS

Hello forum, this is my first post on a forum in quite some time. Usually Google helps me through all of my problems but this one has me whooped, and I am too new to Arduino to properly troubleshoot by myself. My issues is as follows:

Arduino Mega 2560
Adafruit GPS v3 Breakout
MPU 9250 9DoF

If I run my IMU, I can get YPR data. If I run my GPS, I can get lat/lon/alt data. I cannot however run them both at the same time. I have to either power off my IMU or disconnect the TX from the GPS. I have ruled out power consumption by using external power supplies, and the code works with whatever device is currently connected. As soon as I connect the serial from the GPS with the IMU running, the YPR starts to jump all over the place, and after about 10 seconds or so, shuts the program down and everything stops scrolling on the serial monitor. I have tried multiple serial ports, and even AltSoftSerial, so excuse the excessive serial.begins!

I am assuming I have some kind of memory issue, and I am overloading it with both the IMU and GPS

Example outputs (steady) with IMU running:
Pose: roll:-0.54 pitch:-0.45 yaw:63.85

Connect GPS:
Pose: roll:-0.50 pitch:-0.43 yaw:64.12
Pose: roll:-0.52 pitch:-0.41 yaw:63.87
Pose: roll:-8.09 pitch:-8.14 yaw:66.01
Pose: roll:-6.17 pitch:-6.21 yaw:65.65
Pose: roll:-4.88 pitch:-4.83 yaw:65.43
*stopped scrolling and TX light on Arduino stops flashing

Code:

#include <Wire.h>
#include “I2Cdev.h”
#include “RTIMUSettings.h”
#include “RTIMU.h”
#include “RTFusionRTQF.h”
#include “CalLib.h”
#include <EEPROM.h>
#include <TinyGPS.h>
#include “AltSoftSerial.h”

TinyGPS gps;
void getgps(TinyGPS &gps);

RTIMU *imu; // the IMU object
RTFusionRTQF fusion; // the fusion object
RTIMUSettings settings; // the settings object

// DISPLAY_INTERVAL sets the rate at which results are displayed

#define DISPLAY_INTERVAL 150 // interval between pose displays

// SERIAL_PORT_SPEED defines the speed to use for the debug serial port

#define SERIAL_PORT_SPEED 115200

AltSoftSerial altSerial;

long lat, lon;

unsigned long fix_age, time, date, speed, course;
unsigned long chars;
unsigned short sentences, failed_checksum;
unsigned long lastDisplay;
unsigned long lastRate;

int sampleCount;

void setup()
{
int errcode;

Serial.begin(SERIAL_PORT_SPEED);
Serial2.begin(9600);
Serial3.begin(4800);
altSerial.begin(9600);
Wire.begin();
imu = RTIMU::createIMU(&settings); // create the imu object

Serial.print("ArduinoIMU starting using device "); Serial.println(imu->IMUName());
if ((errcode = imu->IMUInit()) < 0) {
Serial.print("Failed to init IMU: "); Serial.println(errcode);
}

if (imu->getCalibrationValid())
Serial.println(“Using compass calibration”);
else
Serial.println(“No valid compass calibration data”);

lastDisplay = lastRate = millis();
sampleCount = 0;

// Slerp power controls the fusion and can be between 0 and 1
// 0 means that only gyros are used, 1 means that only accels/compass are used
// In-between gives the fusion mix.

fusion.setSlerpPower(0.02);

// use of sensors in the fusion algorithm can be controlled here
// change any of these to false to disable that sensor

fusion.setGyroEnable(true);
fusion.setAccelEnable(true);
fusion.setCompassEnable(true);
}

void loop()
{
unsigned long now = millis();
unsigned long delta;
int loopCount = 1;

while (imu->IMURead()) { // get the latest data if ready yet
// this flushes remaining data in case we are falling behind
if (++loopCount >= 10)
continue;
fusion.newIMUData(imu->getGyro(), imu->getAccel(), imu->getCompass(), imu->getTimestamp());
sampleCount++;
if ((delta = now - lastRate) >= 1000)
{
Serial.print(“Sample rate: “); Serial.print(sampleCount);
if (imu->IMUGyroBiasValid())
Serial.println(”, gyro bias valid”);
else
Serial.println(", calculating gyro bias");

sampleCount = 0;
lastRate = now;
}
if ((now - lastDisplay) >= DISPLAY_INTERVAL)
{
lastDisplay = now;
// RTMath::display(“Gyro:”, (RTVector3&)imu->getGyro()); // gyro data
// RTMath::display(“Accel:”, (RTVector3&)imu->getAccel()); // accel data
// RTMath::display(“Mag:”, (RTVector3&)imu->getCompass()); // compass data
RTMath::displayRollPitchYaw(“Pose:”, (RTVector3&)fusion.getFusionPose()); // fused output
Serial.println();
}
}
// if (Serial1.available())
// {
// int c = Serial1.read();
// Serial2.write(c);
// }
}

I do not see where you are reading the GPS in that code. I use the Adafruit GPS V3 and the Adafruit 10DOF together with no problem, but I use my own code for the GPS.

Thats the funny thing, I don't even need to read the GPS in. By attaching the GPS TX to the Arduino Mega's RX on any of the hardware serials or the software serials, it wonks out the IMU. It does it if I don't even begin the serial.

That is strange. Mine does fine with the 10DOF.

edit: Can you post a link to the 9DOF unit you are using? The 9250 appears to be a 3.3v device. The Mega is 5 volt. My 10DOF uses a logic level converter on the interface.

http://www.amazon.com/Diymall%C2%AE-Mpu-9250-Nine-axis-Attitude-Acceleration/dp/B00OPNUO9U?ie=UTF8&psc=1&redirect=true&ref_=oh_aui_detailpage_o05_s00

Shows 3-5V input.

The power supply has a regulator.

Power supply: 3-5v (internal low dropout regulator)

There is no logic level converter. The IMU is rated to take input pin voltages up to the supply voltage +0.5v. That would be 3.8 volts. The Mega is a 5 volt device.

edit: There is a way to turn off the pullup resistors on the Mega. I can’t remember exactly how it is done. The 3.3v pullups on the IMU board should be sufficient for the Mega. I think it is setting the SDA and SCL pins to LOW.

This is from twi.c in the twi_init function…

  // activate internal pullups for twi.
  digitalWrite(SDA, 1);
  digitalWrite(SCL, 1);

…so this should disable the pullups.

  // deactivate internal pullups for twi.
  digitalWrite(SDA, 0);
  digitalWrite(SCL, 0);

I put in a logic converter with the Arduino on +5v and the IMU on +3.3v on the SDA/SCL pins. Some people have had issues using software to change the pullup on the Mega, but I had extra pieces laying around and one was a 8 pin logic board.

It was able to initialize; however, I still can connect the serial output from the GPS to one of my hardware serial lines and it seems to bomb the program.

Pose: roll:1.42 pitch:-0.27 yaw:86.15
Pose: roll:1.40 pitch:-0.24 yaw:85.92
Pose: roll:1.41 pitch:-0.23 yaw:86.01
Pose: roll:1.40 pitch:-0.23 yaw:85.44
Pose: roll:1.40 pitch:-0.23 yaw:85.93
Pose: roll:1.43 pitch:-0.22 yaw:86.53
Sample rate: 84, gyro bias valid
Pose: roll:1.43 pitch:-0.22 yaw:86.25
Pose: roll:1.43 pitch:-0.23 yaw:85.54
Pose: roll:1.43 pitch:-0.21 yaw:85.17
Pose: roll:1.42 pitch:-0.21 yaw:85.31
Sample rate: 51, gyro bias valid <— Connected it about here
Pose: roll:104.72 pitch:20.32 yaw:-15.78
Pose: roll:86.79 pitch:-0.76 yaw:1.10
Pose: roll:69.02 pitch:-12.62 yaw:18.98
Pose: roll:52.78 pitch:-17.03 yaw:34.73
Pose: roll:39.63 pitch:-17.51 yaw:47.97
Pose: roll:29.69 pitch:-15.84 yaw:57.71
Pose: roll:22.42 pitch:-13.45 yaw:64.66
Sample rate: 84, gyro bias valid
Pose: roll:17.10 pitch:-11.08 yaw:69.81
Pose: roll:13.17 pitch:-9.00 yaw:73.96
Pose: roll:10.27 pitch:-7.21 yaw:77.03
Pose: roll:8.11 pitch:-5.73 yaw:79.31 <— Stopped responding after this line

That is a mystery. I’m not sure what to tell you.

edit: Does the same happen even if you do not initialize the serial port the GPS is connected to?

Yeah, I don't even have to initialize the serial port. Whats even more strange, if I connect the "TX" from the GPS to another logic level converter pin, A3, and B3 isnt even connected back to the Arduino it does the same thing. Almost like I am getting something back on my power lines so I am triple checking all my VCC/GNDs.

Have you checked the Arduino's 5v pin for a voltage sag? Maybe one is drawing too much current.

Never dropped below 4.8; however, appears that using an external 5V power supply for the GPS module may fix the issue. I am running both concurrently and pulling in YPR+Lat/Lon/Alt. I used a 2A wall adapter for the Arduino to get better power than the USB, but looks like I should plan for an external BUC and supply voltage to everything, not rely on the Arduino to serve it out.

Thank you for all your help!