A complete walk-through of wiring an SSD1306 OLED to an Arduino, converting an image to a C++ byte array with image2cpp, and rendering it using Adafruit GFX.
You do NOT need an SD card, SPI adapter, or extra hardware. The bitmap lives inside your sketch as PROGMEM data.
Most SSD1306 OLEDs speak I2C and have just 4 pins: VCC, GND, SCL, and SDA. Connect them to your Arduino like this:
| OLED Pin | Arduino UNO/Nano | ESP32 | ESP8266 |
|---|---|---|---|
VCC | 5V or 3.3V | 3.3V | 3.3V |
GND | GND | GND | GND |
SDA | A4 | GPIO 21 | D2 (GPIO 4) |
SCL | A5 | GPIO 22 | D1 (GPIO 5) |
Double-check the VCC pin voltage on the back of your OLED module. Some cheap boards only tolerate 3.3V even though they look 5V compatible.
Open the Arduino IDE and go to Sketch → Include Library → Manage Libraries.... Search for and install these two libraries from Adafruit:
Or, if you prefer the lighter-weight u8g2 library:
This is where pixel.hjlabs.in comes in. Instead of manually computing every bit of every row, just drop your image into the converter and let the tool generate perfect PROGMEM code.
128 × 64 (or match your OLED)If you are using the u8g2 library, enable the "Swap bits" checkbox before generating. u8g2 expects bits in MSB-first LSB order.
Here is a complete working sketch. Replace the epd_bitmap_myImage array with your own output from the converter:
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define SCREEN_ADDR 0x3C // or 0x3D
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// ===== Paste your image2cpp output below =====
const unsigned char epd_bitmap_myImage [] PROGMEM = {
0x00, 0x00, 0x01, 0x80, 0x03, 0xc0, 0x07, 0xe0,
// ... rest of your bytes ...
};
void setup() {
Serial.begin(9600);
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDR)) {
Serial.println("SSD1306 allocation failed");
for(;;);
}
display.clearDisplay();
display.drawBitmap(0, 0, epd_bitmap_myImage, 128, 64, SSD1306_WHITE);
display.display();
}
void loop() {}
Click Upload in the Arduino IDE. In a few seconds, your image should appear on the OLED!
If you prefer the smaller, faster u8g2 library:
#include <U8g2lib.h>
#include <Wire.h>
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);
const unsigned char myImage [] PROGMEM = {
// ... your bytes (remember to enable 'Swap bits' in image2cpp) ...
};
void setup() {
u8g2.begin();
}
void loop() {
u8g2.clearBuffer();
u8g2.drawXBMP(0, 0, 128, 64, myImage);
u8g2.sendBuffer();
delay(1000);
}
Verify the I2C address — run the i2c_scanner sketch. Most SSD1306 modules are 0x3C, some are 0x3D.
Open the converter and toggle Invert colors, or enable one of the Flip options. Regenerate and paste the new bytes.
You probably forgot to enable Swap bits in the image2cpp converter. u8g2 uses reversed bit order compared to Adafruit GFX.
Your Arduino is out of RAM. A full 128×64 framebuffer needs 1 KB — on an Arduino UNO (2 KB SRAM) you may need to trim other variables or switch to u8g2 (which has a smaller buffer mode).
The output resolution must match your drawBitmap call. If you converted at 64×64, call drawBitmap(32, 0, img, 64, 64, WHITE); to center it.
Skip the manual bit twiddling. Drop an image, pick a dithering mode, copy the code.
Open Converter →