0.96 OLED & 4x20 LED library conflict

These libraries <Adafruit_GFX.h> <Adafruit_SSD1306.h> conflict with these <hd44780.h> <hd44780ioClass/hd44780_I2Cexp.h>. I don't believe this is a hardware address problem. The code compiles, but execution produces very strange Serial.print() outputs that are elsewhere in the code, not related to either one of the displays' lines of code.

Removing either one of the displays (the libraries and the begin() statement) results in the expected operation for the remaining display, as well as the expected operation of the Serial.print() lines.

Is your LCD using the I2C bus? Would you post a drawing of your device connections (might show something) and the sketch you are using (this will show bus addresses - be sure to use hex, not dec)?

Note that the Adafruit SSD1306 library will allocate a display buffer at run-time, either 512 bytes for a 128x32 display, or 1024 bytes for 128x64.

Without seeing a sketch where the problem occurs it's very hard to say anything about what might be causing it.

David_2018, I think you found the problem. The IDE reports the sketch uses 1153 bytes of dynamic memory. The allocation of another 1024 bytes at runtime by the OLED driver would leave less than zero bytes available. I can see that the function calls and returns are going to be totally dorked up. Thanks.

As a general rule, how many unallocated bytes should be available at run time (for a Pro Mini using OneWire and I2C)? Back when I was using Forth, the stack could get pretty deep, but I don't have a feel for C.

Mileage varies.

I went looking for this

void display_freeram() {
  Serial.print(F("- SRAM left: "));
  Serial.println(freeRam());
}

int freeRam() {
  extern int __heap_start,*__brkval;
  int v;
  return (int)&v - (__brkval == 0  
    ? (int)&__heap_start : (int) __brkval);  
}

that you can use to dynamically watch memory use. For AVR Arduinos.

You may be interested in the ebtire article I copied it from:

Arduino Memory Guide

a7

2 Likes

I'm a bit perplexed that the following code doesn't tell the compiler that it will need 1K at runtime, or better yet, that it is asking the IDE to allocate 1K right now.

//initialize the 0.96" OLED
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

The object should know WxH=bytes

xfpd, yes, you'd think so. But the IDE doesn't account or it or the library doesn't tell the IDE or or or...maybe an omission in the library.

I just assumed that the compiler would allocate all the required dynamic memory, not allow the code to allocate additional memory at run time.

I have no idea why the buffer is allocated at run-time instead of compile-time. Looking at the library, begin() will return false if the memory allocation fails, so a severe lack of memory should be detectable, and there is a method of de-allocating the buffer. There really is nothing preventing the stack from colliding with the buffer either, I've seen sketches where this happened, causing random pixels to appear in the corner of the display.

The compiler will not include any local variables in the dynamic memory, unless they are declared as static. Doing so would be an impossible task, because which functions are called and which local variable are declared could vary depending on external input at run-time.

Don't give up on the code yet, there may be some easy ways to reduce the memory usage. The simplest is to use the F() macro for text literals, such as

  Serial.print("this text is stored in RAM");
  Serial.print(F("this text is stored in program memory, not RAM"));

There are also OLED libraries that use either no buffer (generally limited to text), or a smaller buffer. Really depends on how you are using the display.

Thanks, works great. I've got my use of dynamic memory down to where I've got 1115 bytes available, but the SSD1306 allocation still fails. In another sketch, I do see that when the allocation is successful, it uses exactly 1024 bytes.

In another post I've asked about using #define to get my use of dynamic memory down further (I have about 64 "const byte" variables), but that doesn't seem to do what I want.

I've used the print(F()) extensively, also progmem, so I'm reconsidering my arrays and constant pointers. Good luck to me. I'm going to look at my functions. I have an old habit of making all my variables global (writing code since 1965); maybe it's time I modernize.

I would appreciate any pointers to other OLED drivers. I'm only using text, but I need the "display.setTextSize(1) and display.setCursor(5,10)" funtions, so that may require a bigger graphics-type driver.

The OLED isn't required for my application--the 4x20 LCD is the user interface. But having the OLED for displaying background diagnostics is could be really handy.

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