ESP32 (25) – Oled display with U8G2

luca 30/10/2017 2

If you read my post ESP32, Wemos or not to Wemos you know that I brought a development board, that happened to be a D-duino-32 clone, with an ESP-WROOM-32 module and a 0.96″ oled display.

This display, available also as a standalone module on several websites (for example on Banggood), has the following features:

  • size: 0.96 inches
  • resolution: 128×64 pixels
  • controller: SSD1306 with I2C interface
  • power supply: 3.3V – 6V

u8g2-00a u8g2-00b

It’s very easy to interface it with the esp32 chip thanks to the work of olikraus and Neil Kolban. The first wrote the u8g2 library, while the second implemented the specific functions of the u8g2’s hardware abstraction layer (HAL) for the esp32.

u8g2, installation

u8g2 is a fantastic library for monochrome displays: it supports several types of displays and controllers, it’s easy to port to new platforms and offers many methods to draw geometric figures, display images and write strings using different fonts.

Let’s learn how to use it in your project. First download the archive with the content of the library’s Github repository:


If it doesn’t exist, create the components folder in the main folder of your project. Unzip the archive into that folder and rename the subfolder u8g2-master in u8g2:


In the u8g2 folder create a file named with the following content:


Now download the files u8g2_esp32_hal.c and u8g2_esp32_hal.h from nkolban’s repository:


You can copy the two files in the main folder of your project:


u8g2, configuration

To use the u8g2 library in your program, first include the header file:

#include "u8g2_esp32_hal.h"

The HAL configuration is stored in the u8g2_esp32_hal_t struct:

typedef struct {
  gpio_num_t clk;
  gpio_num_t mosi;
  gpio_num_t sda;
  gpio_num_t scl;
  gpio_num_t cs;
  gpio_num_t reset;
  gpio_num_t dc;
} u8g2_esp32_hal_t;

The library supports both I2C and SPI displays: this is the reason why you see in the struct fields related to the two buses.

You can define and initialize the struct with default values with:

u8g2_esp32_hal_t u8g2_esp32_hal = U8G2_ESP32_HAL_DEFAULT;

The oled display of the D-duino-32 board has an I2C interface connected to esp32’s pin 4 (SCL) and 5 (SDA):

u8g2_esp32_hal.sda = 5;
u8g2_esp32_hal.scl = 4;

When the configuration of the struct is complete, you can use the u8g2_esp32_hal_init() method:


Now move to the configuration of the u8g2 library. Define an u8g2_t variable:

u8g2_t u8g2;

Based on the display you’re using, you have to choose the correct setup function. The parameters for the function are:

  • the pointer to the u8g2_t variable you defined before
  • a constant value that specifies the display rotation
  • two HAL functions to send data on the bus and to delay

The constants for the display roation are:


and the two HAL functions developed by Kolban are:

  • u8g2_esp32_msg_i2c_cb
  • u8g2_esp32_msg_i2c_and_delay_cb

Here I’m using the setup function for the ssd1306 “noname” controller with the _f prefix that means full framebuffer:

  &u8g2, U8G2_R0,


full framebuffer means that all the data to send to the display are stored in the RAM memory of the microcontroller. This makes easier and faster to work with the display but consumes more RAM. The u8g2 library also supports a page buffer mode to save some memory. A comparison between the different modes, with pros and cons, is available on the library’s wiki.

Finally – if you’re using an I2C display – you have to specify its address (here 0x78):


u8g2, use

After the setup, initialize the display with:


The display is now in power save mode, to “turn it on” you have to disable this mode with:

u8g2_SetPowerSave(&u8g2, 0);

Now you can call the different methods available to display text, images, shapes. If you’re using the full framebuffer mode, first prepare the buffer in memory and then send it to the display.

Prepare an empty buffer with ClearBuffer():


Now for example use the SetFont() and DrawStr() methods to write a string into the buffer with a specific font:

u8g2_SetFont(&u8g2, u8g2_font_timR14_tf);
u8g2_DrawStr(&u8g2, 2,17,"Hello World!");

and finally display the buffer’s content on the display with:




In the following video I quickly explain how to install the library, how to prepare an image to be displayed and in the end you can see the execution, on my D-duino-32, of the example program available on Github.


  1. Jabes Cândido da Silva 28/03/2018 at 16:53 - Reply

    Hi, congratulations on the explanations. I’m testing this example with a heltec module, and am having the following error at compile time:

    C:/msys32/home/jabes/esp-idf/examples/lucca_exemplos/esp32-tutorial-master/18_u8g2/main/u8g2_esp32_hal.c:79:14: error: ‘spi_transaction_t {aka struct spi_transaction_t}’ has no member named ‘command’
    trans_desc.command = 0;
    make[1]: *** [/home/jabes/esp-idf/make/ u8g2_esp32_hal.o] Error 1
    make: *** [C:/msys32/home/jabes/esp-idf/make/ component-main-build] Error 2

    What do you think it can be?

    • luca 03/05/2018 at 13:35 - Reply

      Hi, ESP changed something in the framework… you should use the updated version of the u8g2 hal

Leave A Response »

This website uses cookies to ensure you get the best experience on our website maggiori informazioni

Questo sito utilizza i cookie per fonire la migliore esperienza di navigazione possibile. Continuando a utilizzare questo sito senza modificare le impostazioni dei cookie o clicchi su "Accetta" permetti al loro utilizzo.