ESP32 UNO - OLED 128x32

Need a tiny screen for your next build? Put a 128x32 OLED on the ESP32 Uno and show words, numbers, shapes and logos with only two signal wires. The SSD1306 I2C display plugs into the ESP32 Uno form board in a few minutes, and the Adafruit libraries in Arduino IDE do the hard work.

By the end, you can:

  1. Connect an SSD1306 I2C OLED to the SDA and SCL header pins
  2. Print text and numbers on a 128x32 OLED screen
  3. Draw rectangles, circles and triangles with Arduino code
  4. Turn a picture into a bitmap and show it on the ESP32 Uno OLED
  5. Place a word or value exactly in the middle of the screen
ESP32 Uno 128x32 OLED

Components You Need

1×ESP32 Uno-form Board
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×SSD1306 I2C OLED Display 128x32
1×Jumper Wires

Or you can buy the following kits:

1×DIYables Sensor Kit (18 sensors/displays)
Disclosure: Some of the links provided in this section are Amazon affiliate links. We may receive a commission for any purchases made through these links at no additional cost to you.
Additionally, some of these links are for products from our own brand, DIYables .

Meet the 128x32 OLED Module

After this part, you know what each pin of the module is for.

Spec Value
Resolution 128 x 32 pixels (monochrome)
Driver chip SSD1306
Interface I2C (2 signal wires)
Common I2C address 0x3C (some modules use 0x3D)
Backlight None, every pixel gives its own light

OLED Pin Roles

Pin Role Goes to
GND Ground GND on the ESP32 Uno
VCC Power input 3.3V on the ESP32 Uno
SCL I2C clock SCL (GPIO22)
SDA I2C data SDA (GPIO21)
OLED Pinout

※ NOTE THAT:

Pin order is not the same on every OLED board. Read the labels printed on your own module and wire by name, not by position.

The steps here are for SSD1306 I2C modules. A DIYables 128x32 OLED was used for testing, and it ran with no issue.

ESP32 Uno Pinout

On the ESP32 Uno form board, every Uno-style header hole links to a GPIO number, and that number is what the code uses. Find the SDA and SCL holes on the diagram before you connect the screen.

ESP32 Uno pinout diagram

How to Connect

Four jumper wires join the OLED to the board, and then the hardware side is done.

The wiring diagram between ESP32 Uno OLED 128x32

This image is created using Fritzing. Click to enlarge image

※ NOTE THAT:

The wiring diagram may not show the correct wiring for the ESP32 Uno. On the ESP32 Uno, connect VCC to 3.3V, not 5V. We will update the diagram soon. Until then, follow the wiring table and the text on this page, not the picture.

Component Pin ESP32 Uno Pin
VCC 3.3V
GND GND
SDA SDA (GPIO21)
SCL SCL (GPIO22)

Good to know: the A4 and A5 holes on the ESP32 Uno are input-only analog pins (GPIO36 and GPIO39) with no I2C role. Plug the OLED into the separate SDA and SCL header pins. Wire.begin() picks GPIO21 and GPIO22 by itself.

WARNING

Every ESP32 Uno I/O pin is a 3.3V pin and is NOT 5V tolerant. On many OLED boards the I2C pull-up resistors tie SDA and SCL to VCC. Feed the screen from 3.3V so the bus never rises to 5V.

Prepare Arduino IDE for the OLED

When this part is done, the libraries are in place and you know the four setup lines every OLED sketch needs.

Step 1 — Install the SSD1306 library

  1. Open the Libraries panel on the left edge of Arduino IDE.
  2. Search for "SSD1306" and pick the entry from Adafruit.
  3. Press Install.
  • Search for Adafruit SSD1306 created by Adafruit and click the Install button.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32 Dev Module
Library Manager
Type:
All
Topic:
All
Adafruit SSD1306 by Adafruit
SSD1306 oled driver library for monochrome 128x64 and 128x32 displays More info
2.5.9
INSTALL
Newbiely.ino
···
1 void setup() {
Output
Serial Monitor
Ln 1, Col 1
ESP32 Dev Module on COM15
1
  1. A pop-up lists extra libraries it depends on, such as Adafruit GFX. Press Install All.
  • Search for Adafruit GFX Library created by Adafruit and click the Install button.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32 Dev Module
Library Manager
Type:
All
Topic:
All
Adafruit GFX Library by Adafruit
Install this library in addition to the display library for your hardware. More info
1.12.6
INSTALL
Newbiely.ino
···
1 void setup() {
Output
Serial Monitor
Ln 1, Col 1
ESP32 Dev Module on COM15
1

Step 2 — Learn the basic sketch layout

Part Why You Need It
Includes Load Wire (I2C), GFX (drawing) and SSD1306 (screen driver)
Screen size Tell the library the panel is 128 x 32
Display object Link the screen to the I2C bus
oled.begin() Wake the screen at address 0x3C

Add the libraries:

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

Set the panel size:

#define SCREEN_WIDTH 128 // screen is 128 pixels wide #define SCREEN_HEIGHT 32 // screen is 32 pixels tall

Create the display object:

// SSD1306 object on the I2C bus: SDA (GPIO21), SCL (GPIO22) on the ESP32 Uno Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

Start the screen inside setup():

// start the 128x32 screen at I2C address 0x3C if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { Serial.println(F("SSD1306 allocation failed")); // report that the screen did not answer while (true); // stop here so nothing else runs }

With these lines in place, any text, shape or picture call can follow.

ESP32 Uno Code - Show Text on the OLED

This sketch wakes the screen, waits two seconds, and writes "Hello World!" in the small font.

/* * This ESP32 Uno code was developed by newbiely.com * * This ESP32 Uno code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp32-uno/esp32-uno-oled-128x32 */ #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 // screen is 128 pixels wide #define SCREEN_HEIGHT 32 // screen is 32 pixels tall // SSD1306 object on the I2C bus: SDA (GPIO21), SCL (GPIO22) on the ESP32 Uno Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); void setup() { Serial.begin(9600); // start the 128x32 screen at I2C address 0x3C if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { Serial.println(F("SSD1306 allocation failed")); while (true); } delay(2000); // give the screen time to power up oled.clearDisplay(); // blank the buffer oled.setTextSize(1); // smallest font oled.setTextColor(WHITE); // lit pixels for text oled.setCursor(0, 10); // x = 0, y = 10 oled.println("Hello World!"); // put the message in the buffer oled.display(); // push the buffer to the screen } void loop() { }

Upload and Test

  1. First time with this board? Set it up with ESP32 Uno - Getting Started before you continue.
  2. Build the circuit by following the wiring table above.
  3. Plug in the USB Type-C cable between the ESP32 Uno and your computer.
  4. Select the board in Arduino IDE: pick ESP32 Dev Module and the COM port of the board (CH340).
  5. Add the libraries Adafruit SSD1306 and Adafruit GFX if you skipped that part.
  6. Paste the sketch into a new Arduino IDE window.
  7. Press Upload and wait for "Done uploading".
  8. Look at the OLED. After a short pause, "Hello World!" appears near the top left.
  9. Pro tip: Change oled.setTextSize(1) to oled.setTextSize(2) and upload again. A size-2 line holds about 10 characters across this 128-pixel screen, so short labels read better from a distance.

Text Functions at a Glance

Function What It Does
oled.clearDisplay() Switches every pixel off in the buffer
oled.drawPixel(x, y, color) Lights one pixel at x, y
oled.setTextSize(n) Picks a font scale from 1 to 8
oled.setCursor(x, y) Moves the text start point
oled.setTextColor(WHITE) Writes lit text
oled.setTextColor(BLACK, WHITE) Writes dark text on a lit box
oled.println("message") Writes a string
oled.println(number) Writes a number
oled.println(number, HEX) Writes a number in hex
oled.display() Copies the buffer to the panel
oled.startscrollright(start, stop) Slides the content to the right
oled.startscrollleft(start, stop) Slides the content to the left
oled.startscrolldiagright(start, stop) Slides it up and to the right
oled.startscrolldiagleft(start, stop) Slides it up and to the left
oled.stopscroll() Ends any scroll

All drawing calls only edit memory on the ESP32 Uno. The panel changes when oled.display() runs.

ESP32 Uno Code - Draw Shapes on the OLED

This sketch cycles through eight frames: a box, a rounded box, a circle and a triangle, each as an outline and then solid, two seconds apiece.

/* * This ESP32 Uno code was developed by newbiely.com * * This ESP32 Uno code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp32-uno/esp32-uno-oled-128x32 */ #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 // screen is 128 pixels wide #define SCREEN_HEIGHT 32 // screen is 32 pixels tall // SSD1306 object on the I2C bus: SDA (GPIO21), SCL (GPIO22) on the ESP32 Uno Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); void setup() { Serial.begin(9600); // start the 128x32 screen at I2C address 0x3C if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { Serial.println(F("SSD1306 allocation failed")); while (true); } delay(2000); // give the screen time to power up oled.setCursor(0, 0); } void loop() { // rectangle outline oled.clearDisplay(); oled.drawRect(0, 15, 60, 40, WHITE); oled.display(); delay(2000); // solid rectangle oled.clearDisplay(); oled.fillRect(0, 15, 60, 40, WHITE); oled.display(); delay(2000); // rectangle outline with round corners oled.clearDisplay(); oled.drawRoundRect(0, 15, 60, 40, 8, WHITE); oled.display(); delay(2000); // solid rectangle with round corners oled.clearDisplay(); oled.fillRoundRect(0, 15, 60, 40, 8, WHITE); oled.display(); delay(2000); // circle outline oled.clearDisplay(); oled.drawCircle(20, 35, 20, WHITE); oled.display(); delay(2000); // solid circle oled.clearDisplay(); oled.fillCircle(20, 35, 20, WHITE); oled.display(); delay(2000); // triangle outline oled.clearDisplay(); oled.drawTriangle(30, 15, 0, 60, 60, 60, WHITE); oled.display(); delay(2000); // solid triangle oled.clearDisplay(); oled.fillTriangle(30, 15, 0, 60, 60, 60, WHITE); oled.display(); delay(2000); }

Good to know: the shapes in this demo are sized for a taller panel, so the bottom of each one is clipped at row 31. Lower the y value or the height to see the whole shape.

Center Text and Numbers on the OLED

This sketch puts "DIYables" and then the number 21 in the exact middle of the screen, swapping every two seconds.

/* * This ESP32 Uno code was developed by newbiely.com * * This ESP32 Uno code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp32-uno/esp32-uno-oled-128x32 */ #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 // screen is 128 pixels wide #define SCREEN_HEIGHT 32 // screen is 32 pixels tall Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); // SSD1306 on SDA (GPIO21) / SCL (GPIO22) void setup() { Serial.begin(9600); // start the 128x32 screen at I2C address 0x3C if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { Serial.println(F("SSD1306 allocation failed")); while (true); } delay(2000); // give the screen time to power up oled.clearDisplay(); // blank the buffer oled.setTextSize(2); // double-size font oled.setTextColor(WHITE); // lit pixels for text oled.setCursor(0, 10); // start point before centering } void loop() { // show a word in the middle String text = "DIYables"; oledDisplayCenter(text); delay(2000); // show a number in the middle int number = 21; String str = String(number); oledDisplayCenter(str); delay(2000); } void oledDisplayCenter(String text) { int16_t x1; int16_t y1; uint16_t width; uint16_t height; oled.getTextBounds(text, 0, 0, &x1, &y1, &width, &height); // place the text so equal space is left on all sides oled.clearDisplay(); // blank the buffer oled.setCursor((SCREEN_WIDTH - width) / 2, (SCREEN_HEIGHT - height) / 2); oled.println(text); // put the text in the buffer oled.display(); }
Code Part What It Does
oled.setTextSize(2) Uses the double-size font
getTextBounds() Measures the text width and height in pixels
(SCREEN_WIDTH - width) / 2 Finds the left start point
(SCREEN_HEIGHT - height) / 2 Finds the top start point
String(number) Turns a number into text so it can be centered too

The result: any short string or reading lands in the middle of the 128x32 screen.

ESP32 Uno vs UNO R4 for This Project

This table shows what changes when you move the 128x32 OLED from the UNO R4 to the ESP32 Uno.

Item Arduino UNO R4 ESP32 Uno
Logic voltage 5V 3.3V
OLED power pin 5V 3.3V
SDA wire A4 SDA header (GPIO21)
SCL wire A5 SCL header (GPIO22)
Libraries Adafruit SSD1306 + GFX Same libraries, no change
Arduino IDE board Arduino UNO R4 WiFi ESP32 Dev Module
WiFi and Bluetooth WiFi only on the R4 WiFi WiFi + Bluetooth Classic + BLE

The sketches run without any edit. Only two wires move: SDA and SCL go to the dedicated I2C header, and VCC goes to 3.3V.

Find the OLED I2C Address

At the end of this part, you know the exact address your screen answers on.

Use this scanner when the screen stays dark. It lists every device on SDA (GPIO21) and SCL (GPIO22).

// I2C scanner for the ESP32 Uno: checks SDA (GPIO21) / SCL (GPIO22) for devices #include <Wire.h> void setup() { Wire.begin(); Serial.begin(9600); Serial.println("I2C Scanner"); } void loop() { byte error, address; int nDevices; Serial.println("Scanning..."); nDevices = 0; 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); // pause 5 seconds, then scan again }

Set the Serial Monitor to 9600 baud. With one OLED on the bus, you see lines like these:

∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32 Dev Module' on 'COM15')
New Line
9600 baud
I2C Scanner Scanning... I2C device found at address 0x3C ! done Scanning... I2C device found at address 0x3C ! done
Ln 11, Col 1
ESP32 Dev Module on COM15
2

If the scanner prints 0x3D, put 0x3D in the oled.begin() line of every sketch above.

Go Wireless: Send Messages to the OLED from Your Phone

The goal here is a screen you can write to without a USB cable.

The ESP32 Uno has WiFi and Bluetooth built in. Type a message in a chat page on your phone, and the board prints it on the 128x32 OLED. It works well as a desk sign, a door status note, or a small alert panel. You can also mirror the same text to a web monitor page for logging.

Troubleshooting

Problem Possible Cause Solution
No COM port shows in Arduino IDE CH340 driver missing or a charge-only cable Install the CH340 driver and use a USB cable that carries data
Upload stops at Failed to connect or Waiting for download Board did not enter download mode Hold the BOOT button while the upload starts, then let go
Screen stays fully dark SDA and SCL plugged into A4 and A5 Move the wires to the SDA (GPIO21) and SCL (GPIO22) header pins
Serial Monitor prints SSD1306 allocation failed Screen is not at address 0x3C Run the I2C scanner and use the address it finds
Scanner reports No I2C devices found Loose GND or VCC wire, or SDA and SCL swapped Re-seat all four wires and check that SDA goes to GPIO21
Board resets or the screen flickers Weak USB port or long thin jumper wires Use a short cable and a powered USB port
Picture looks like random dots bitmap_width and bitmap_height do not match the array Set both values to the size the converter used
Text sits in the wrong place SCREEN_HEIGHT left at 64 from another sketch Set SCREEN_HEIGHT to 32

FAQ

Where do the OLED SDA and SCL wires go on the ESP32 Uno?

Use the two pins marked SDA and SCL on the header, which are GPIO21 and GPIO22. Wire.begin() selects them on its own, so you never type these pin numbers. The A4 and A5 holes do not carry I2C on this board.

Can the 128x32 OLED run from the ESP32 Uno 3.3V pin?

Yes. SSD1306 modules work from 3.3V, and the screen draws only about 10 to 20 mA. Using 3.3V also keeps the I2C pull-up resistors at a level that is safe for the ESP32 Uno pins.

Is a level shifter needed between the OLED and the ESP32 Uno?

Not when the OLED is powered from 3.3V. The module then talks at 3.3V, which matches the board. Add a level shifter only if your module must run from 5V and its pull-ups connect to 5V.

Do I need to change the Adafruit sketches written for the UNO R4?

No. The Adafruit SSD1306 and GFX libraries support the ESP32 Uno core, so the same code compiles as-is. Only the SDA, SCL and VCC wires move to new pins.

How many characters fit on a 128x32 OLED?

At text size 1, each character is 6 x 8 pixels, so you get about 21 characters on each of 4 lines. At size 2 you get about 10 characters on 2 lines.

Can I use two OLED screens on one ESP32 Uno?

Yes, if they have different I2C addresses, such as 0x3C and 0x3D. Many modules have a solder jumper to change the address. Create two display objects, one for each address.

Can I add a second I2C bus on the ESP32 Uno?

Yes. The ESP32 Uno has two I2C controllers, and the second one can use almost any free I/O pin through Wire1.begin(sda, scl). Do not pick A2 to A5, because they are input only and cannot drive the clock line.

Why does the ESP32 Uno need the CH340 driver?

This board uses a CH340 chip to turn USB into serial. Windows and macOS may not include its driver, so the COM port does not show until you install it.

What if my project needs more pins than the Uno headers give?

The ESP32 Uno has a few extra holes near the power header. GPIO32 and GPIO33 are I/O, PWM and analog pins on ADC1, so they also read sensors while WiFi is on. GPIO15 is I/O, PWM and analog on ADC2. Add header pins to those holes and put the plain GPIO number in your sketch. For this OLED project, GPIO32 or GPIO33 is a good place for an extra button or an analog sensor whose value you show on the screen. Two warnings: GPIO15 and GPIO0 (the IO0 pin at the unused Uno NC position) are boot strapping pins, and a wrong connection can stop the board from booting or uploading code, so use GPIO32/33 first. Never use the six holes under the digital header (SD0 to SD3, CMD, CLK = GPIO6 to GPIO11), because they connect to the flash chip and using them crashes the board.

Can I show sensor readings and WiFi data on this OLED?

Yes. Read the sensor, turn the value into a String, and pass it to the oledDisplayCenter() function from the center sketch. Because the ESP32 Uno has WiFi, you can also show the time from the internet or a message sent from a web page.

※ OUR MESSAGES

  • As freelancers, We are AVAILABLE for HIRE. See how to outsource your project to us
  • Please feel free to share the link of this tutorial. However, Please do not use our content on any other websites. We invested a lot of effort and time to create the content, please respect our work!