Strange UNO RAM issue

Disclaimer: this is not an OLED issue, it’s a software issue, also I’m somewhat know what I’m doing, take it in consideration when posting reply.

I’m trying to draw full screen dynamic image on SSD1306 128x64 OLED from RAM with Adafruit lib.

As you can see below – I’m creating ScreenBuffer array and define its size by static var BufferSize.
Creating a RamAddress pointer to point to this array and passing this pointer to Adafruit lib (I do not pass ScreenBuffer array itself or ScreenBuffer size) and even tho it shows garbadge (RAM content of Arduino) it works – it updates entire screen.

But if you change BufferSize to a bigger value like 400 or more UNO halts, no compiling error, no out of memory error, it just halts. By halts I mean stops somwhere in Adafruit lib, it never exits first try to draw the screen, tho it doesn’t look that UNO gets bricked. I’ve noticed that Adafruit likes to add forever loops in their code – it might be it…

My guess would be that Adafruit lib tries to create it’s own dynamic RAM buffer and it fails due to not enough memory? Adafruit ssd1306 lib is very messy and uses GFX and other libs to make it work, so it’s pain to track code execution.

Let me repeat this – I do not pass ScreenBuffer array itself or ScreenBuffer size to Adafruit lib.

If my code would work in full screen (BufferSize= 1024) it would draw every other vertical line:

#include <Wire.h>
#include <Adafruit_SSD1306.h>

Adafruit_SSD1306 display(128, 64);

const uint16_t BufferSize= 324; // BUFFER SIZE
volatile uint8_t ScreenBuffer[BufferSize];
byte *RamAddress = ScreenBuffer;

void setup()
{
  Wire.begin();
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  filBuff();
}

void loop()
{
  display.clearDisplay();
  display.drawBitmap(0, 0, RamAddress, 128, 64, 1);
  display.display();
}

void filBuff()
{
  for (uint16_t n = 0; n < BufferSize; n++ )
  {
    ScreenBuffer[n] = 0b10101010;
  }
}

What is the memory usage reported by the compiler? Also what testing have you done? I'm not asking for any particular kind because you somewhat know what you're doing. :slight_smile:

If my code would work in full screen (BufferSize= 1024) it would draw every other vertical line

Actually, no. It will draw separated vertical stripes consisting of 4 vertical lines each stripe. But let's make it work first.

What about this line from the Adafruit documentation?

The bitmap data must be located in program memory using the PROGMEM directive.

Your code’s static allocation is 624 bytes. As you suspect, Adafruit’s library mallocs a buffer, in your case 1136 bytes leaving 288. There’s not enough space to run a stack and increase the size of your screen buffer substantially.

wildbill:
Your code's static allocation is 624 bytes. As you suspect, Adafruit's library mallocs a buffer, in your case 1136 bytes leaving 288. There's not enough space to run a stack and increase the size of your screen buffer substantially.

Thanks, I guess I'll have to make my own lib...
Or I could try writing directly to Adafruit buffer if it's public.

.getBuffer() returns buffer address, so I'm somewhat back in business.

3Dgeo:
Thanks, I guess I'll have to make my own lib...

Or just access their screen buffer directly...

aarg:
What about this line from the Adafruit documentation?

The bitmap data must be located in program memory using the PROGMEM directive.

Graphics Primitives | Adafruit GFX Graphics Library | Adafruit Learning System

The library has apparently changed since that was written, because you can have a bitmap stored in RAM. The OP's code actually runs properly with a buffer size of 1024 on a mega, although with the lines vertical instead of the desired horizontal. The drawBitmap function will use PROGMEM when the pointer to the bitmap is declared const, ram when it is not, so be careful not to declare the pointer to the bitmap array as const even though the address of a global array will be constant.

3Dgeo:
Thanks, I guess I'll have to make my own lib...
Or I could try writing directly to Adafruit buffer if it's public.

.getBuffer() returns buffer address, so I'm somewhat back in business.

Adafruit is famous for prolific methods, so no surprise there. I haven't looked but maybe there is more support for that somewhere in the library.