0

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

2
  • Where is the difference between those sketches?
    – Sim Son
    Commented Apr 20, 2021 at 19:12
  • 1
    Made the corrections, I made mistake while copying pasting the comments
    – Pankaj
    Commented Apr 20, 2021 at 23:52

2 Answers 2

3

The SSD1306 uses a lot of RAM. Pretty much all your RAM. Serial also uses quite a bit of RAM. The two struggle to work together.

There is a special "text only" SSD1306 library that uses considerably less RAM: https://github.com/greiman/SSD1306Ascii

1

Thank you Majenko...

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 https://stackoverflow.com/questions/8649174/checking-memory-footprint-in-arduino

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;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.