Serial.print and I2C Communication not working together

Hi,

I have very peculier problem. When I run this code SSD1306 fails to initialize. Output at serial console is:
20:26:33.194 → MPU6050 OLED demo
20:26:33.532 → SSD1306 allocation failed

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_Sensor.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3D ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32

Adafruit_MPU6050 mpu;
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

int count =0;

void setup() {
  
  Serial.begin(9600);
  while (!Serial);
  Serial.println("MPU6050 OLED demo");

  if (!mpu.begin()) {
    Serial.println("Sensor init failed");
    while (1)
      yield();
  }
  Serial.println("Found a MPU-6050 sensor");

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { // Address 0x3C for 128x32
    Serial.println(F("SSD1306 allocation failed"));
    for (;;)
      ; // Don't proceed, loop forever
  }
  
  display.display();
  delay(500); // Pause for 2 seconds
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setRotation(0);
}

void loop() {
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);

  display.clearDisplay();
  display.setCursor(0, 0);

  display.println("Accelerometer - m/s^2");
  display.print(a.acceleration.x, 1);
  display.print(", ");
  display.print(a.acceleration.y, 1);
  display.print(", ");
  display.print(a.acceleration.z, 1);
  display.println("");
  
  display.println("Gyroscope - rps");
  display.print(g.gyro.x, 1);
  display.print(", ");
  display.print(g.gyro.y, 1);
  display.print(", ");
  display.print(g.gyro.z, 1);
  display.println("");
  display.display();
  delay(100);
}

But when I run this code, without displaying gyro everything runs fine. Adafruit logo is displayed and then followed by regular accelerometer data.

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_Sensor.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3D ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32

Adafruit_MPU6050 mpu;
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

int count =0;

void setup() {
  
  //Serial.begin(9600);
  //while (!Serial);
  //Serial.println("MPU6050 OLED demo");

  if (!mpu.begin()) {
    //Serial.println("Sensor init failed");
    while (1)
      yield();
  }
  //Serial.println("Found a MPU-6050 sensor");

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { // Address 0x3C for 128x32
    //Serial.println(F("SSD1306 allocation failed"));
    for (;;)
      ; // Don't proceed, loop forever
  }
  
  display.display();
  delay(500); // Pause for 2 seconds
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setRotation(0);
}

void loop() {
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);

  display.clearDisplay();
  display.setCursor(0, 0);

  display.println("Accelerometer - m/s^2");
  display.print(a.acceleration.x, 1);
  display.print(", ");
  display.print(a.acceleration.y, 1);
  display.print(", ");
  display.print(a.acceleration.z, 1);
  display.println("");

  display.println("Gyroscope - rps");
  display.print(g.gyro.x, 1);
  display.print(", ");
  display.print(g.gyro.y, 1);
  display.print(", ");
  display.print(g.gyro.z, 1);
  display.println("");
  display.display();
  delay(100);
}

Now, while debugging when I disable Serial logs and comment all Serial.print then the above code runs properly, logo is displayed, accelerometer and gyro both the data are displayed on OLED properly.

Compiler Log for non-working code is:
Sketch uses 21980 bytes (71%) of program storage space. Maximum is 30720 bytes.
Global variables use 761 bytes (37%) of dynamic memory, leaving 1287 bytes for local variables. Maximum is 2048 bytes.

The setup I am using as Arduino Nano, MPU6050 connected over I2C (address 0x68), SSD1306 based 0.96" 128x64 display over I2C (address 0x3D). I am using A4 and A5 pin of Arduino Nano as I2C. Both device are connected over same bus. I am using breadboard for testing.

PS: Both the code compiles without error or warning

I can’t see the difference between the 2 codes you posted

Short of memory .

Make use of the print F macro .

Use that for all your text prints and it may well give you enough memory for the 1306 initialisation .

See the Bald engineers explanation

https://www.baldengineer.com/arduino-f-macro.html

Please check again, I have made corrections

What arduino are you using?

The setup I am using as Arduino Nano, MPU6050 connected over I2C (address 0x68), SSD1306 based 0.96" 128x64 display over I2C (address 0x3D). I am using A4 and A5 pin of Arduino Nano as I2C. Both device are connected over same bus. I am using breadboard for testing.

Try with the serial monitor at 250000 bauds instead of 9600 (modify the Serial.begin())

Tried to Put a 4.7K pullup resistor on SCA and SCL ?

I don’t think this is serial port issue, since I am getting prints and it crashes at “display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)”.

Anyways tried both the suggestion, still same problem.
Also I have measuredI2C bus capacitance it is with recommended range.

9600 bauds is super slow, I was trying to look at ISR contention

You don’t have anything else connected ?

It was low RAM problem.
SSD1306 takes 1K, with MPU6050 the and serial print which I have included the remaining RAM is 5 bytes only, hence the initialization issue.
I followed simple guideline to reduce RAM footprint

Read this thread Checking memory footprint in Arduino - Stack Overflow

Code to print available SRAM.

Serial.print(availableMemory());

// free RAM check for debugging. SRAM for ATmega328p = 2048Kb.
int availableMemory() {
// Use 1024 with ATmega168
int size = 2048;
byte *buf;
while ((buf = (byte *) malloc(–size)) == NULL);
free(buf);
return size;
}