Esp32

Display Image on OLED Screen with ESP32 Using Arduino IDE

ESP32 is a small compact microcontroller board with minimum power requirements. In the last couple of years ESP32 gained a tremendous amount of success due to its versatility and ease of use. In many projects where output needs to be displayed on a serial monitor. So instead of doing this we can interface an OLED display with ESP32. This lesson will be a guide to interfacing ESP32 with I2C 0.96” OLED display.

This lesson includes following topics:

1: Introduction to OLED Display

Before moving further first we must know what an OLED (Organic Light Emitting Diode) display is. OLED displays are used as an alternative for LCD. OLED LEDs are used to produce light displays on OLED screens. The LCD screen uses backlight for illuminating its pixels while OLED displays have their own self emissive LEDs. There are hundreds of self-illuminating LEDs. To display images and text brightness of these LEDs can be controlled pixel by pixel.

Now as we know some basics related to OLED display. Next step is to wire ESP32 with an OLED display module.

2: Wiring OLED Display Module to ESP32

The OLED display mainly comes with two different communication protocols. The two protocols are I2C and SPI. The serial peripheral interface (SPI) is generally faster than I2C, but we preferred I2C over SPI protocol as it required less number of pins.

Following image illustrates ESP32 connection diagram with 128×64 pixels (0.96’’) OLED display.

Below is the connection table:

Once ESP32 is interfaced with an OLED display, the next step on the list is install all required libraries for ESP32 programming using Arduino IDE.

3: Installing Required Libraries

Multiple libraries are available in Arduino IDE to program ESP32 with an OLED display. Here we will be using two libraries from Adafruit: SSD1306 and GFX library.

Now in the Arduino IDE open Library Manager and search for the SSD1306 library. Install SSD1306 library by Adafruit from the search bar.

Alternatively, one can also go to: Sketch>Include Library>Manage Libraries

Next library we need to install is the GFX library by Adafruit.

After both libraries are installed successfully, the next step is to check the I2C address where ESP32 is connected.

4: Check OLED Display I2C Address

I2C stands for Inter-Integrated Circuit communication. Using I2C we can interface multiple devices over 2 wires. However, while connecting them every I2C device must use a separate I2C address. This address ranges from 0 to 127. For example, if we have two different I2C devices using the same I2C address they cannot be connected on the same I2C line.

Before interfacing ESP32 with I2C devices, remember to check the I2C address first. To check the I2C address of the connected OLED display connected ESP32 with PC, upload the code given in the article Check I2C Address Using Arduino IDE.

After uploading code I2C address can be seen in the serial monitor. Here in our case the OLED display is connected at I2C address (0x3C).

We will use the mentioned I2C address for the OLED display in Arduino code.

5: Display Image on OLED Screen with ESP32 Using Arduino IDE

First step which is needed to display an image on an OLED screen is to convert the image to a HEX code. Using any online image to HEX converter we can get HEX code against an image.

5.1: Converting Image to HEX Code

To convert an image to HEX code we can use any online tool, or one can also convert image to HEX code using the Windows paint tool. Now follow along the steps for getting HEX code for your image.

Step 1: Click here to visit free image2cpp converter.

Step 2: Select the image which we want to display on OLED.

Step 3: After selecting the image click open.

Step 4: In the image setting set the dimensions to 128 x 64. Brightness can be set according to the image recommended number is somewhere around 150.

Scale the image according to size and for reference see the output preview.

Step 5: Now set the code output format in Arduino code and prefix as bitmap. After that click generate code. Output HEX code can be copied from the output window.

Replace the copied HEX code in Arduino IDE sample code given below.

5.2: Code

Now open the Arduino IDE and paste the given code. Remember to replace the HEX code with the one for the image you need to display on an OLED screen.

/******Linuxhint.COM********/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

static const uint8_t image_HEX_array[1024] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x6f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xfd, 0xb0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xff, 0xfc, 0xe0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xfe, 0x60, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xfe, 0x4f, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xcc, 0x8f, 0x3e, 0x4f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xce, 0x0f, 0x1e, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0x8f, 0xbe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xcd, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xcc, 0xff, 0xe6, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xce, 0x3f, 0x8e, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0x00, 0x0e, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0x80, 0x3e, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xe0, 0x7e, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0x7f, 0xff, 0xff, 0xe3, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xfc, 0xcf, 0xff, 0xff, 0xff, 0xf1, 0xfe, 0x3f, 0xf9, 0xff, 0xe3, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xfc, 0xcf, 0xff, 0xff, 0xff, 0xf1, 0xfe, 0x3f, 0xf8, 0xff, 0xc7, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xf8, 0xff, 0x8e, 0xff, 0xff, 0xff, 0xff,
    0xff, 0x0c, 0xcf, 0x8f, 0x3e, 0x47, 0x90, 0x1e, 0x3c, 0x38, 0x1f, 0x8e, 0x1f, 0xff, 0xff, 0xff,
    0xf8, 0x0c, 0xce, 0x03, 0x3e, 0x47, 0x90, 0x06, 0x30, 0x18, 0x1f, 0x1e, 0x07, 0xff, 0xff, 0xff,
    0xf0, 0x3c, 0xcc, 0x03, 0x3e, 0x47, 0x90, 0x06, 0x20, 0x08, 0x3f, 0x1f, 0x81, 0xff, 0xff, 0xff,
    0xf0, 0xfc, 0xcc, 0xf1, 0x3e, 0x60, 0x10, 0xe2, 0x23, 0x88, 0xfe, 0x3f, 0xe1, 0xff, 0xff, 0xff,
    0xf0, 0x3c, 0xcc, 0xf9, 0x3e, 0x60, 0x31, 0xe2, 0x23, 0xc8, 0xfe, 0x3f, 0x81, 0xff, 0xff, 0xff,
    0xf8, 0x1c, 0xcc, 0xf9, 0x3e, 0x60, 0x11, 0xe2, 0x23, 0xc8, 0xfc, 0x7e, 0x07, 0xff, 0xff, 0xff,
    0xff, 0x0c, 0xcc, 0xf9, 0x1c, 0x47, 0x91, 0xe2, 0x23, 0xc8, 0x7c, 0x7e, 0x1f, 0xff, 0xff, 0xff,
    0xff, 0xfc, 0xcc, 0xf9, 0x80, 0xc7, 0x91, 0xe2, 0x23, 0xcc, 0x18, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xfc, 0xcc, 0xf9, 0xc1, 0xc7, 0x91, 0xe2, 0x23, 0xc6, 0x11, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xf3, 0x37, 0xcf, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff

};
void setup() {
  Serial.begin(115200);  //baud rate for serial communication
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  delay(2000); // delay 2 sec
  display.clearDisplay(); // clear display buffer
  display.drawBitmap(0, 0, image_HEX_array, 128, 64, 1);
  display.display();
}
void loop() {
}

Code started by importing necessary libraries that we installed earlier. Two libraries include the wire and Adafruit library. Wire libraries allow us to use I2C while Adafruit helps to display the written text on screen.

Next following command is written:

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

It contains the SCREEN_WIDTH and SCREEN_HEIGHT variables. Using these variables, we defined the size of the OLED display. Here we used a 128×64 OLED display. After that &Wire object is defined for display.

The last parameter contains (-1), this display that the OLED screen we are using doesn’t have an external reset button. In case we have a reset button on the OLED display. We will pass this parameter to a GPIO pin. After pressing the reset button, the OLED screen will display the text.

In the middle of the code, we included the HEX code for the image and after that initialized the I2C communication at I2C address (0x3C) is defined which we have found earlier using I2C scanner code.

In the last lines of code, the HEX array is printed on OLED using the bitmap function.

5.3: Sample Arduino Code for Image Display

Here is a code given for OLED interfacing with ESP32. In the following code template replace the HEX code of the image which you want to show on the OLED screen.

/******Linuxhint.COM********/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

static const uint8_t image_HEX_array[1024] = {
/*******
*******
*******
[PASTE HEX CODE FOR IMAGE HERE]
*******
*******
*******/
};
void setup() {
  Serial.begin(115200);  //baud rate for serial communication
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  delay(2000); // delay 2 sec
  display.clearDisplay(); // clear display buffer
  display.drawBitmap(0, 0, image_HEX_array, 128, 64, 1);
  display.display();
}
void loop() {
}

5.4: Output

Here in output, we can see the Linuxhint official logo design image which we converted into HEX code earlier.

We have successfully displayed images on an OLED I2C display. Using the same steps any image with correct proportion can be displayed on an OLED screen.

Conclusion

An OLED display is a great way of showing outputs without any need for a serial monitor or PC. OLED displays come with two different protocols I2C and SPI. I2C OLED displays are preferred because of a lesser number of wires. This lesson provides all steps required in displaying an image on an OLED I2C display with ESP32 using the Arduino IDE.

About the author

Kashif

I am an Electrical Engineer. I love to write about electronics. I am passionate about writing and sharing new ideas related to emerging technologies in the field of electronics.