Problem running both MPU9250/6500 and 128x64 OLED over I2C

Hello,

I am working on a project to display data from an MPU9250/6500 using the Bolderflight MPU9250 library, on a 128x64 OLED display using the Adafruit_SSD1306 library (both on I2C) using an Arduino Nano V3. I can run the sketch with either the MPU or the OLED display, but not both. The attached code runs OK as is, but if I uncomment “//MPU9250 IMU(Wire,0x68);” then the “display.begin(…” fails. Conversely, if I don’t run “InitializeDisplay();” then I can get data from the MPU9250 if I enable the InitMPU9250() code.

Thanks!

/*
WIRING NOTES
  Arduino Nano V3.0
  MPU-9250 - Arduino
    VCC    - 5V
    GND    - GND
    SCL    - A5
    SDA    - A4
  OLED Display (128 x 64)
    VCC    - 5V
    GND    - GND
    SCL    - A5
    SDA    - A4
*/

//LIBRARIES
#include <MPU9250.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeSans9pt7b.h>

//OLED DISPLAY (128 x 64)
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

//MPU-9250
//Define MPU9250 object with the MPU-9250 sensor on I2C bus 0 with address 0x68
//MPU9250 IMU(Wire,0x68);


//GLOBAL VARIABLES
  int status;
  float vartest = 12.9;

void setup()
{
  //Open serial communications
  Serial.begin(115200);
  //Wait for serial port to connect
  while(!Serial) {}

  InitializeDisplay();
  InitMPU9250();
}

void loop()
{
  delay(50);
}

void InitializeDisplay(void)
{
  Serial.println(F("Initializing Display"));

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }
    
  display.setFont(&FreeSans9pt7b);
  display.clearDisplay();
  //display.setTextSize(1);      // Normal 1:1 pixel scale
  display.setTextColor(WHITE); // Draw white text
  display.setCursor(2, 2);     // Start at top-left corner
  display.cp437(true);         // Use full 256 char 'Code Page 437' font

  display.setCursor(10, 12);
  display.print(F("X Ang="));
  display.setCursor(80, 12);
  display.print(vartest);
  display.display();
  Serial.println(F("Display Initialized."));
  Serial.println(F("---------------------------"));
}

void InitMPU9250()
{
  /*
  Serial.println(F("Initializing MPU-9250..."));
  // start communication with IMU 
  status = IMU.begin();
  if (status < 0)
  {
    Serial.println(F("IMU initialization unsuccessful"));
    Serial.println(F("Check IMU wiring or try cycling power"));
    Serial.print(F("Status: "));
    Serial.println(status);
    while(1) {} //Infinite loop effectively stops program execution
  }

  //Accelerometer Full Scale Range setting options
  //"ACCEL_RANGE_2G" +/- 2 (g) 
  //"ACCEL_RANGE_4G" +/- 4 (g) 
  //"ACCEL_RANGE_8G" +/- 8 (g) 
  //"ACCEL_RANGE_16G" +/- 16 (g)
     
  status = IMU.setAccelRange(MPU9250::ACCEL_RANGE_2G);
  if (status < 0)
  {
    Serial.println(F("Accelerometer Full Scale Range setting failed"));
    while(1) {}
  }
  Serial.println(F("Accelerometer Full Scale Range set to 2G"));

  //Gyroscope Full Scale Range setting options
  //"GYRO_RANGE_250DPS" +/- 250 (deg/s) 
  //"GYRO_RANGE_500DPS" +/- 500 (deg/s) 
  //"GYRO_RANGE_1000DPS" +/- 1000 (deg/s) 
  //"GYRO_RANGE_2000DPS" +/- 2000 (deg/s) 
   
  status = IMU.setGyroRange(MPU9250::GYRO_RANGE_250DPS);
  if (status < 0)
  {
    Serial.println(F("Gyroscope Full Scale Range setting failed"));
    while(1) {}
  }
  Serial.println(F("Gyroscope Full Scale Range set to 250 degrees / sec"));
  
  //Digital Low Pass Filter (DLPF) bandwidth options
  //Default is 184Hz if this is not called
  //Bandwidth Name         | DLPF Bandwidth | Gyroscope Delay | Accelerometer Delay | Temperature Bandwidth | Temperature Delay
  //"DLPF_BANDWIDTH_184HZ"   184 Hz            2.9 ms            5.8 ms               188 Hz                   1.9 ms 
  //"DLPF_BANDWIDTH_92HZ"     92 Hz            3.9 ms            7.8 ms                98 Hz                   2.8 ms 
  //"DLPF_BANDWIDTH_41HZ"     41 Hz            5.9 ms           11.8 ms                42 Hz                   4.8 ms 
  //"DLPF_BANDWIDTH_20HZ"     20 Hz            9.9 ms           19.8 ms                20 Hz                   8.3 ms 
  //"DLPF_BANDWIDTH_10HZ"     10 Hz          17.85 ms           35.7 ms                10 Hz                  13.4 ms 
  //"DLPF_BANDWIDTH_5HZ"       5 Hz          33.48 ms           66.96 ms                5 Hz                  18.6 ms 
 
  //status = IMU.setDlpfBandwidth(MPU9250::DLPF_BANDWIDTH_184HZ);
  //if (status < 0)
  //{
  //  Serial.println(F("Digital Low Pass Filter (DLPF) bandwidth setting failed"));
  //  while(1) {}
  //}
  //Serial.println(F("Digital Low Pass Filter (DLPF) bandwidth set to 184 Hz / sec"));

  Serial.println(F("MPU-9250 Initialized"));
  Serial.println(F("---------------------------"));
*/
}

Edit the MPU9250.h file and set _i2cRate to 100000 instead of the default 400000.

Thank you very much for your input! I am travelling this week but am looking forward to implementing this change when I get back this weekend.

Unfortunately, changing _i2cRate in MPU9250.h to 100000 (also tried 50000) did not change the behavior in which the display.begin call fails. Any additional thoughts would be greatly appreciated.

The memory is not big enough. The sketch uses about 930 bytes for global variables. The display code allocates 1024 bytes for the screen buffer. That leaves almost no memory for local variables and the stack. If you want to use both hardware parts you have to "upgrade" your Arduino to at least a Mega2560 (which has 4 times the RAM).

pylon - Yes, you are correct! I tried on Mega and it works fine. I incorrectly thought if it compiled for Nano it would work and did not realize the screen buffer requires additional memory. I will try to read more about this to get a better understanding.

Thanks!