OLED SSD1306 works fine on ESP32C but not on NANO 328P with the same resolution

Hi everybody,
I have a strange behaviour of small SSD1306 OLED 128x64 displays using them on different processors with exactly the same code.
I am using a simple example code to test a bme680 sensor with output on an OLED. I load the code on a ESP32C mini processor and everything OK. I can even switch between 128x64 and 128x32 resolution. If I load the same code on a NANO or UNO the 128x64 mode does not work, means the display doesn´t get allocated. If I change to 128x32 it gets work fine.
here is the code:

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BME680.h"
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10

#define SEALEVELPRESSURE_HPA (1013.25)
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

Adafruit_BME680 bme; // I2C
//Adafruit_BME680 bme(BME_CS); // hardware SPI
//Adafruit_BME680 bme(BME_CS, BME_MOSI, BME_MISO,  BME_SCK);

//Adafruit_SSD1306 display = Adafruit_SSD1306();
Adafruit_SSD1306 display = Adafruit_SSD1306(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

void setup() {
  //Serial.begin(9600);
  //Serial.println(F("BME680 test"));

  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  //display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x32)
  //display.begin(0x3C, false);
  
 if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C))
  {
    //Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  
  // init done
  display.display();
  delay(100);
  display.clearDisplay();
  display.display();
  display.setTextSize(1);
  display.setTextColor(WHITE);

  if (!bme.begin()) {
    //Serial.println("Could not find a valid BME680 sensor, check wiring!");
    while (1);
  }

  // Set up oversampling and filter initialization
  bme.setTemperatureOversampling(BME680_OS_8X);
  bme.setHumidityOversampling(BME680_OS_2X);
  bme.setPressureOversampling(BME680_OS_4X);
  bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
  bme.setGasHeater(320, 150); // 320*C for 150 ms
}

void loop() {
  display.setCursor(0,0);
  display.clearDisplay();

  if (! bme.performReading()) {
    //Serial.println("Failed to perform reading :(");
    return;
  }
  //display.println("--------------------");
  //display.println("** Sensor BME680 **");
  //display.println("--------------------");
  
  //Serial.print("Temperature = "); //Serial.print(bme.temperature); //Serial.println(" *C");
  display.print("Temp: "); display.print(bme.temperature); display.println(" *C");

  //Serial.print("Pressure = "); //Serial.print(bme.pressure / 100.0); //Serial.println(" hPa");
  display.print("Pres: "); display.print(bme.pressure / 100); display.println(" hPa");

  //Serial.print("Humidity = "); //Serial.print(bme.humidity); //Serial.println(" %");
  display.print("Humi: "); display.print(bme.humidity); display.println(" %");

  //Serial.print("Gas = "); //Serial.print(bme.gas_resistance / 1000.0); //Serial.println(" KOhms");
  display.print("Gas : "); display.print(bme.gas_resistance / 1000.0); display.println(" KOhms");

  display.println("--------------------");
  //Serial.println();
  display.display();
  delay(2000);
}

this is how it looks like
I suspect it might be a memory issue but the Adafruit examples work all fine even when I add more code to them to fill up the memory for testing.
actionally many times I have some problems with the Adafruit libraries for OLED and in these cases I need to switch to other libraries.
Has somebody an idea what makes these Adafruit libraries so unreliable?

Limited RAM space on the Uno (2K vs 200-500K on the various ESP32-Cx's) put the onus on the programmer to be much more careful in doling out a limited resource. Try putting all your string literals inside F() to save some of the Uno's measly 2K of RAM.

What is a ESP32C ?

sorry, I mean a ESP32C3

I did it but no change as I expected because the library examples are much havier and they work fine

When you use too much SRAM memory, then sometimes the heap overlaps with the stack or variables are overwritten, and the project might still run.

The sketch uses far too much memory for an Arduino Nano.
I had to remove most of the code in the loop(), to be able to check the available memory: OLED SSD1306 works fine on ESP32C but not on NANO 328P with the same resolution - Wokwi ESP32, STM32, Arduino Simulator

Your project will not work with a Arduino Nano.
Use a ESP32 (ESP32-C3) or a Raspberry Pi Pico.

If you still want to run it on a Arduino Nano, then the u8g2 library has a 8x8 option.

If you don't use any graphics commands, the text only SSD1306 library should work fine on the Nano. It does not require a display buffer.

Thanks a lot for your feedback but I don´t understand your point. You say that you had to remove most of the code in lhe loop(). The loop contains just a reading of the sensor values and 5 lines with output to the display, nothing else. On the other hand the example of the Adafruit_SSD1306 library contains all posible graphics and text features what an OLED display can offer and this works pretty fine on all my processors an displays I have.

The compiler does extreme optimizations. It is hard to tell how the usage of SRAM changes if functions from a library are used.

I added the freeMemory() function and I tried to get passed the display.begin() function. That was not easy.
I don't know how much SRAM the "Adafruit_Sensor" and "Adafruit_BME680" libraries use. That is why so many examples use very simple code and very little libraries, because you get immediate into trouble if you do more on a Arduino Nano with a OLED display.
There is an option to remove the Adafruit startup logo, perhaps that helps a little.

There is a "real" test of the SRAM use, it is sometimes called the "High Water Mark". It keeps track of how much memory is never used. If you let a project run for months and check the "High Water Mark", and there is 200 bytes never used, then it is probably okay to run that on a Arduino Nano. I did some tests in the past: HighWaterMark.ino

My point is: Don't try to run this on a Arduino Nano.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.