Library / SDK
ThingPulse/esp8266-oled-ssd1306 avatar
ThingPulse/esp8266-oled-ssd1306

ThingPulse esp8266-oled-ssd1306: one driver, four display geometries, three buses

Driver for the SSD1306 and SH1106 based 128x64, 128x32, 64x48 pixel OLED display running on ESP8266/ESP32

2,179 stars669 forksC++NOASSERTION

At a glance

What is it?
A C++ OLED driver for Arduino, ESP8266, ESP32 and mbed-os that handles SSD1306 and SH1106 panels over I2C or SPI, with a UI layer and a browser based font generator on top.
Who is it for?
This driver earns its place by covering the parts of an OLED project that are tedious rather than hard. Two controller chips, four geometries, three bus options including the fast BRZO assembly library, a text renderer with font generation, and a small UI layer with a scrolling carousel, all in one Arduino library that also installs from PlatformIO or copies into an mbed-os project.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 137 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Two controllers, four geometries, one class hierarchy

The scope statement is precise: a driver for SSD1306 and SH1106 displays at 128x64, 128x32, 64x48 and 64x32 pixels, running on the Arduino, ESP8266, ESP32 and mbed-os platforms, over either I2C or SPI.

Both controller chips matter in practice. SSD1306 is the common one, and SH1106 is what you find on a lot of the cheaper 0.96 inch panels that are otherwise physically identical, which is why a driver that handles both saves you from the classic 2 pixel column offset bug when you swap modules. The four geometries cover the panel sizes that actually ship, and the 64x48 case has its own documentation file in the tree, `README_GEOMETRY_64_48.md`, which tells you that unusual size got enough attention to need a page of its own.

The layering is visible in the file names the README lists for mbed-os: `OLEDDisplay.cpp`, `OLEDDisplay.h`, `OLEDDisplayFonts.h`, `OLEDDisplayUi.cpp`, `OLEDDisplayUi.h` and `SSD1306I2C.h`. So there is a controller-independent base, a font layer, a UI layer, and then a thin bus-specific class on top. That separation is why the same drawing code works on I2C, on BRZO I2C and on SPI.

Installing it three different ways

There are three supported install paths and the README is upfront about all of them. Download the zip and unpack it into your Arduino `libraries` folder. Or find it in the Arduino library manager under the name ESP8266 and ESP32 Oled Driver for SSD1306 display. Or install it as a PlatformIO library:

code
platformio lib install 2978

The PlatformIO registry entry is what that command resolves, library 2978, and the badge at the top of the README points at the registry page for it.

For mbed-os there are two options. A copy of the library exists in mbed-os itself under the name OLED_SSD1306, contributed by Helmut Tschemernjak. Or you can copy six files into your own mbed-os project, which the README lists explicitly: OLEDDisplay.cpp, OLEDDisplay.h, OLEDDisplayFonts.h, OLEDDisplayUi.cpp, OLEDDisplayUi.h and SSD1306I2C.h.

The repository also carries the metadata files each build system expects: `library.properties` and `library.json` for the Arduino and PlatformIO worlds, a `component.mk` for the ESP-IDF build, and a `platformio.ini` and `CMakeLists.txt` at the root. That is a small but meaningful detail, since a library that only ships an Arduino manifest tends to be awkward everywhere else.

Constructor arguments and the things that bite you

The Wire.h example is annotated well enough to be a reference on its own:

C++
SSD1306Wire display(0x3c, SDA, SCL);  // ADDRESS, SDA, SCL
// for 128x32 displays:
// SSD1306Wire display(0x3c, SDA, SCL, GEOMETRY_128_32);  // ADDRESS, SDA, SCL, GEOMETRY_128_32 (or 128_64)

The geometry constant is optional and defaults to 128x64. Further along the constructor line come the bus selection and the I2C frequency, with these cases spelled out in the comments: a second hardware I2C bus via `I2C_TWO`, an explicit clock of 400000 Hz, and the value -1 to leave the bus frequency alone.

C++
// By default SD1306Wire set I2C frequency to 700000, you can use set either another frequency or skip setting the frequency by providing -1 value
// SSD1306Wire(0x3c, SDA, SCL, GEOMETRY_128_64, I2C_ONE, 400000); //set I2C frequency to 400kHz

The SPI version is smaller and has its own trap:

C++
#include <SPI.h>
#include "SSD1306Spi.h"

SSD1306Spi display(D0, D2, D8);  // RES, DC, CS

In case the CS pin is not used, hard wired to ground, you pass CS as -1. That is the kind of detail that only appears in a README written by someone who has connected these panels a few hundred times.

Fonts come from a web app, and the format is proprietary

The font story is the one place where the project asks you to leave your editor. Fonts are defined in what the README calls a proprietary but open format, and you generate them with a web app at oleddisplay.squix.ch: choose the font family, style and size, check the preview image, and click Create. The output is a font array as text that you copy into a new or existing header file.

The feature list explains what the text renderer does with it. You can set alignment to left, right or center, choose the font face, and limit the width in pixels, in which case the renderer wraps text onto a new line if it can before it reaches that limit. Wrapping on a 128 pixel wide monochrome display is a real problem, and having the library handle it rather than doing string arithmetic by hand is the single most useful thing in that list.

The app is hosted under the squix78 account, which is also the author the credits section names as having initially written the library. So the font tool and the driver share an origin even though the tool lives on its own domain now.

The drawing primitives below the text layer are the straightforward ones: pixels at coordinates, lines between coordinates, rectangles drawn or filled, and a UI feature described as an automatically side scrolling carousel where you define transition cycles and how long each frame is displayed, with one indicator per frame.

Credits, service levels, and two upgrade guides

The credits section is unusually specific and worth reading for what it says about the shape of the project. The library was initially written by Daniel Eichhorn, better known as squix78. Fabrice Weinberg is thanked for optimizing and refactoring many aspects of it. Mbed-OS support and other improvements came from Helmut Tschemernjak. And the init sequence for the SSD1306 was inspired by Adafruit's library for the same display.

That last credit matters more than it looks. The initialisation sequence is the part of an OLED driver that everyone copies from somewhere, and this project says where it came from rather than leaving you to guess.

There is a service level section too. The project labels itself a ThingPulse prime project and links to an open source commitment declaration explaining what that means, which is a level of formality you rarely see in a hobby-adjacent driver.

The two upgrade guides are the practical warning. The API changed substantially with the 3.0 release, and moving from 3.x to 4.0 changed a lot of internals and added compatibility for more displays, with both `UPGRADE-3.0.md` and `UPGRADE-4.0.md` in the tree. Code written against the squix78 era of this library will not compile unchanged, and the README asks you to read the relevant guide rather than discover this at compile time.

GitHub reports 2,178 stars, 670 forks and 31 open issues on this C++ project, with the last push on 2026-05-28 and the default branch `master`.

Where the README stops

The README ends at the word API, with the section heading present and nothing under it. Everything a reader needs about the drawing and display methods is therefore somewhere else: the examples folder, or the wiki.

The examples folder is the better of the two, and the material lists eight of them by name: SSD1306ClockDemo, SSD1306DrawingDemo, SSD1306FontTryout, SSD1306OTADemo, SSD1306ScrollVerticalDemo, SSD1306SimpleDemo, SSD1306TwoScreenDemo and SSD1306UiDemo. Between them they cover the full feature list: a clock, raw drawing primitives, fonts, over the air updates, scrolling, the minimal case, driving two panels at once, and the UI layer. Two screens at once is the one that would be hardest to work out on your own.

The README also points at a sibling project, the ESP8266 Weather Station, which uses this library to display weather information and is described as producing beautiful output. It is linked from ThingPulse, the same organisation that sells the IoT starter kit this driver is said to drive the display for.

On the licensing question, GitHub reports the repository license field as NOASSERTION while the tree contains a file named `license` with no extension at all. That is the shape of the metadata being unhelpful rather than the license being absent, and reading the file settles it.

Editorial conclusion

This driver earns its place by covering the parts of an OLED project that are tedious rather than hard. Two controller chips, four geometries, three bus options including the fast BRZO assembly library, a text renderer with font generation, and a small UI layer with a scrolling carousel, all in one Arduino library that also installs from PlatformIO or copies into an mbed-os project. Two practical notes before you commit. The README cuts off exactly where the API reference begins, so the method list lives on the wiki and in the examples folder rather than in the repository front page, and there are separate upgrade guides for both the 3.0 and 4.0 API breaks, which means code written against the 2.x line will need changes. Install it through the Arduino library manager or with `platformio lib install 2978`, then start from SSD1306SimpleDemo and read UPGRADE-4.0.md if you are porting older code.

Frequently asked questions

How do I use the SSD1306 OLED module with Arduino?

Install the library, then include the bus specific header and construct a display object with the I2C address and your pins. For I2C that is `#include "SSD1306Wire.h"` and `SSD1306Wire display(0x3c, SDA, SCL);`. Add a geometry constant as a fourth argument for a 128x32 panel, and start from the SSD1306SimpleDemo example in the examples folder.

What is the difference between SSD1306 and SH1106 support in this driver?

Both are supported as separate header classes, SSD1306Wire and SH1106Wire, for I2C, with the same constructor signature. SH1106 is the controller found on many cheaper 0.96 inch panels, which have a slight column offset compared with SSD1306 panels, so having both classes avoids a display that appears shifted by two pixels after you swap modules.

Can I use this library with ESP32 as well as ESP8266?

Yes. The library targets the Arduino, ESP8266, ESP32 and mbed-os platforms, and the repository topics list both esp8266 and esp32. It installs through the Arduino library manager, through PlatformIO with `platformio lib install 2978`, or as a copy of six named files for mbed-os. A second hardware I2C bus is selectable with the I2C_TWO constructor argument.

How do I create a custom font for the display?

Use the web app at oleddisplay.squix.ch. Pick a font family, style and size, check the preview, and click Create, which produces a font array as text to copy into a header file. The README notes the format is proprietary but open. The SSD1306FontTryout example is the place to see a generated font in use.

Official sources

  1. Issues
  2. Project website
  3. README
  4. Releases
  5. ThingPulse/esp8266-oled-ssd1306 on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/thingpulse-esp8266-oled-ssd1306.svg)](https://hysenlabs.com/projects/thingpulse-esp8266-oled-ssd1306)