{"id":32104846,"url":"https://github.com/meshtastic/esp8266-oled-ssd1306","last_synced_at":"2025-10-20T05:02:40.788Z","repository":{"id":44786267,"uuid":"241775403","full_name":"meshtastic/esp8266-oled-ssd1306","owner":"meshtastic","description":"Driver for the SSD1306 and SH1106 based 128x64, 128x32, 64x48 pixel OLED display running on ESP8266/ESP32","archived":false,"fork":true,"pushed_at":"2025-09-13T21:06:28.000Z","size":1569,"stargazers_count":10,"open_issues_count":0,"forks_count":17,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-10-02T09:36:10.348Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://thingpulse.com","language":"C++","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"ThingPulse/esp8266-oled-ssd1306","license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/meshtastic.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"license","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2020-02-20T02:31:54.000Z","updated_at":"2025-09-25T18:48:09.000Z","dependencies_parsed_at":"2023-02-10T18:40:12.503Z","dependency_job_id":"dedfa6b5-4963-446b-a5a7-07a7f3168d5d","html_url":"https://github.com/meshtastic/esp8266-oled-ssd1306","commit_stats":{"total_commits":327,"total_committers":53,"mean_commits":6.169811320754717,"dds":0.7920489296636086,"last_synced_commit":"b38094e03dfa964fbc0e799bc374e91a605c1223"},"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/meshtastic/esp8266-oled-ssd1306","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meshtastic%2Fesp8266-oled-ssd1306","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meshtastic%2Fesp8266-oled-ssd1306/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meshtastic%2Fesp8266-oled-ssd1306/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meshtastic%2Fesp8266-oled-ssd1306/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/meshtastic","download_url":"https://codeload.github.com/meshtastic/esp8266-oled-ssd1306/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meshtastic%2Fesp8266-oled-ssd1306/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280014593,"owners_count":26258647,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-20T02:00:06.978Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-10-20T05:01:34.055Z","updated_at":"2025-10-20T05:02:40.782Z","avatar_url":"https://github.com/meshtastic.png","language":"C++","funding_links":[],"categories":["C++"],"sub_categories":[],"readme":"# ThingPulse OLED SSD1306 (ESP8266/ESP32/Mbed-OS)\n\n[![PlatformIO Registry](https://badges.registry.platformio.org/packages/thingpulse/library/ESP8266%20and%20ESP32%20OLED%20driver%20for%20SSD1306%20displays.svg)](https://registry.platformio.org/libraries/thingpulse/ESP8266%20and%20ESP32%20OLED%20driver%20for%20SSD1306%20displays)\n[![Build Status](https://github.com/ThingPulse/esp8266-oled-ssd1306/actions/workflows/main.yml/badge.svg)](https://github.com/ThingPulse/esp8266-oled-ssd1306/actions)\n\nThis is a driver for SSD1306 128x64, 128x32, 64x48 and 64x32 OLED displays running on the Arduino/ESP8266 \u0026 ESP32 and mbed-os platforms.\nCan be used with either the I2C or SPI version of the display.\n\nThis library drives the OLED display included in the [ThingPulse IoT starter kit](https://thingpulse.com/product/esp8266-iot-electronics-starter-kit-weatherstation-planespotter-worldclock/) aka classic kit aka weather station kit.\n\n[![ThingPulse ESP8266 WeatherStation Classic Kit](https://github.com/ThingPulse/esp8266-weather-station/blob/master/resources/ThingPulse-ESP8266-Weather-Station.jpeg?raw=true)](https://thingpulse.com/product/esp8266-iot-electronics-starter-kit-weatherstation-planespotter-worldclock/)\n\nYou can either download this library as a zip file and unpack it to your Arduino/libraries folder or find it in the Arduino library manager under \"ESP8266 and ESP32 Oled Driver for SSD1306 display\". For mbed-os a copy of the files are available as an mbed-os library.\n\nIt is also available as a [PlatformIO library](https://platformio.org/lib/show/2978/ESP8266%20and%20ESP32%20OLED%20driver%20for%20SSD1306%20displays/examples). Just execute the following command:\n```\nplatformio lib install 2978\n```\n\n## Service level promise\n\n\u003ctable\u003e\u003ctr\u003e\u003ctd\u003e\u003cimg src=\"https://thingpulse.com/assets/ThingPulse-open-source-prime.png\" width=\"150\"\u003e\n\u003c/td\u003e\u003ctd\u003eThis is a ThingPulse \u003cem\u003eprime\u003c/em\u003e project. See our \u003ca href=\"https://thingpulse.com/about/open-source-commitment/\"\u003eopen-source commitment declaration\u003c/a\u003e for what this means.\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\n## Credits\n\nThis library has initially been written by [Daniel Eichhorn](https://github.com/squix78). Many thanks go to [Fabrice Weinberg](https://github.com/FWeinb) for optimizing and refactoring many aspects of the library. Also many thanks to the many committers who helped to add new features and who fixed many bugs. Mbed-OS support and other improvements were contributed by [Helmut Tschemernjak](https://github.com/helmut64).\n\nThe init sequence for the SSD1306 was inspired by Adafruit's library for the same display.\n\n## mbed-os\nThis library has been adopted to support the ARM mbed-os environment. A copy of this library is available in mbed-os under the name OLED_SSD1306 by Helmut Tschemernjak. An alternate installation option is to copy the following files into your mbed-os project: OLEDDisplay.cpp OLEDDisplay.h OLEDDisplayFonts.h OLEDDisplayUi.cpp OLEDDisplayUi.h SSD1306I2C.h\n\n## Usage\n\nCheck out the examples folder for a few comprehensive demonstrations how to use the library. Also check out the [ESP8266 Weather Station](https://github.com/ThingPulse/esp8266-weather-station) library which uses the OLED library to display beautiful weather information.\n\n## Upgrade\n\nThe API changed a lot with the 3.0 release. If you were using this library with older versions please have a look at the [Upgrade Guide](UPGRADE-3.0.md).\n\nGoing from 3.x version to 4.0 a lot of internals changed and compatibility for more displays was added. Please read the [Upgrade Guide](UPGRADE-4.0.md).\n\n## Features\n\n* Draw pixels at given coordinates\n* Draw lines from given coordinates to given coordinates\n* Draw or fill a rectangle with given dimensions\n* Draw Text at given coordinates:\n * Define Alignment: Left, Right and Center\n * Set the Fontface you want to use (see section Fonts below)\n * Limit the width of the text by an amount of pixels. Before this widths will be reached, the renderer will wrap the text to a new line if possible\n* Display content in automatically side scrolling carousel\n * Define transition cycles\n * Define how long one frame will be displayed\n * Draw the different frames in callback methods\n * One indicator per frame will be automatically displayed. The active frame will be displayed from inactive once\n\n## Fonts\n\nFonts are defined in a proprietary but open format. You can create new font files by choosing from a given list\nof open sourced Fonts from this web app: http://oleddisplay.squix.ch\nChoose the font family, style and size, check the preview image and if you like what you see click the \"Create\" button. This will create the font array in a text area form where you can copy and paste it into a new or existing header file.\n\n\n![FontTool](https://github.com/squix78/esp8266-oled-ssd1306/raw/master/resources/FontTool.png)\n\n## Hardware Abstraction\n\nThe library supports different protocols to access the OLED display. Currently there is support for I2C using the built in Wire.h library, I2C by using the much faster [BRZO I2C library](https://github.com/pasko-zh/brzo_i2c) written in assembler and it also supports displays which come with the SPI interface.\n\n### I2C with Wire.h\n\n```C++\n#include \u003cWire.h\u003e\n#include \"SSD1306Wire.h\"\n\n// for 128x64 displays:\nSSD1306Wire display(0x3c, SDA, SCL);  // ADDRESS, SDA, SCL\n// for 128x32 displays:\n// SSD1306Wire display(0x3c, SDA, SCL, GEOMETRY_128_32);  // ADDRESS, SDA, SCL, GEOMETRY_128_32 (or 128_64)\n// for using 2nd Hardware I2C (if available)\n// SSD1306Wire(0x3c, SDA, SCL, GEOMETRY_128_64, I2C_TWO); //default value is I2C_ONE if not mentioned\n// By default SD1306Wire set I2C frequency to 700000, you can use set either another frequency or skip setting the frequency by providing -1 value\n// SSD1306Wire(0x3c, SDA, SCL, GEOMETRY_128_64, I2C_ONE, 400000); //set I2C frequency to 400kHz\n// SSD1306Wire(0x3c, SDA, SCL, GEOMETRY_128_64, I2C_ONE, -1); //skip setting the I2C bus frequency\n```\n\nfor a SH1106:\n```C++\n#include \u003cWire.h\u003e\n#include \"SH1106Wire.h\"\n\nSH1106Wire display(0x3c, SDA, SCL);  // ADDRESS, SDA, SCL\n// By default SH1106Wire set I2C frequency to 700000, you can use set either another frequency or skip setting the frequency by providing -1 value\n// SH1106Wire(0x3c, SDA, SCL, GEOMETRY_128_64, I2C_ONE, 400000); //set I2C frequency to 400kHz\n// SH1106Wire(0x3c, SDA, SCL, GEOMETRY_128_64, I2C_ONE, -1); //skip setting the I2C bus frequency\n```\n\n### I2C with brzo_i2c\n\n```C++\n#include \u003cbrzo_i2c.h\u003e\n#include \"SSD1306Brzo.h\"\n\nSSD1306Brzo display(0x3c, SDA, SCL);  // ADDRESS, SDA, SCL\n```\nor for the SH1106:\n```C++\n#include \u003cbrzo_i2c.h\u003e\n#include \"SH1106Brzo.h\"\n\nSH1106Brzo display(0x3c, SDA, SCL);  // ADDRESS, SDA, SCL\n```\n\n### SPI\n\n```C++\n#include \u003cSPI.h\u003e\n#include \"SSD1306Spi.h\"\n\nSSD1306Spi display(D0, D2, D8);  // RES, DC, CS\n```\nor for the SH1106:\n```C++\n#include \u003cSPI.h\u003e\n#include \"SH1106Spi.h\"\n\nSH1106Spi display(D0, D2, CS);  // RES, DC, CS\n```\n\nIn case the CS pin is not used (hard wired to ground), pass CS as -1.\n\n## API\n\n### Display Control\n\n```C++\n// Initialize the display\nvoid init();\n\n// Free the memory used by the display\nvoid end();\n\n// Cycle through the initialization\nvoid resetDisplay(void);\n\n// Connect again to the display through I2C\nvoid reconnect(void);\n\n// Turn the display on\nvoid displayOn(void);\n\n// Turn the display offs\nvoid displayOff(void);\n\n// Clear the local pixel buffer\nvoid clear(void);\n\n// Write the buffer to the display memory\nvoid display(void);\n\n// Inverted display mode\nvoid invertDisplay(void);\n\n// Normal display mode\nvoid normalDisplay(void);\n\n// Set display contrast\n// really low brightness \u0026 contrast: contrast = 10, precharge = 5, comdetect = 0\n// normal brightness \u0026 contrast:  contrast = 100\nvoid setContrast(uint8_t contrast, uint8_t precharge = 241, uint8_t comdetect = 64);\n\n// Convenience method to access\nvoid setBrightness(uint8_t);\n\n// Turn the display upside down\nvoid flipScreenVertically();\n\n// Draw the screen mirrored\nvoid mirrorScreen();\n```\n\n## Pixel drawing\n\n```C++\n\n/* Drawing functions */\n// Sets the color of all pixel operations\n// color : BLACK, WHITE, INVERSE\nvoid setColor(OLEDDISPLAY_COLOR color);\n\n// Draw a pixel at given position\nvoid setPixel(int16_t x, int16_t y);\n\n// Draw a line from position 0 to position 1\nvoid drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1);\n\n// Draw the border of a rectangle at the given location\nvoid drawRect(int16_t x, int16_t y, int16_t width, int16_t height);\n\n// Fill the rectangle\nvoid fillRect(int16_t x, int16_t y, int16_t width, int16_t height);\n\n// Draw the border of a circle\nvoid drawCircle(int16_t x, int16_t y, int16_t radius);\n\n// Fill circle\nvoid fillCircle(int16_t x, int16_t y, int16_t radius);\n\n// Draw an empty triangle i.e. only the outline\nvoid drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2);\n\n// Draw a solid triangle i.e. filled\nvoid fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2);\n\n// Draw a line horizontally\nvoid drawHorizontalLine(int16_t x, int16_t y, int16_t length);\n\n// Draw a lin vertically\nvoid drawVerticalLine(int16_t x, int16_t y, int16_t length);\n\n// Draws a rounded progress bar with the outer dimensions given by width and height. Progress is\n// a unsigned byte value between 0 and 100\nvoid drawProgressBar(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t progress);\n\n// Draw a bitmap in the internal image format\nvoid drawFastImage(int16_t x, int16_t y, int16_t width, int16_t height, const uint8_t *image);\n\n// Draw a XBM\nvoid drawXbm(int16_t x, int16_t y, int16_t width, int16_t height, const uint8_t *xbm);\n```\n\n## Text operations\n\n``` C++\n// Draws a string at the given location, returns how many chars have been written\nuint16_t drawString(int16_t x, int16_t y, const String \u0026text);\n\n// Draws a String with a maximum width at the given location.\n// If the given String is wider than the specified width\n// The text will be wrapped to the next line at a space or dash\n// returns 0 if everything fits on the screen or the numbers of characters in the\n// first line if not\nuint16_t drawStringMaxWidth(int16_t x, int16_t y, uint16_t maxLineWidth, const String \u0026text);\n\n// Returns the width of the const char* with the current\n// font settings\nuint16_t getStringWidth(const char* text, uint16_t length, bool utf8 = false);\n\n// Convencience method for the const char version\nuint16_t getStringWidth(const String \u0026text);\n\n// Specifies relative to which anchor point\n// the text is rendered. Available constants:\n// TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER, TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER_BOTH\nvoid setTextAlignment(OLEDDISPLAY_TEXT_ALIGNMENT textAlignment);\n\n// Sets the current font. Available default fonts\n// ArialMT_Plain_10, ArialMT_Plain_16, ArialMT_Plain_24\n// Or create one with the font tool at http://oleddisplay.squix.ch\nvoid setFont(const uint8_t* fontData);\n```\n\n## Ui Library (OLEDDisplayUi)\n\nThe Ui Library is used to provide a basic set of user interface elements called `Frames` and `Overlays`. A `Frame` is used to provide\ninformation to the user. The default behaviour is to display a `Frame` for a defined time and than move to the next `Frame`. The library also\nprovides an `Indicator` element that will be updated accordingly. An `Overlay` on the other hand is a piece of information (e.g. a clock) that\nis always displayed at the same position.\n\n```C++\n/**\n * Initialise the display\n */\nvoid init();\n\n/**\n * Configure the internal used target FPS\n */\nvoid setTargetFPS(uint8_t fps);\n\n/**\n * Enable automatic transition to next frame after the some time can be configured with\n * `setTimePerFrame` and `setTimePerTransition`.\n */\nvoid enableAutoTransition();\n\n/**\n * Disable automatic transition to next frame.\n */\nvoid disableAutoTransition();\n\n/**\n * Set the direction if the automatic transitioning\n */\nvoid setAutoTransitionForwards();\nvoid setAutoTransitionBackwards();\n\n/**\n *  Set the approx. time a frame is displayed\n */\nvoid setTimePerFrame(uint16_t time);\n\n/**\n * Set the approx. time a transition will take\n */\nvoid setTimePerTransition(uint16_t time);\n\n/**\n * Draw the indicator.\n * This is the default state for all frames if\n * the indicator was hidden on the previous frame\n * it will be slided in.\n */\nvoid enableIndicator();\n\n/**\n * Don't draw the indicator.\n * This will slide out the indicator\n * when transitioning to the next frame.\n */\nvoid disableIndicator();\n\n/**\n * Enable drawing of all indicators.\n */\nvoid enableAllIndicators();\n\n/**\n * Disable drawing of all indicators.\n */\nvoid disableAllIndicators();\n\n/**\n * Set the position of the indicator bar.\n */\nvoid setIndicatorPosition(IndicatorPosition pos);\n\n/**\n * Set the direction of the indicator bar. Defining the order of frames ASCENDING / DESCENDING\n */\nvoid setIndicatorDirection(IndicatorDirection dir);\n\n/**\n * Set the symbol to indicate an active frame in the indicator bar.\n */\nvoid setActiveSymbol(const uint8_t* symbol);\n\n/**\n * Set the symbol to indicate an inactive frame in the indicator bar.\n */\nvoid setInactiveSymbol(const uint8_t* symbol);\n\n/**\n * Configure what animation is used to transition from one frame to another\n */\nvoid setFrameAnimation(AnimationDirection dir);\n\n/**\n * Add frame drawing functions\n */\nvoid setFrames(FrameCallback* frameFunctions, uint8_t frameCount);\n\n/**\n * Add overlays drawing functions that are draw independent of the Frames\n */\nvoid setOverlays(OverlayCallback* overlayFunctions, uint8_t overlayCount);\n\n/**\n * Set the function that will draw each step\n * in the loading animation\n */\nvoid setLoadingDrawFunction(LoadingDrawFunction loadingDrawFunction);\n\n/**\n * Run the loading process\n */\nvoid runLoadingProcess(LoadingStage* stages, uint8_t stagesCount);\n\n// Manual control\nvoid nextFrame();\nvoid previousFrame();\n\n/**\n * Switch without transition to frame `frame`.\n */\nvoid switchToFrame(uint8_t frame);\n\n/**\n * Transition to frame `frame`. When the `frame` number is bigger than the current\n * frame the forward animation will be used, otherwise the backwards animation is used.\n */\nvoid transitionToFrame(uint8_t frame);\n\n// State Info\nOLEDDisplayUiState* getUiState();\n\n// This needs to be called in the main loop\n// the returned value is the remaining time (in ms)\n// you have to draw after drawing to keep the frame budget.\nint8_t update();\n```\n\n## Creating and using XBM bitmaps\n\nIf you want to display your own images with this library, the best way to do this is using a bitmap.\n\nThere are two options to convert an image to a compatible bitmap:\n1. **Using Gimp.**\n   In this case exporting the bitmap in an 1-bit XBM format is sufficient.\n2. **Using a converter website.**\n   You could also use online converter services like e.g. [https://javl.github.io/image2cpp/](https://javl.github.io/image2cpp/). The uploaded image should have the same dimension as the screen (e.g. 128x64). The following output settings should be set:\n    - Draw Mode: Horizontal - 1 bit per pixel\n    - Swap bits in byte: swap checkbox should be checked.\n\nThe resulting bitmap can be put into a header file:\n```C++\nconst unsigned char epd_example [] PROGMEM = {\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ... \n    ...\n};\n```\n\nSubsequently, it can be used like this:\n```C++\ndisplay.clear();\ndisplay.drawXbm(0, 0, 128, 64, epd_example); // assuming your bitmap is 128x64\ndisplay.display();\n```\n\n## Example: SSD1306Demo\n\n### Frame 1\n![DemoFrame1](https://github.com/squix78/esp8266-oled-ssd1306/raw/master/resources/DemoFrame1.jpg)\n\nThis frame shows three things:\n * How to draw an XMB image\n * How to draw static text which is not moved by the frame transition\n * The active/inactive frame indicators\n\n### Frame 2\n![DemoFrame2](https://github.com/squix78/esp8266-oled-ssd1306/raw/master/resources/DemoFrame2.jpg)\n\nCurrently there are one fontface with three sizes included in the library: Arial 10, 16 and 24. Once the converter is published you will be able to convert any ttf font into the used format.\n\n### Frame 3\n\n![DemoFrame3](https://github.com/squix78/esp8266-oled-ssd1306/raw/master/resources/DemoFrame3.jpg)\n\nThis frame demonstrates the text alignment. The coordinates in the frame show relative to which position the texts have been rendered.\n\n### Frame 4\n\n![DemoFrame4](https://github.com/squix78/esp8266-oled-ssd1306/raw/master/resources/DemoFrame4.jpg)\n\nThis shows how to use define a maximum width after which the driver automatically wraps a word to the next line. This comes in very handy if you have longer texts to display.\n\n### SPI version\n\n![SPIVersion](https://github.com/neptune2/esp8266-oled-ssd1306/raw/master/resources/SPI_version.jpg)\n\nThis shows the code working on the SPI version of the display. See demo code for ESP8266 pins used.\n\n## Selection of projects using this library\n\n * [QRCode ESP8266](https://github.com/anunpanya/ESP8266_QRcode) (by @anunpanya)\n * [Scan I2C](https://github.com/hallard/Scan-I2C-WiFi) (by @hallard)\n * [ThingPulse Weather Station](https://github.com/ThingPulse/esp8266-weather-station)\n * [Meshtastic](https://www.meshtastic.org/) - an open source GPS communicator mesh radio\n * Yours?\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeshtastic%2Fesp8266-oled-ssd1306","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmeshtastic%2Fesp8266-oled-ssd1306","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeshtastic%2Fesp8266-oled-ssd1306/lists"}