First words on the OLED
The glass is 72 pixels by 40. The controller behind it has 132 columns of memory, and the panel is wired to a window inside that — so the constructor you pick is not a detail, it is the whole difference between text and a blank screen.
Install U8g2, not the other one
Use U8g2 by oliver, from the Library Manager. It is the library that has a constructor for this exact panel, which the popular Adafruit SSD1306 library does not — that one is written for 128 × 64 modules and has no notion of the offset this glass needs.
Why the constructor is the whole sketch
The panel is 72 pixels wide and 40 tall. The controller driving it is not: it has 132 columns and 64 rows of display RAM, and the glass is wired to a window somewhere inside that. Nothing in the I²C protocol says where the window starts — the driver has to already know, and that knowledge is baked into the constructor's name.
drawStr(0, 10, …) puts a character in the top-left corner of what you can actually see.Three failures come out of that, and all three look like a broken screen:
- A 128 × 64 constructor writes a picture bigger than the glass, starting in the wrong corner. You get a fragment, or nothing.
- An SSD1306 72 × 40 constructor is the right size and the wrong controller. The two chips have different memory widths — 132 columns against 128 — so a driver written for one applies an offset the other does not want, and the picture lands a few pixels across with a sliver wrapped round the edge.
- The SH1106 72 × 40 constructor is the one this board wants.
The pin order that is not the order you say it
U8G2_SH1106_72X40_WISE_F_SW_I2C u8g2(U8G2_R0, 6, 5);After the rotation, U8g2's software-I²C constructors take clock first, then data — so SCL 6 and then SDA 5. People say "SDA and SCL" out loud and type them in that order, which puts the bus on the wrong two pins and produces exactly the same silence as every other mistake on this page.
The F means a full frame buffer. For a 72 × 40 monochrome panel that is 360
bytes, so there is no reason to use the paged variants on this chip. Draw into
the buffer, then sendBuffer() once.
Forty pixels is not many
drawStr(0, 10, …) places text by its baseline, not its top, so a y of 10
puts a 10-pixel font just inside the top edge and a y of 0 puts it entirely off
the screen. With u8g2_font_6x10_tf you get two comfortable lines of about
twelve characters, or three tight ones.
If a string runs off the right-hand edge, U8g2 clips it silently rather than
wrapping. u8g2.getStrWidth() will tell you how wide it would be before you
draw it, which is the honest way to fit a variable-length reading into 72
pixels.
The code
The smallest sketch that puts words on this screen. The constructor line carries the controller, the panel size and the two pins, and it is the only line most people get wrong.
/* Lonely Binary ESP32-C3 OLED — first words
Tools > Board: ESP32C3 Dev Module
Tools > USB CDC On Boot: Enabled
Library: U8g2 by oliver (Library Manager) */
#include <U8g2lib.h>
// SH1106 controller, 72x40 panel, software I2C.
// Arguments: rotation, clock (SCL), data (SDA).
U8G2_SH1106_72X40_WISE_F_SW_I2C u8g2(U8G2_R0, 6, 5);
void setup() {
u8g2.begin();
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_6x10_tf);
u8g2.drawStr(0, 10, "LONELY");
u8g2.drawStr(0, 22, "BINARY");
u8g2.sendBuffer();
}
void loop() {}The two arguments after the rotation are, in order, the clock pin and the data pin — SCL 6 then SDA 5, which is the opposite order to the way people say "SDA and SCL" out loud. Swap them and the bus goes quiet with no error message.
When it does not work
Run the I²C scanner first. If it reports a device at 0x3C the panel is alive and the problem is the constructor or the pin order; if it reports nothing, the problem is the bus and no display library will help. Those are two different afternoons and the scanner tells you which one you are in.
The wrong controller. An SSD1306 has 128 columns of memory and an SH1106 has 132, so a driver written for the first offsets the window by a different amount than this panel needs. Everything renders, a few pixels across, which reads as a hardware fault and is one word in the constructor.
A 128x64 constructor. That is what almost every OLED tutorial uses, because almost every other module is a 0.96 inch 128x64 — here it writes a picture four times the size of the glass, starting in the wrong corner, and you see whatever fragment happens to land in the window.
The F in the constructor name means a full frame buffer, which for this panel is only 360 bytes and is not the problem. A reset loop with a display attached is usually the supply — check it on USB before blaming the sketch, since a nearly-flat cell browns out under the screen's current draw.
Bridge one pad and the board can read its own cell. Then three conversions in a row, each of them a chance to be wrong by a factor of two.
Battery level, on the screen →Edit this page — content/boards/c3-oled/first-words-on-the-oled.mdx
Questions about this product
See what other owners have asked, and read their solutions.
ESP32-C3 OLED Development Board with Expansion Base
Loading discussions…
Discuss this article
Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.