To show a QR code on an Arduino SSD1306 OLED, use two pieces of software: a QR encoder to create the symbol and a display library to draw its pixels. The SSD1306 driver alone does not generate QR codes. For a 128×64 display, scale the QR modules to fit both dimensions, center the symbol, then send the display buffer with display.display(). You can test the drawing on a computer with an SSD1306 emulator that captures or renders display frames, but that does not reproduce every hardware timing or electrical condition.
What you need
- An SSD1306 OLED supported by Adafruit_SSD1306. That library targets monochrome 128×64 and 128×32 displays and supports I2C and SPI.
- A QR encoder, such as ricmoo’s QRCode library, which provides the QR matrix.
- A renderer such as QRCodeGFX, which connects QR generation to Adafruit_GFX-compatible displays, including Adafruit_SSD1306. You can also draw the matrix yourself by filling a small rectangle for each dark module.
The display driver handles communication with the OLED; it does not turn text into a QR symbol. The encoder and display renderer have separate jobs.
How the sketch fits the QR code on the display
A QR symbol is a square grid of modules. To draw it sharply on a monochrome screen, give each module an integer number of pixels. Compute the scale from both the screen width and height, use the smaller result, and center the resulting square. The Arduino Project Hub example uses this fit-and-center approach, paints active modules with fillRect(), and refreshes the OLED with display.display().
The example below uses the QRCode library’s matrix API directly. It reserves a four-module clear border around the symbol, a useful quiet zone that gives scanners blank space around the code. That border also reduces the available drawing area, so a larger QR version or longer payload may not fit at a readable scale—especially on a 128×32 display.
Recommended Free Tools
#1 Best Overall
- Three Displays For More Projects: Build a sensor dashboard, robot status panel and classroom demo at the same time, or keep spare modules ready for testing; each compact screen delivers 128x64 graphics with self-luminous pixels and no backlight
- Fixed Yellow-Blue Zones Make Status Information Easy To Scan: Use the yellow upper band for headings, alerts or icons and the blue lower area for readings and menus; the display colors are fixed by the OLED panel rather than programmable RGB, and the screen does not support touch input
- Four-Wire I2C Connection Saves Controller Pins: Connect GND, VCC, SCL and SDA according to the module labels, scan the I2C bus and use the default 7-bit address 0x3C; the 0x78 PCB marking represents the corresponding 8-bit write-address format used by some documentation
- Works With Common 3.3 V & 5 V Project Platforms: Add compact visual feedback to compatible microcontroller and single-board computer projects, but verify the module pin order, supply voltage, I2C logic levels, pull-up voltage and SSD1306 software configuration before powering
- Three Modules Plus Ten Dupont Wires: Includes 3 OLED display modules, 5 female-to-female and 5 male-to-female jumper wires; controller boards, breadboards and enclosures are not included, and multiple displays on one I2C bus require unique addresses where supported or an I2C multiplexer
Example: draw a QR code on a 128×64 I2C SSD1306
Install the Adafruit GFX Library, Adafruit SSD1306, and QRCode library in the Arduino IDE’s Library Manager. Connect the OLED using the I2C pins for your board, then upload this sketch. The sample initializes the display at address 0x3C; change that address if your particular module uses another one.
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <qrcode.h>
#define OLED_WIDTH 128
#define OLED_HEIGHT 64
#define OLED_RESET -1
#define OLED_ADDRESS 0x3C
const uint8_t QR_VERSION = 3;
const uint8_t QUIET_ZONE = 4;
const char payload[] = "https://example.com";
Adafruit_SSD1306 display(OLED_WIDTH, OLED_HEIGHT, &Wire, OLED_RESET);
QRCode qr;
uint8_t qrBuffer[qrcode_getBufferSize(QR_VERSION)];
void setup() {
if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDRESS)) {
while (true) {}
}
display.clearDisplay();
qrcode_initText(&qr, qrBuffer, QR_VERSION, ECC_LOW, payload);
const int totalModules = qr.size + 2 * QUIET_ZONE;
const int scaleX = OLED_WIDTH / totalModules;
const int scaleY = OLED_HEIGHT / totalModules;
const int scale = (scaleX < scaleY) ? scaleX : scaleY;
if (scale < 1) {
display.display();
return;
}
const int drawnSize = totalModules * scale;
const int originX = (OLED_WIDTH - drawnSize) / 2 + QUIET_ZONE * scale;
const int originY = (OLED_HEIGHT - drawnSize) / 2 + QUIET_ZONE * scale;
for (uint8_t y = 0; y < qr.size; y++) {
for (uint8_t x = 0; x < qr.size; x++) {
if (qrcode_getModule(&qr, x, y)) {
display.fillRect(originX + x * scale,
originY + y * scale,
scale, scale, SSD1306_WHITE);
}
}
}
display.display();
}
void loop() {
}
Replace payload with the text or URL you want encoded. QR_VERSION selects the QR symbol size; the example uses version 3. Keep the payload within the selected version’s capacity for the chosen error-correction level. If you change the version, the buffer size is derived from it by qrcode_getBufferSize(). The code clears the display before drawing, leaving the quiet-zone area blank.
Rank #2
- 0.96 inch,Resolution: 128 x 64, View angle: > 160°, Support voltage: 3.3V-5V DC, Power consumption: 0.04W during normal operation, full screen lit 0.08W
- Embedded Driver IC: SSD1306. Communication: I2C/IIC Interface, only need two I / O ports
- It compatibles with Arduino Nano, R3 board and Mega, Raspberry pi, 51 MCU, STIM 32, etc.
- No backlight is required, and the display unit can be self-luminous. It has ultra-high contrast, bright and clear dots, and it is easy to read even small fonts
- There are no fonts embedded in the OLED controller, users can create fonts through font generation software.
How to simulate the OLED without connecting it
An SSD1306 host emulator can help you inspect the rendered frame while iterating on the sketch. The documented emulator approaches include saving display frames as numbered PNG files, combining frames into an animated GIF, or rendering them through pygame. An Adafruit SSD1306 emulator project also describes forwarding display bytes over serial for processing on the host.
- Choose an emulator compatible with the display library and output method you intend to use.
- Build or configure the sketch for that emulator’s capture or serial-forwarding workflow.
- Inspect the captured frame or host rendering for a centered symbol, square modules, and clear space around the code.
- Once the display output looks right, test with the actual OLED and a QR scanner.
Emulation is useful for checking drawing behavior; it should not be treated as proof that the sketch matches every board’s electrical behavior, I2C address, or timing.
Rank #3
- UCTRONICS 0.96 Inch OLED Module for showing graphical & textual information directly on your micro-controller projects. It supports many chips: Arduino UNO and Mega, Raspberry pi, 51 MCU, STIM 32, etc., the UNO shown in the picture is NOT INCLUDE
- Resolution: 128 x 64, View angle: > 160°, Support voltage: 3.3V-5V DC, Power consumption: 0.04W during normal operation, full screen lit 0.08W
- Embedded Driver IC: SSD1306. Communication: I2C/IIC Interface, only need two I / O ports
- Needn't backlight, the oled screen unit can self-luminous. It has Super High Contrast, bright and crisp dots, even tiny fonts quite readable
- No embedded fonts inside the OLED controller, user can create the fonts through the font generation software. We offer technical support and software library as well as the guide book in the package. Note: the display part is 15mm±0.5 tall.
Check the OLED and wiring before troubleshooting the QR
A 0.96-inch I2C SSD1306 module in 128×64 form is a direct hardware match for the example. Confirm the controller and resolution, then verify that the sketch uses the correct bus, board pins, voltage level, and I2C address for your specific module. The display library also supports 128×32 panels, but their shorter height leaves less room for a QR symbol and its clear border.
Quick Recap
Best Value
- 0.96 inch,Resolution: 128 x 64, View angle: > 160°, Support voltage: 3.3V-5V DC, Power consumption: 0.04W during normal operation, full screen lit 0.08W
- Embedded Driver IC: SSD1306. Communication: I2C/IIC Interface, only need two I / O ports
- It compatibles with R3 board and Mega, Raspberry pi, 51 MCU, STIM 32, etc.
- No backlight is required, and the display unit can be self-luminous. It has ultra-high contrast, bright and clear dots, and it is easy to read even small fonts
- There are no fonts embedded in the OLED controller, users can create fonts through font generation software.
Rank #4
- Three White OLED Displays For More Projects: Build multiple sensor monitors, status panels or classroom demonstrations at the same time, or keep spare modules ready for testing; each 0.96-inch screen provides 128 × 64 pixels
- White Monochrome OLED For Clear Status Information: Active pixels display white on the dark OLED panel for text, numbers, icons and simple graphics; the display color is fixed by the panel and the screen does not support touch input
- Four-Wire I2C Connection Saves Controller Pins: Connect GND, VCC, SCL and SDA according to the module labels and use the default 7-bit I2C address 0x3C with compatible software libraries
- 3.3–5 V Power For Controller Projects: Add compact visual feedback to compatible microcontroller and single-board-computer projects while verifying pin order, supply voltage, I2C logic levels, pull-up voltage and SSD1306 software configuration before powering
- Three Modules Plus Ten Jumper Wires: Includes 3 OLED display modules, 5 female-to-female and 5 male-to-female jumper wires for prototyping; controller boards, breadboards, sensors, headers and enclosures are not included
Common problems and fixes
- The display stays blank: check power, ground, the board’s I2C wiring, and the module address. The example uses
0x3C, which may not match every module. - The code is clipped or too small: the fit calculation uses both screen dimensions and the quiet zone. Try a smaller QR version or shorter payload, or use a larger display.
- The image appears stretched: keep each module square by using one integer scale for both axes rather than calculating separate horizontal and vertical scales.
- The OLED image looks correct but will not scan: test the physical display with a scanner and check focus, contrast, module size, and the blank border. A host-rendered frame does not establish that a real camera can read the OLED.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

