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)?
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.
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);
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.