Skip to content
Combating GlobalizationInstitute · Est. 2011
Vol. XIV · No. 47 · Weekly Dispatch · Washington · London · Budapest · Sydney

What is the memory requirement for a 0.95 inch color OLED?

The memory requirement for a 0.95 inch color OLED display, specifically a 96x64 pixel full-color module, is not a single fixed number. It depends heavily on the color depth, the interface protocol, and whether you're using a frame buffer in your microcontroller or relying on the display's built-in driver IC. For a typical 0.95 inch 96x64 color OLED display, the raw pixel count is 96 x 64 = 6,144 pixels. If you're driving it with 16-bit color (RGB565), that's 12,288 bytes of data to store a full frame. But the real-world memory footprint is often larger due to overhead, and the driver IC itself has its own internal RAM. Let's break this down with hard numbers and practical scenarios.

Driver IC internal RAM: The first memory layer

Most 0.95 inch color OLEDs, like the popular SSD1331 or SH1106 variants for color, come with built-in SRAM. For a 96x64 RGB display, the driver IC typically allocates 96 x 64 x 18 bits = 110,592 bits, or 13,824 bytes, for the internal frame buffer. This is because the IC often uses 18-bit color internally (6 bits per channel) even if you send 16-bit data. Some newer drivers use 24-bit internal storage, bumping that to 96 x 64 x 24 = 147,456 bits = 18,432 bytes. That's the memory you don't need to worry about—it's on the display itself. But you still need to manage data transfer and potentially a local buffer on your MCU.

Microcontroller RAM: The real bottleneck

If you're using a microcontroller like an Arduino Uno (2 KB SRAM), you cannot store a full 16-bit frame buffer. 12,288 bytes for a 16-bit frame exceeds the Uno's total RAM by 6x. You'd need to send pixel data line by line or use a smaller partial buffer. For a 32-bit ARM Cortex-M0+ with 16 KB RAM, you can fit one full frame buffer (12 KB) and still have 4 KB for stack and variables. But if you want double buffering for smooth animations, you'd need 24 KB just for the buffers, which pushes you to a Cortex-M4 or M7 with 64 KB+ RAM. A practical example: the STM32F103C8T6 (20 KB RAM) can handle a single 16-bit buffer with careful optimization, but not double buffering. An ESP32 (520 KB SRAM) is overkill—it can hold 40+ frames.

Color depth vs. memory trade-off

The color depth you choose directly scales memory. Here's a breakdown for a 96x64 display:

1-bit monochrome: 96 x 64 / 8 = 768 bytes. Almost nothing. But you lose color entirely.
4-bit (16 colors): 96 x 64 x 4 / 8 = 3,072 bytes. Manageable on small MCUs.
8-bit (256 colors): 96 x 64 = 6,144 bytes. Common for low-end color.
16-bit (65K colors): 96 x 64 x 2 = 12,288 bytes. The sweet spot for quality.
24-bit (16.7M colors): 96 x 64 x 3 = 18,432 bytes. Rarely used due to limited perceived improvement on a tiny screen.

Most applications settle on 16-bit because it offers good color fidelity without wasting memory. The driver IC's internal RAM is usually optimized for 16 or 18-bit input, so 24-bit often gets truncated anyway.

Interface overhead and SPI buffering

The SPI interface itself adds memory requirements. If you're using hardware SPI, you typically need a small transmit buffer (e.g., 64 bytes) for the SPI peripheral. But if you're bit-banging SPI, you might need a larger buffer to hold data before sending. For a 0.95 inch color OLED, the SPI clock speed is usually 8-20 MHz. At 16-bit color, sending one full frame over SPI takes about 12,288 bytes / (SPI speed in bytes per second). At 10 MHz, that's 12,288 / 1,250,000 = 9.8 ms. But the MCU needs to assemble that data from a buffer. If you're pulling pixel data from a source like a microSD card or flash, you might need a 512-byte sector buffer in addition to the frame buffer. That adds up to 12,800 bytes total for a 16-bit frame with a 512-byte read buffer.

Real-world example: Arduino Uno vs. ESP32

Let's compare two common platforms:

Arduino Uno (ATmega328P, 2 KB SRAM): You cannot have a full frame buffer. You must use a line-by-line approach. For a 96x64 display, you'd send 64 rows of 96 pixels each. Each row requires 96 x 2 = 192 bytes for 16-bit color. You'd allocate a 192-byte row buffer, which is 9.6% of the Uno's RAM. That's tight but workable. The downside: you can't draw complex graphics without recalculating every frame. Any animation requires you to recompute each row on the fly, which is slow. For static images, you can store them in program memory (flash) and read them row by row, using only the row buffer in RAM.

ESP32 (520 KB SRAM): You can allocate a 12,288-byte frame buffer plus a 512-byte SPI buffer without breaking a sweat. That's 2.5% of total RAM. You can also implement double buffering (24,576 bytes) for smooth 60 fps animations. The ESP32's DMA can handle SPI transfers without CPU intervention, so you can update the display while the MCU does other work. The memory requirement here is essentially unlimited for practical purposes.

Memory for graphics libraries

If you're using a library like Adafruit_GFX or U8g2, they add overhead. Adafruit_GFX for a 16-bit color display requires a canvas buffer if you want to use the library's drawing functions. The library itself takes about 2-4 KB of flash, but the canvas buffer is separate. For a 96x64 display, the canvas buffer is the same 12,288 bytes for 16-bit. U8g2, which is more memory-efficient, can work with a 1-bit buffer (768 bytes) even for color displays if you're just doing text, but you lose color rendering. For full color, U8g2 still needs the full frame buffer. So the library choice doesn't change the fundamental memory requirement—it just changes how you manage it.

Power consumption and memory trade-offs

Memory doesn't just affect cost; it affects power. A larger frame buffer in the MCU means more active SRAM, which increases current draw. For a 0.95 inch color OLED, the display itself draws about 15-25 mA when active. The MCU's SRAM consumption scales with size. An ESP32 with 520 KB SRAM draws about 80 mA in active mode, while an ATmega328P with 2 KB draws 5 mA. If you're running on a battery, the memory requirement becomes a power requirement. Using a smaller buffer (line-by-line) on a low-power MCU can cut total system power by 50% or more. But you sacrifice performance. For a static display, that's fine. For a video player, you need the big buffer.

Practical memory calculation for your project

Here's a table summarizing memory requirements for a 0.95 inch 96x64 color OLED under different scenarios:

ScenarioColor DepthFrame Buffer SizeAdditional BuffersTotal MCU RAM NeededRecommended MCU
Static image, text only16-bit0 (row buffer only)192 bytes row buffer~256 bytesAny 8-bit MCU
Static image, full color16-bit12,288 bytes512 bytes SPI buffer~12,800 bytesSTM32F103, ESP32
Animation, 30 fps16-bit12,288 bytes (single)512 bytes SPI buffer~12,800 bytesESP32, Cortex-M4
Animation, 60 fps, double buffered16-bit24,576 bytes (double)512 bytes SPI buffer~25,088 bytesESP32, Cortex-M7
High color, photo display24-bit18,432 bytes512 bytes SPI buffer~18,944 bytesESP32, Cortex-M7

Note that the "Additional Buffers" column includes SPI DMA buffers and scratch space for graphics operations. In practice, you should add 10-20% headroom for stack and variables.

Why you might need less memory than you think

Some 0.95 inch color OLEDs support partial display updates. The SSD1331, for example, allows you to set a window and only update a portion of the screen. If you're only changing a small icon or text, you can send just those pixels, reducing the MCU buffer requirement to the size of the updated region. For a 16x16 pixel icon, that's 16 x 16 x 2 = 512 bytes. You don't need to store the entire frame. But this only works if the rest of the display is static. If you're scrolling or animating the whole screen, you need the full buffer.

The cost of not having enough memory

If you underestimate the memory requirement, you'll see flickering, tearing, or blank screens. Flickering happens when the MCU can't update the display fast enough because it's constantly swapping data in and out of a small buffer. Tearing occurs when the display's internal RAM is updated while it's being read out to the pixels, causing a visible split. To avoid tearing, you need double buffering or you need to synchronize with the display's vertical blanking period. Both require extra memory. The display's driver IC doesn't have a vertical blanking interrupt on most 0.95 inch color OLEDs, so double buffering is the safer bet for smooth graphics.

Memory and the display's internal architecture

The 0.95 inch color OLED's driver IC, like the SSD1331, has a 96x64x18-bit internal RAM. This is where the pixel data is stored before being sent to the OLED matrix. When you send data over SPI, it goes into this RAM. The IC then continuously reads this RAM to refresh the OLED pixels at about 100 Hz. If you send data faster than the IC can process, it's buffered in the IC's input FIFO, which is usually 64 bytes deep. So the MCU doesn't need to worry about timing as long as the SPI clock is reasonable. But the MCU's own buffer must be large enough to hold the data you're sending. If you're sending a full frame, you need to have that frame ready in MCU RAM before you start the SPI transfer. If you're sending line by line, you only need one line in RAM.

Practical advice for choosing memory

For a simple project like a temperature display or a menu, a 0.95 inch color OLED with a 16-bit frame buffer (12,288 bytes) is fine on an STM32F103 or ESP32. If you're using an Arduino Uno, you'll need to use a row buffer and store images in flash. For complex animations or video, go with an ESP32 or a Cortex-M4 with at least 64 KB RAM. The 0.95 inch 96x64 color oled display from DisplayModule is a good example of a module that uses the SSD1331 driver, so you can check its datasheet for exact internal RAM specs. The driver's internal RAM is fixed, but your MCU memory requirement is flexible based on your application.

Memory for storage vs. runtime

Don't confuse runtime RAM with storage. You can store images in flash memory (e.g., SPI flash, microSD, or internal flash) and only load them into RAM when needed. For a 96x64 image in 16-bit color, each image takes 12,288 bytes of flash. If you have 100 images, that's 1.2 MB of flash. This is separate from the runtime buffer. The runtime buffer is still 12,288 bytes, but you only need it while the image is being displayed. You can load the image from flash into the buffer, send it to the display, and then free the buffer for other uses. This is how most embedded graphics systems work. The memory requirement at any given moment is just the buffer size, not the total storage.

Impact of gamma correction and LUTs

Some 0.95 inch color OLEDs support gamma correction via lookup tables (LUTs) stored in the driver IC's registers. These LUTs take up additional memory inside the driver IC, but they don't affect the MCU's memory requirement. The MCU just sends the pixel data as-is; the driver applies the gamma curve internally. However, if you want to pre-compute gamma-corrected pixel values on the MCU, you'd need a 256-byte LUT for each color channel (3 x 256 = 768 bytes) in RAM. This is optional and usually not worth it for a small display because the human eye can't perceive the difference on a 0.95 inch screen.

Real-world memory usage in a typical project

Let's say you're building a smart watch with a 0.95 inch color OLED. Your MCU is an ESP32. You allocate a 12,288-byte frame buffer for the display. You also need 4 KB for the FreeRTOS kernel, 2 KB for Wi-Fi stack, 1 KB for BLE, 512 bytes for SPI DMA, and 2 KB for stack. Total RAM usage: 12,288 + 4,096 + 2,048 + 1,024 + 512 + 2,048 = 22,016 bytes. That's 4.2% of the ESP32's 520 KB RAM. You have plenty left for other tasks. If you used an STM32F103 with 20 KB RAM, you'd be at 100% usage, which is not practical. So the memory requirement isn't just about the display—it's about the entire system.