ESP32 - SSD1309 OLED Display

An OLED (Organic Light-Emitting Diode) display offers self-emitting pixels that deliver deep blacks, high contrast, and wide viewing angles — making it a great upgrade over traditional LCDs. The SSD1309 is the driver IC commonly found on 2.42-inch (sometimes labeled 2.4-inch) 128×64 I2C OLED modules.

ESP32 SSD1309 2.42-inch OLED

In this step-by-step guide you will learn how to connect and program the SSD1309 OLED 128×64 with an ESP32 board using the DIYables_OLED_SSD1309 library. Specifically, we will cover:

Hardware Used In This Tutorial

1×ESP-WROOM-32 Dev Module
1×USB Cable Type-A to Type-C (for USB-A PC)
1×USB Cable Type-C to Type-C (for USB-C PC)
1×SSD1309 I2C OLED Display 128x64 (2.42 inch)
1×Breadboard
1×Jumper Wires
1×Optionally, DC Power Jack
1×Recommended: Screw Terminal Expansion Board for ESP32
1×Recommended: Breakout Expansion Board for ESP32
1×Recommended: Power Splitter for ESP32

Or you can buy the following kits:

1×DIYables ESP32 Starter Kit (ESP32 included)
1×DIYables Sensor Kit (30 sensors/displays)
1×DIYables Sensor Kit (18 sensors/displays)
Disclosure: Some of the links in this section are Amazon affiliate links, meaning we may earn a commission at no additional cost to you if you make a purchase through them. Additionally, some links direct you to products from our own brand, DIYables .

Introduction to the SSD1309 2.42-Inch OLED Display

The SSD1309 is a single-chip CMOS OLED driver IC designed for 128×64 dot-matrix panels. It is register-compatible with the widely-used SSD1306, so many existing code examples carry over with minimal changes. The key hardware differences are:

  • No built-in charge pump — the SSD1309 requires an external VCC rail, though virtually all breakout boards (including 2.42-inch and 2.4-inch modules) ship with an onboard boost converter, so this is transparent to you.
  • Higher voltage tolerance — the SSD1309 accepts up to 16 V VCC, whereas the SSD1306 is limited to roughly 4.2 V.

The 2.42 inch (2.4 inch) OLED module commonly uses the SSD1309 driver and features a 128×64 pixel resolution with I2C interface. Panel color (white, blue, yellow, green, or dual-zone) is determined by the physical OLED material and is not software-controllable.

This tutorial communicates with the display over the I2C bus, which only requires two signal wires (SDA and SCL) and can share the bus with other I2C peripherals.

SSD1309 OLED Pinout (I2C Module)

The typical 2.42-inch SSD1309 I2C OLED module exposes four pins:

  • GND pin: should be connected to the ground of ESP32
  • VCC pin: should be connected to the 3.3V or 5V pin of ESP32 (check your module's specifications)
  • SCL pin: is a I2C clock pin. Connect to GPIO 22 (default SCL)
  • SDA pin: is a I2C data pin. Connect to GPIO 21 (default SDA)
SSD1309 OLED Pinout

※ NOTE THAT:

Pin order may vary between manufacturers. Always check the labels printed on your OLED module.

Wiring Diagram

  • How to connect ESP32 to SSD1309 OLED 128x64 display using breadboard
ESP32 SSD1309 OLED 128x64 wiring diagram

This image is created using Fritzing. Click to enlarge image

How to connect ESP32 and SSD1309 OLED

This image is created using Fritzing. Click to enlarge image

If you're unfamiliar with how to supply power to the ESP32 and other components, you can find guidance in the following tutorial: The best way to Power ESP32 and sensors/displays.

How to Program ESP32 for SSD1309 OLED

Install the DIYables_OLED_SSD1309 Library

The DIYables_OLED_SSD1309 library is specifically tailored for SSD1309 displays and extends Adafruit_GFX for richer graphics support.

  • Open the Arduino IDE
  • Navigate to the Libraries icon on the left sidebar
  • Search for DIYables_OLED_SSD1309
  • Click Install
  • A dependency prompt will appear — click Install All to also install Adafruit GFX Library (required for shape drawing and fonts)
ESP32 SSD1309 OLED library

Programming Steps

  1. Include the required libraries
#include <Wire.h> #include <Adafruit_GFX.h> #include <DIYables_OLED_SSD1309.h>
  1. Define the screen dimensions
#define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64
  1. Declare the display object
#define OLED_RESET -1 // Reset pin not used on most I2C modules #define SCREEN_ADDRESS 0x3C DIYables_OLED_SSD1309 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
  1. Initialize the OLED in setup()
if (!display.begin(SSD1309_SWITCHCAPVCC, SCREEN_ADDRESS)) { Serial.println(F("SSD1309 allocation failed")); for (;;); // halt }
  1. Display content
display.clearDisplay(); display.setTextSize(2); display.setTextColor(SSD1309_PIXEL_ON); display.setCursor(0, 20); display.println(F("Hello ESP32")); display.display(); // push buffer to screen

ESP32 Code — Hello World on SSD1309 OLED

The simplest starting point: print a few lines of text at different sizes.

/* * This ESP32 code is created by esp32io.com * * This ESP32 code is released in the public domain * * For more detail (instruction and wiring diagram), visit https://esp32io.com/tutorials/esp32-ssd1309-oled-display */ /* * DIYables OLED SSD1309 – Hello World * Prints text in two sizes on the 2.42 inch 128x64 I2C OLED with ESP32. */ #include <Wire.h> #include <Adafruit_GFX.h> #include <DIYables_OLED_SSD1309.h> #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_RESET -1 #define SCREEN_ADDRESS 0x3C DIYables_OLED_SSD1309 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); void setup() { Serial.begin(115200); if (!display.begin(SSD1309_SWITCHCAPVCC, SCREEN_ADDRESS)) { Serial.println(F("SSD1309 allocation failed")); for (;;); } display.clearDisplay(); display.setTextSize(1); // 6x8 pixels per character display.setTextColor(SSD1309_PIXEL_ON); // turn pixels on display.setCursor(0, 0); display.println(F("Hello, World!")); display.println(); display.setTextSize(2); // 12x16 pixels per character display.println(F("DIYables")); display.setTextSize(1); display.println(); display.println(F("SSD1309 OLED 128x64")); display.display(); // push buffer to screen } void loop() { }

ESP32 Code — Display Text on SSD1309 OLED

The following example demonstrates more text features — multiple sizes, number formatting, and the F() macro for saving RAM.

/* * This ESP32 code is created by esp32io.com * * This ESP32 code is released in the public domain * * For more detail (instruction and wiring diagram), visit https://esp32io.com/tutorials/esp32-ssd1309-oled-display */ /* * DIYables OLED SSD1309 – Display Text * Displays text in various sizes and formats on the 2.42" SSD1309 OLED with ESP32. */ #include <Wire.h> #include <Adafruit_GFX.h> #include <DIYables_OLED_SSD1309.h> #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_RESET -1 #define SCREEN_ADDRESS 0x3C DIYables_OLED_SSD1309 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); void setup() { Serial.begin(115200); if (!display.begin(SSD1309_SWITCHCAPVCC, SCREEN_ADDRESS)) { Serial.println(F("SSD1309 allocation failed")); for (;;); } display.clearDisplay(); // Various text sizes display.setTextSize(1); display.setTextColor(SSD1309_PIXEL_ON); display.setCursor(0, 0); display.println(F("Size 1 - DIYables")); display.setTextSize(2); display.println(F("Size 2")); display.setTextSize(3); display.println(F("Sz3")); display.display(); delay(3000); // Number formatting display.clearDisplay(); display.setTextSize(1); display.setCursor(0, 0); int value = 42; float pi = 3.14159; display.print(F("Integer: ")); display.println(value); display.print(F("Float: ")); display.println(pi, 2); // 2 decimal places display.print(F("Hex: 0x")); display.println(value, HEX); display.print(F("Binary: 0b")); display.println(value, BIN); display.display(); } void loop() { }

Useful Display Functions Reference

Below is a quick-reference list of the most frequently used functions when working with the SSD1309 OLED through the DIYables library:

  • oled.clearDisplay() — wipe the frame buffer (all pixels off).
  • oled.display() — transfer the buffer to the OLED so changes become visible.
  • oled.drawPixel(x, y, color) — set or clear an individual pixel.
  • oled.setTextSize(n) — scale the font by factor *n* (1 = 6×8, 2 = 12×16, …, up to 8).
  • oled.setCursor(x, y) — move the text cursor to pixel coordinates *(x, y)*.
  • oled.setTextColor(SSD1309_PIXEL_ON) — text foreground only (background is transparent).
  • oled.setTextColor(SSD1309_PIXEL_OFF, SSD1309_PIXEL_ON) — text with an explicit background colour.
  • oled.println("message") — print a string and advance to the next line.
  • oled.println(number) — print an integer in decimal.
  • oled.println(number, HEX) — print an integer in hexadecimal.
  • oled.startscrollright(start, stop) — hardware-scroll right between page *start* and page *stop*.
  • oled.startscrollleft(start, stop) — hardware-scroll left.
  • oled.startscrolldiagright(start, stop) — hardware-scroll diagonally right.
  • oled.startscrolldiagleft(start, stop) — hardware-scroll diagonally left.
  • oled.stopscroll() — halt any active hardware scroll.
  • oled.setContrast(value) — adjust display brightness (0–255).
  • oled.dim(true/false) — quickly dim the display to minimum or restore the previous contrast.
  • oled.invertDisplay(true/false) — hardware-level colour inversion (on pixels ↔ off pixels).

How to Vertically and Horizontally Center Text on the SSD1309 OLED

See How to vertical/horizontal center on OLED

ESP32 Code — Draw Shapes on SSD1309 OLED

Because the DIYables_OLED_SSD1309 library extends Adafruit_GFX, you get a complete set of shape-drawing primitives: pixels, lines, rectangles, filled rectangles, circles, filled circles, triangles, filled triangles, and rounded rectangles. The sketch below cycles through all of them with animated demos.

/* * This ESP32 code is created by esp32io.com * * This ESP32 code is released in the public domain * * For more detail (instruction and wiring diagram), visit https://esp32io.com/tutorials/esp32-ssd1309-oled-display */ /* * DIYables OLED SSD1309 – Draw Shapes * Demonstrates drawing pixels, lines, rectangles, circles, and triangles on the 2.42" OLED with ESP32. */ #include <Wire.h> #include <Adafruit_GFX.h> #include <DIYables_OLED_SSD1309.h> #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_RESET -1 #define SCREEN_ADDRESS 0x3C DIYables_OLED_SSD1309 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); void setup() { Serial.begin(115200); if (!display.begin(SSD1309_SWITCHCAPVCC, SCREEN_ADDRESS)) { Serial.println(F("SSD1309 allocation failed")); for (;;); } display.clearDisplay(); display.display(); } void loop() { // Draw pixels display.clearDisplay(); for (int i = 0; i < 20; i++) { display.drawPixel(random(SCREEN_WIDTH), random(SCREEN_HEIGHT), SSD1309_PIXEL_ON); } display.display(); delay(2000); // Draw lines display.clearDisplay(); for (int y = 0; y < SCREEN_HEIGHT; y += 8) { display.drawLine(0, 0, SCREEN_WIDTH - 1, y, SSD1309_PIXEL_ON); } display.display(); delay(2000); // Draw rectangles display.clearDisplay(); display.drawRect(10, 10, 40, 30, SSD1309_PIXEL_ON); // outline display.fillRect(60, 10, 40, 30, SSD1309_PIXEL_ON); // filled display.drawRoundRect(10, 45, 40, 15, 5, SSD1309_PIXEL_ON); // rounded corners display.display(); delay(2000); // Draw circles display.clearDisplay(); display.drawCircle(32, 32, 20, SSD1309_PIXEL_ON); // outline display.fillCircle(96, 32, 20, SSD1309_PIXEL_ON); // filled display.display(); delay(2000); // Draw triangles display.clearDisplay(); display.drawTriangle(20, 10, 10, 50, 30, 50, SSD1309_PIXEL_ON); // outline display.fillTriangle(90, 10, 70, 50, 110, 50, SSD1309_PIXEL_ON); // filled display.display(); delay(2000); }

ESP32 Code — Hardware Scrolling on SSD1309 OLED

The SSD1309 has a built-in scrolling engine that shifts the display contents without any CPU load. The DIYables library exposes four scroll directions: right, left, diagonal-right, and diagonal-left. Each takes a start page and stop page parameter (pages are 8-pixel-high horizontal strips numbered 0–7 on a 64-pixel-tall display).

※ NOTE THAT:

Always call display() to push your content to the OLED before starting a scroll. Avoid drawing new content while scrolling is active — call stopscroll() first.

/* * This ESP32 code is created by esp32io.com * * This ESP32 code is released in the public domain * * For more detail (instruction and wiring diagram), visit https://esp32io.com/tutorials/esp32-ssd1309-oled-display */ /* * DIYables OLED SSD1309 – Scroll Text * Demonstrates all four hardware scroll directions on the 2.42" OLED with ESP32. */ #include <Wire.h> #include <Adafruit_GFX.h> #include <DIYables_OLED_SSD1309.h> #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_RESET -1 #define SCREEN_ADDRESS 0x3C DIYables_OLED_SSD1309 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); void setup() { Serial.begin(115200); if (!display.begin(SSD1309_SWITCHCAPVCC, SCREEN_ADDRESS)) { Serial.println(F("SSD1309 allocation failed")); for (;;); } display.clearDisplay(); display.setTextSize(2); display.setTextColor(SSD1309_PIXEL_ON); display.setCursor(10, 24); display.println(F("DIYables")); display.display(); delay(2000); } void loop() { // Scroll right across all pages display.startscrollright(0x00, 0x07); delay(3000); display.stopscroll(); delay(500); // Scroll left display.startscrollleft(0x00, 0x07); delay(3000); display.stopscroll(); delay(500); // Diagonal scroll right display.startscrolldiagright(0x00, 0x07); delay(3000); display.stopscroll(); delay(500); // Diagonal scroll left display.startscrolldiagleft(0x00, 0x07); delay(3000); display.stopscroll(); delay(500); }

ESP32 Code — Display Bitmap Image on SSD1309 OLED

To display a bitmap on the SSD1309 OLED you must first convert your image into a C byte array. Use the free image2cpp online tool for this conversion:

  1. Upload your image file (PNG, JPG, BMP, etc.).
  2. Set the canvas size to 128×64 (or smaller).
  3. Choose Arduino code as the output format.
  4. Copy the generated array into your sketch.
image to bitmap array

The example below alternates between a 16×16 heart icon and a full-width DIYables logo:

/* * This ESP32 code is created by esp32io.com * * This ESP32 code is released in the public domain * * For more detail (instruction and wiring diagram), visit https://esp32io.com/tutorials/esp32-ssd1309-oled-display */ /* * DIYables OLED SSD1309 – Display Bitmap Image * Shows a 16x16 heart icon and 128x64 DIYables logo on the 2.42" OLED with ESP32. */ #include <Wire.h> #include <Adafruit_GFX.h> #include <DIYables_OLED_SSD1309.h> #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_RESET -1 #define SCREEN_ADDRESS 0x3C DIYables_OLED_SSD1309 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); // 16x16 heart icon bitmap const unsigned char heart_icon[] PROGMEM = { 0x00, 0x00, 0x0c, 0x30, 0x1e, 0x78, 0x3f, 0xfc, 0x7f, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfe, 0x3f, 0xfc, 0x1f, 0xf8, 0x0f, 0xf0, 0x03, 0xc0, 0x00, 0x00 }; // 128x64 DIYables logo bitmap const unsigned char diyables_logo[] PROGMEM = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x07, 0xff, 0xc1, 0xff, 0xe0, 0x7f, 0xf0, 0x1f, 0xfc, 0x03, 0x00, 0x7f, 0xff, 0xff, 0xfc, 0x00, 0x1f, 0xff, 0xf7, 0xff, 0xf9, 0xff, 0xfc, 0x7f, 0xff, 0x0f, 0x80, 0x3f, 0xff, 0xff, 0xf8, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xff, 0x9f, 0xc0, 0x1f, 0xff, 0xff, 0xf8, 0x00, 0x7f, 0x80, 0xff, 0x00, 0x7f, 0xc0, 0x3f, 0xf0, 0x0f, 0xfc, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0xfe, 0x00, 0x7f, 0x00, 0x3f, 0x80, 0x1f, 0xe0, 0x07, 0xf8, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x01, 0xfc, 0x00, 0x3e, 0x00, 0x1f, 0x00, 0x0f, 0xc0, 0x03, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x03, 0xf8, 0x00, 0x3e, 0x00, 0x1f, 0x00, 0x0f, 0xc0, 0x03, 0xf0, 0x00, 0x07, 0xff, 0xff, 0xc0, 0x07, 0xf8, 0x00, 0x3e, 0x00, 0x1f, 0x00, 0x0f, 0xc0, 0x03, 0xf0, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x0f, 0xf8, 0x00, 0x3e, 0x00, 0x1f, 0x00, 0x0f, 0xc0, 0x03, 0xf0, 0x00, 0x03, 0xff, 0xff, 0x80, 0x0f, 0xf8, 0x00, 0x3e, 0x00, 0x1f, 0x00, 0x0f, 0xc0, 0x03, 0xf0, 0x00, 0x01, 0xff, 0xff, 0x80, 0x1f, 0xf8, 0x00, 0x3e, 0x00, 0x1f, 0x00, 0x0f, 0xc0, 0x03, 0xf0, 0x00, 0x01, 0xff, 0xff, 0x00, 0x3f, 0xf8, 0x00, 0x3e, 0x00, 0x1f, 0x00, 0x0f, 0xc0, 0x03, 0xf0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x3f, 0xf8, 0x00, 0x3e, 0x00, 0x1f, 0x00, 0x0f, 0xc0, 0x03, 0xf0, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x7f, 0xf8, 0x00, 0x3e, 0x00, 0x1f, 0x00, 0x0f, 0xc0, 0x03, 0xf0, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x7f, 0xf8, 0x00, 0x3e, 0x00, 0x1f, 0x00, 0x0f, 0xc0, 0x03, 0xf0, 0x00, 0x00, 0xff, 0xfc, 0x00, 0xff, 0xf8, 0x00, 0x3e, 0x00, 0x1f, 0x00, 0x0f, 0xc0, 0x03, 0xf0, 0x00, 0x00, 0xff, 0xfc, 0x00, 0xff, 0xf8, 0x00, 0x3e, 0x00, 0x1f, 0x00, 0x0f, 0xc0, 0x03, 0xf0, 0x00, 0x00, 0xff, 0xfc, 0x01, 0xff, 0xf8, 0x00, 0x3e, 0x00, 0x1f, 0x00, 0x0f, 0xc0, 0x03, 0xf0, 0x00, 0x00, 0xff, 0xf8, 0x01, 0xff, 0xf8, 0x00, 0x3e, 0x00, 0x1f, 0x00, 0x0f, 0xc0, 0x03, 0xf0, 0x00, 0x00, 0xff, 0xf8, 0x03, 0xff, 0xf8, 0x00, 0x3e, 0x00, 0x1f, 0x00, 0x0f, 0xc0, 0x03, 0xf0, 0x00, 0x00, 0xff, 0xf0, 0x03, 0xff, 0xfc, 0x00, 0x7e, 0x00, 0x1f, 0x80, 0x1f, 0xe0, 0x07, 0xf8, 0x00, 0x00, 0xff, 0xf0, 0x07, 0xff, 0x7f, 0x80, 0xff, 0x00, 0x7f, 0xc0, 0x3f, 0xf0, 0x0f, 0xfc, 0x00, 0x00, 0xff, 0xf0, 0x07, 0xfe, 0x3f, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xff, 0x9f, 0xc0, 0x00, 0xff, 0xe0, 0x0f, 0xfc, 0x1f, 0xff, 0xf7, 0xff, 0xf9, 0xff, 0xfc, 0x7f, 0xff, 0x0f, 0x80, 0x00, 0xff, 0xe0, 0x0f, 0xf8, 0x07, 0xff, 0xc1, 0xff, 0xe0, 0x7f, 0xf0, 0x1f, 0xfc, 0x03, 0x00, 0x00, 0xff, 0xe0, 0x1f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x1f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x3f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x3f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x80, 0x7f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x7f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0xfe, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xfc, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xf8, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xf0, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x03, 0xe0, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x07, 0xc0, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x0f, 0x80, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x3e, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x7c, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xf8, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81, 0xf0, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0xe0, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; void setup() { Serial.begin(115200); if (!display.begin(SSD1309_SWITCHCAPVCC, SCREEN_ADDRESS)) { Serial.println(F("SSD1309 allocation failed")); for (;;); } display.clearDisplay(); display.display(); } void loop() { // Display small heart icon centered display.clearDisplay(); display.drawBitmap((SCREEN_WIDTH - 16) / 2, (SCREEN_HEIGHT - 16) / 2, heart_icon, 16, 16, SSD1309_PIXEL_ON); display.display(); delay(3000); // Display full-screen DIYables logo display.clearDisplay(); display.drawBitmap(0, 0, diyables_logo, SCREEN_WIDTH, SCREEN_HEIGHT, SSD1309_PIXEL_ON); display.display(); delay(3000); // Invert display display.invertDisplay(true); delay(2000); display.invertDisplay(false); delay(1000); }

※ NOTE THAT:

  • The bitmap dimensions must not exceed the screen resolution (128×64 for the 2.42 inch module).

ESP32 Code — Contrast and Dim on SSD1309 OLED

The SSD1309 supports 256 levels of contrast (0–255). The DIYables library provides setContrast() for fine-grained control and dim() for a quick toggle between minimum brightness and the previously-configured level.

/* * This ESP32 code is created by esp32io.com * * This ESP32 code is released in the public domain * * For more detail (instruction and wiring diagram), visit https://esp32io.com/tutorials/esp32-ssd1309-oled-display */ /* * DIYables OLED SSD1309 – Contrast & Dim * Sweeps contrast from 0→255→0 then toggles dim mode on the 2.42" OLED with ESP32. */ #include <Wire.h> #include <Adafruit_GFX.h> #include <DIYables_OLED_SSD1309.h> #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_RESET -1 #define SCREEN_ADDRESS 0x3C DIYables_OLED_SSD1309 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); void setup() { Serial.begin(115200); if (!display.begin(SSD1309_SWITCHCAPVCC, SCREEN_ADDRESS)) { Serial.println(F("SSD1309 allocation failed")); for (;;); } // Draw a test pattern so the contrast changes are visible display.clearDisplay(); display.fillRect(0, 0, 64, 32, SSD1309_PIXEL_ON); display.fillRect(64, 32, 64, 32, SSD1309_PIXEL_ON); display.setTextSize(1); display.setTextColor(SSD1309_PIXEL_INVERSE); display.setCursor(16, 28); display.println(F("Contrast Demo")); display.display(); delay(2000); } void loop() { // Ramp up for (int c = 0; c <= 255; c += 5) { display.setContrast((uint8_t)c); delay(30); } delay(1000); // Ramp down for (int c = 255; c >= 0; c -= 5) { display.setContrast((uint8_t)c); delay(30); } delay(1000); // Quick dim toggle display.dim(true); // minimum brightness delay(2000); display.dim(false); // restore delay(2000); }

ESP32 Code — Custom External Fonts on SSD1309 OLED

The Adafruit GFX library ships with dozens of scalable FreeFont typefaces (Serif, Sans, Mono — each in Regular, Bold, Italic, and four sizes). You can activate any of them on the SSD1309 display by including the corresponding header and calling setFont().

※ NOTE THAT:

  • When an external font is active, the cursor Y coordinate refers to the text baseline, not the top-left corner. This is different from the built-in 5×7 font.
  • External fonts are stored in flash (PROGMEM). The ESP32 has ample flash memory, so feel free to use multiple font files in your project.
/* * This ESP32 code is created by esp32io.com * * This ESP32 code is released in the public domain * * For more detail (instruction and wiring diagram), visit https://esp32io.com/tutorials/esp32-ssd1309-oled-display */ /* * DIYables OLED SSD1309 – External Fonts * Cycles through three FreeFont typefaces on the 2.42" SSD1309 OLED with ESP32. */ #include <Wire.h> #include <Adafruit_GFX.h> #include <DIYables_OLED_SSD1309.h> #include <Fonts/FreeSerif9pt7b.h> #include <Fonts/FreeSansBold12pt7b.h> #include <Fonts/FreeMono9pt7b.h> #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_RESET -1 #define SCREEN_ADDRESS 0x3C DIYables_OLED_SSD1309 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); void setup() { Serial.begin(115200); if (!display.begin(SSD1309_SWITCHCAPVCC, SCREEN_ADDRESS)) { Serial.println(F("SSD1309 allocation failed")); for (;;); } display.clearDisplay(); display.display(); } void loop() { // ── Built-in 5×7 font ── display.clearDisplay(); display.setFont(NULL); display.setTextSize(1); display.setTextColor(SSD1309_PIXEL_ON); display.setCursor(0, 0); display.println(F("Built-in 5x7 font")); display.println(); display.setTextSize(2); display.println(F("DIYables")); display.display(); delay(3000); // ── FreeSerif 9pt ── display.clearDisplay(); display.setFont(&FreeSerif9pt7b); display.setTextSize(1); display.setTextColor(SSD1309_PIXEL_ON); display.setCursor(0, 14); // Y = baseline display.println(F("FreeSerif 9pt")); display.setCursor(0, 38); display.println(F("DIYables OLED")); display.setCursor(0, 58); display.println(F("Hello World!")); display.display(); delay(3000); // ── FreeSansBold 12pt ── display.clearDisplay(); display.setFont(&FreeSansBold12pt7b); display.setTextSize(1); display.setTextColor(SSD1309_PIXEL_ON); display.setCursor(0, 20); display.println(F("SansBold")); display.setCursor(0, 52); display.println(F("DIYables")); display.display(); delay(3000); // ── FreeMono 9pt ── display.clearDisplay(); display.setFont(&FreeMono9pt7b); display.setTextSize(1); display.setTextColor(SSD1309_PIXEL_ON); display.setCursor(0, 14); display.println(F("FreeMono 9pt")); display.setCursor(0, 34); display.println(F("0123456789")); display.setCursor(0, 54); display.println(F("!@#$%^&*()")); display.display(); delay(3000); }

SSD1309 OLED Troubleshooting with ESP32

If nothing appears on the 2.42 inch SSD1309 OLED after uploading your sketch, work through these checks:

  • Verify wiring — confirm SDA, SCL, VCC and GND are connected to the correct ESP32 pins.
  • Confirm the driver chip — this library is designed for the SSD1309. If your module uses a different controller (e.g. SH1106), it will not respond correctly.
  • Check the I2C address — most SSD1309 modules default to 0x3C, but some use 0x3D. Run the I2C scanner sketch below to detect the actual address:
// I2C address scanner — prints every detected device to the Serial Monitor #include <Wire.h> void setup() { Wire.begin(); Serial.begin(9600); Serial.println("I2C Scanner"); } void loop() { byte error, address; int nDevices = 0; Serial.println("Scanning..."); for (address = 1; address < 127; address++) { Wire.beginTransmission(address); error = Wire.endTransmission(); if (error == 0) { Serial.print("I2C device found at address 0x"); if (address < 16) Serial.print("0"); Serial.print(address, HEX); Serial.println(" !"); nDevices++; } else if (error == 4) { Serial.print("Unknown error at address 0x"); if (address < 16) Serial.print("0"); Serial.println(address, HEX); } } if (nDevices == 0) Serial.println("No I2C devices found"); else Serial.println("done"); delay(5000); }

Expected Serial Monitor output when the SSD1309 is detected:

COM6
Send
Scanning... I2C device found at address 0x3C ! done
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  
  • Ensure display() is called — the SSD1309 uses a frame buffer. Drawing functions only modify the buffer in RAM; nothing appears on screen until you call oled.display().
  • Check power supply — the 2.42 inch module draws more current than smaller OLEDs. Ensure your power source can deliver sufficient current (typically 20–40 mA at full brightness). If using USB power, this is usually not an issue with ESP32.
  • Custom I2C pins (optional) — If you need to use non-default I2C pins, initialize Wire with Wire.begin(SDA_PIN, SCL_PIN) before calling display.begin().

Wrap Up

This guide has covered all the essentials for using the 2.42-inch SSD1309 OLED display (128×64) with ESP32, including:

  • Hardware connections and I2C wiring
  • Text and number display with multiple sizes
  • Shape drawing (rectangles, circles, triangles)
  • Bitmap image rendering
  • Hardware scrolling in four directions
  • Contrast and brightness control
  • Custom external fonts

The DIYables_OLED_SSD1309 library simplifies SSD1309 programming by providing high-level functions for text, graphics, and display control while leveraging Adafruit GFX for extended drawing capabilities.

For more ESP32 projects and tutorials, visit esp32io.com

※ OUR MESSAGES