In this ESP-IDF tutorial, we will show you how to interface SSD1306 OLED with ESP32. Organic Light Emitting Diode commonly known as OLED is used to display texts, bitmap images, and shapes. Due to its cost-effective nature and great view angle and pixel density. This guide includes a brief introduction to the 0.96-inch OLED display, interfacing with the ESP32 board, and then using SSD1306/SH1106 Driver for ESP-IDF to display texts, scrolling text, images, and animations on the OLED display.
Before we move ahead, make sure you have the latest version of VS Code installed on your system with the ESP-IDF extension configured.
SSD1306 0.96 inch OLED Display Introduction
An OLED is an organic light-emitting diode that consists of two organic thin films connected in series between two electric conductors. There are several versions of OLED displays available in the market. This guide focuses on SSD1306 0.96 inch OLED display which has 128×64 pixels. The SSD1306 controller is the major component of thus display, which allows I2C/SPI communication between microcontrollers. The OLED we will be using communicates through I2C only thus it has four pins that need to be connected with the ESP32 board.
The diagram below shows the pinout of the OLED display we will be using.
As you can view in the pinout above, this OLED has 4 pins. This display requires a driving voltage of 3.3-5V. The VCC and GND pins are the power supply pins of the OLED connected with ESP32 Vin or 3.3V pin. The SCL and SDA pins are the I2C pins required to generate the clock signal and transmit the data respectively. These two pins will be connected with the I2C pins of the ESP32 board.
The table below shows some key specifications of this model.
Size | 0.96 inch |
---|---|
Terminals | 4 |
Pixels | 128×64 |
Communication | I2C only |
VCC | 3.3V-5V |
Operating Temperature | -40℃ to +80℃ |
Refer to the following article for an in-depth introduction to 0.96-inch OLED: Monochrome 0.96” OLED Display
ESP-IDF Interface OLED with ESP32
In this section, we will connect the SSD1306 OLED display with the ESP32 development board. Follow the connections as shown in the table below:
ESP32 board | SSD1306 OLED Display |
---|---|
3.3V or Vin | VCC |
GPIO21(I2C SDA) | SDA |
GPIO22(I2C SCL) | SCL |
GND | GND |
As we mentioned previously, the OLED display requires an operating voltage of 3.3-5V hence we can connect either the 3.3V pin or the Vin pin of the ESP32 module with the VCC pin of the display. The GND pins of both the pins will be common. To connect the I2C pins, we will use the default I2C pins of the ESP32 board. By default in ESP32, GPIO22 is set up as SCL pin and GPIO21 is set up as SDA pin. Therefore, we will connect SDA pin of display with GPIO21 and SCL pin of display with GPIO22.
ESP32 OLED Connection Diagram
The diagram below shows the connections between ESP32 board and OLED display. We have used the same connections as we described above.
ESP-IDF ESP32 OLED Display and Scroll Text
Let’s set up a project in ESP-IDF to test our SSD1306 OLED display. We will demonstrate TextDemo by nopnop2002 uploaded on GitHub at the following link:
These examples use the SSD1306/SH1106 Driver for ESP-IDF.
Create Project
Open your VS Code and head over to View > Command Palette. Type ESP-IDF: New Project in the search bar and press enter.
Specify the project name and directory. We have named our project ‘ESP_IDF_ssd1306_TextDemo.’ For the ESP-IDF board, we have chosen the custom board option. For ESP-IDF target, we have chosen ESP32 module. Click ‘Choose Template’ button to proceed forward.
In the Extension, select ESP-IDF option:
We will click the ‘sample_project’ under the get-started tab. Now click ‘Create project using template sample_project.’
You will get a notification that the project has been created. To open the project in a new window, click ‘Yes.’
Add Libraries
This opens esp-idf project that we created, inside the EXPLORER tab. There are several folders inside our project folder. This is the same for every project which you will create through ESP-IDF Explorer. Create a new folder named ‘components‘ and copy the files from the link given below into your project components folder. This will contain the libraries that will be required for this project.
OLED MenuConfig Settings ESP-IDF
Let’s first head over to the menuconfig. Opens the ESP-IDF SDK Configuration Editor. Scroll down and open the SSD1306 Configuration. Here we can set the SSD1306 configuration parameter according to our needs. This includes the UART interface, panel type, SCL GPIO pin, SDA GPIO pin and the reset GPIO pin. Here you can view that by default, ESP-IDF is using the interface as I2C, panel type as 128×64, SCL GPIO pin as 22, SDA GPIO pin as 21 and Reset GPIO pin as 33. You can alter these parameters according to your OLED display and then click the Save button found at the top. We will leave the configuration settings as default as they match our module.
Alternatively, we can also set this config value with menuconfig. Open menuconfig by typing idf.py menuconfig in the terminal. This command opens the Espressif IoT Development Framework Configuration. Head over to SSD1306 Configuration and set the parameters accordingly.
Code
The main folder contains the source code meaning the main.c file will be found here. Inside the main.c we will write our program code. Go to main > main.c and open it. We will define the functions and the program code here. Copy the code from this link here.
This is our main.c file.
Note: All examples and library for this tutorial are taken from this GitHub repo.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "ssd1306.h"
#include "font8x8_basic.h"
/*
You have to set this config value with menuconfig
CONFIG_INTERFACE
for i2c
CONFIG_MODEL
CONFIG_SDA_GPIO
CONFIG_SCL_GPIO
CONFIG_RESET_GPIO
for SPI
CONFIG_CS_GPIO
CONFIG_DC_GPIO
CONFIG_RESET_GPIO
*/
#define tag "SSD1306"
void app_main(void)
{
SSD1306_t dev;
int center, top, bottom;
char lineChar[20];
#if CONFIG_I2C_INTERFACE
ESP_LOGI(tag, "INTERFACE is i2c");
ESP_LOGI(tag, "CONFIG_SDA_GPIO=%d",CONFIG_SDA_GPIO);
ESP_LOGI(tag, "CONFIG_SCL_GPIO=%d",CONFIG_SCL_GPIO);
ESP_LOGI(tag, "CONFIG_RESET_GPIO=%d",CONFIG_RESET_GPIO);
i2c_master_init(&dev, CONFIG_SDA_GPIO, CONFIG_SCL_GPIO, CONFIG_RESET_GPIO);
#endif // CONFIG_I2C_INTERFACE
#if CONFIG_SPI_INTERFACE
ESP_LOGI(tag, "INTERFACE is SPI");
ESP_LOGI(tag, "CONFIG_MOSI_GPIO=%d",CONFIG_MOSI_GPIO);
ESP_LOGI(tag, "CONFIG_SCLK_GPIO=%d",CONFIG_SCLK_GPIO);
ESP_LOGI(tag, "CONFIG_CS_GPIO=%d",CONFIG_CS_GPIO);
ESP_LOGI(tag, "CONFIG_DC_GPIO=%d",CONFIG_DC_GPIO);
ESP_LOGI(tag, "CONFIG_RESET_GPIO=%d",CONFIG_RESET_GPIO);
spi_master_init(&dev, CONFIG_MOSI_GPIO, CONFIG_SCLK_GPIO, CONFIG_CS_GPIO, CONFIG_DC_GPIO, CONFIG_RESET_GPIO);
#endif // CONFIG_SPI_INTERFACE
#if CONFIG_FLIP
dev._flip = true;
ESP_LOGW(tag, "Flip upside down");
#endif
#if CONFIG_SSD1306_128x64
ESP_LOGI(tag, "Panel is 128x64");
ssd1306_init(&dev, 128, 64);
#endif // CONFIG_SSD1306_128x64
#if CONFIG_SSD1306_128x32
ESP_LOGI(tag, "Panel is 128x32");
ssd1306_init(&dev, 128, 32);
#endif // CONFIG_SSD1306_128x32
ssd1306_clear_screen(&dev, false);
ssd1306_contrast(&dev, 0xff);
ssd1306_display_text_x3(&dev, 0, "Hello", 5, false);
vTaskDelay(3000 / portTICK_PERIOD_MS);
#if CONFIG_SSD1306_128x64
top = 2;
center = 3;
bottom = 8;
ssd1306_display_text(&dev, 0, "SSD1306 128x64", 14, false);
ssd1306_display_text(&dev, 1, "ABCDEFGHIJKLMNOP", 16, false);
ssd1306_display_text(&dev, 2, "abcdefghijklmnop",16, false);
ssd1306_display_text(&dev, 3, "Hello World!!", 13, false);
//ssd1306_clear_line(&dev, 4, true);
//ssd1306_clear_line(&dev, 5, true);
//ssd1306_clear_line(&dev, 6, true);
//ssd1306_clear_line(&dev, 7, true);
ssd1306_display_text(&dev, 4, "SSD1306 128x64", 14, true);
ssd1306_display_text(&dev, 5, "ABCDEFGHIJKLMNOP", 16, true);
ssd1306_display_text(&dev, 6, "abcdefghijklmnop",16, true);
ssd1306_display_text(&dev, 7, "Hello World!!", 13, true);
#endif // CONFIG_SSD1306_128x64
#if CONFIG_SSD1306_128x32
top = 1;
center = 1;
bottom = 4;
ssd1306_display_text(&dev, 0, "SSD1306 128x32", 14, false);
ssd1306_display_text(&dev, 1, "Hello World!!", 13, false);
//ssd1306_clear_line(&dev, 2, true);
//ssd1306_clear_line(&dev, 3, true);
ssd1306_display_text(&dev, 2, "SSD1306 128x32", 14, true);
ssd1306_display_text(&dev, 3, "Hello World!!", 13, true);
#endif // CONFIG_SSD1306_128x32
vTaskDelay(3000 / portTICK_PERIOD_MS);
// Display Count Down
uint8_t image[24];
memset(image, 0, sizeof(image));
ssd1306_display_image(&dev, top, (6*8-1), image, sizeof(image));
ssd1306_display_image(&dev, top+1, (6*8-1), image, sizeof(image));
ssd1306_display_image(&dev, top+2, (6*8-1), image, sizeof(image));
for(int font=0x39;font>0x30;font--) {
memset(image, 0, sizeof(image));
ssd1306_display_image(&dev, top+1, (7*8-1), image, 8);
memcpy(image, font8x8_basic_tr[font], 8);
if (dev._flip) ssd1306_flip(image, 8);
ssd1306_display_image(&dev, top+1, (7*8-1), image, 8);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
// Scroll Up
ssd1306_clear_screen(&dev, false);
ssd1306_contrast(&dev, 0xff);
ssd1306_display_text(&dev, 0, "---Scroll UP---", 16, true);
//ssd1306_software_scroll(&dev, 7, 1);
ssd1306_software_scroll(&dev, (dev._pages - 1), 1);
for (int line=0;line<bottom+10;line++) {
lineChar[0] = 0x01;
sprintf(&lineChar[1], " Line %02d", line);
ssd1306_scroll_text(&dev, lineChar, strlen(lineChar), false);
vTaskDelay(500 / portTICK_PERIOD_MS);
}
vTaskDelay(3000 / portTICK_PERIOD_MS);
// Scroll Down
ssd1306_clear_screen(&dev, false);
ssd1306_contrast(&dev, 0xff);
ssd1306_display_text(&dev, 0, "--Scroll DOWN--", 16, true);
//ssd1306_software_scroll(&dev, 1, 7);
ssd1306_software_scroll(&dev, 1, (dev._pages - 1) );
for (int line=0;line<bottom+10;line++) {
lineChar[0] = 0x02;
sprintf(&lineChar[1], " Line %02d", line);
ssd1306_scroll_text(&dev, lineChar, strlen(lineChar), false);
vTaskDelay(500 / portTICK_PERIOD_MS);
}
vTaskDelay(3000 / portTICK_PERIOD_MS);
// Page Down
ssd1306_clear_screen(&dev, false);
ssd1306_contrast(&dev, 0xff);
ssd1306_display_text(&dev, 0, "---Page DOWN---", 16, true);
ssd1306_software_scroll(&dev, 1, (dev._pages-1) );
for (int line=0;line<bottom+10;line++) {
//if ( (line % 7) == 0) ssd1306_scroll_clear(&dev);
if ( (line % (dev._pages-1)) == 0) ssd1306_scroll_clear(&dev);
lineChar[0] = 0x02;
sprintf(&lineChar[1], " Line %02d", line);
ssd1306_scroll_text(&dev, lineChar, strlen(lineChar), false);
vTaskDelay(500 / portTICK_PERIOD_MS);
}
vTaskDelay(3000 / portTICK_PERIOD_MS);
// Horizontal Scroll
ssd1306_clear_screen(&dev, false);
ssd1306_contrast(&dev, 0xff);
ssd1306_display_text(&dev, center, "Horizontal", 10, false);
ssd1306_hardware_scroll(&dev, SCROLL_RIGHT);
vTaskDelay(5000 / portTICK_PERIOD_MS);
ssd1306_hardware_scroll(&dev, SCROLL_LEFT);
vTaskDelay(5000 / portTICK_PERIOD_MS);
ssd1306_hardware_scroll(&dev, SCROLL_STOP);
// Vertical Scroll
ssd1306_clear_screen(&dev, false);
ssd1306_contrast(&dev, 0xff);
ssd1306_display_text(&dev, center, "Vertical", 8, false);
ssd1306_hardware_scroll(&dev, SCROLL_DOWN);
vTaskDelay(5000 / portTICK_PERIOD_MS);
ssd1306_hardware_scroll(&dev, SCROLL_UP);
vTaskDelay(5000 / portTICK_PERIOD_MS);
ssd1306_hardware_scroll(&dev, SCROLL_STOP);
// Invert
ssd1306_clear_screen(&dev, true);
ssd1306_contrast(&dev, 0xff);
ssd1306_display_text(&dev, center, " Good Bye!!", 12, true);
vTaskDelay(5000 / portTICK_PERIOD_MS);
// Fade Out
ssd1306_fadeout(&dev);
#if 0
// Fade Out
for(int contrast=0xff;contrast>0;contrast=contrast-0x20) {
ssd1306_contrast(&dev, contrast);
vTaskDelay(40);
}
#endif
// Restart module
esp_restart();
}
How the Code Works?
Note: This code is applicable for OLED displays with different panel types and interfaces. The #if #endif conditions will work according to the particular parameter defined. Hence, we will look at those parts which are applicable to our SSD1306 Configuration parameters.
Firstly, the code starts by including the necessary libraries that includes the FreeRTOS libraries to generate delays, ssd1306.h driver for the OLED functionality, font8x8_basic.h which contains 8×8 pixels ASCII font set and esp_log.h for debugging.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "ssd1306.h"
#include "font8x8_basic.h"
Initialize I2C interface and OLED
Inside the app_main() function, firstly the I2C interface is configured. The current settings that we setup in the menuconfig will get printed in the terminal. This includes the interface type, SDA GPIO, SCL GPIO and Reset GPIO. Moreover, the I2C interface will be configured by calling the i2c_master_init() function and passing the address of the SSD1306_t structure, SDA pin, SCL pin and Reset pin as parameters inside it.
#if CONFIG_I2C_INTERFACE
ESP_LOGI(tag, "INTERFACE is i2c");
ESP_LOGI(tag, "CONFIG_SDA_GPIO=%d",CONFIG_SDA_GPIO);
ESP_LOGI(tag, "CONFIG_SCL_GPIO=%d",CONFIG_SCL_GPIO);
ESP_LOGI(tag, "CONFIG_RESET_GPIO=%d",CONFIG_RESET_GPIO);
i2c_master_init(&dev, CONFIG_SDA_GPIO, CONFIG_SCL_GPIO, CONFIG_RESET_GPIO);
#endif // CONFIG_I2C_INTERFACE
The following statement will print the panel type on the terminal. Moreover, it will also initialize the OLED display by calling ssd1306_init() function. This takes in three parameters. The first parameter is the address of the SSD1306_t structure, the second parameter is the width and the third parameter is the height of the display in pixels. We are using a 128×64 display hence the width is 128 and the height is 64.
#if CONFIG_SSD1306_128x64
ESP_LOGI(tag, "Panel is 128x64");
ssd1306_init(&dev, 128, 64);
#endif // CONFIG_SSD1306_128x64
Clear Screen and Set Contrast
Next, we have a few function calls. First the screen of the OLED display is cleared using ssd1306_clear_screen(). This function takes in two parameters. The first is the address of the SSD1306_t structure and the second parameter is invert which is a bool variable. It is set as false. This means we have a dark background and the text will be displayed in white.
ssd1306_clear_screen(&dev, false);
Secondly, the contrast of the screen is set using ssd1306_contrast(). This function takes in two parameters. The first is the address of the SSD1306_t structure and the second parameter is the contrast value which is an int variable. It is set as 0xff.
ssd1306_contrast(&dev, 0xff);
Display Text
Then, the screen displays the text ‘Hello’ by calling the function ssd1306_display_text_x3(). This will be displayed on the screen for three seconds. It takes in five parameters. The first parameter is the address of the SSD1306_t structure. The second parameter is the page number of the composition data which is set as 0. The third parameter is the text that we want to display. It is “Hello” in this case. The fourth parameter is the length of the text which is specified as 5. Lastly, the fifth parameter is invert which is a bool variable. It is set as false. This means we have a dark background and the text will be displayed in white.
ssd1306_display_text_x3(&dev, 0, "Hello", 5, false);
vTaskDelay(3000 / portTICK_PERIOD_MS);
Display Text and Invert
Next we have another block of code for the SSD1306 128×64 configuration. This displays a series of texts that fill the whole screen. We start by defining the top, center and bottom values. Then we call ssd_1306_display_text() several times to display various messages with invert values as both false and true. When the invert is set as false, we have a dark background and the text will be displayed in white. Likewise, when the invert is set as true, we have a bright background and the text is displayed in black. This function takes the same parameters as ssd1306_display_text_x3().
#if CONFIG_SSD1306_128x64
top = 2;
center = 3;
bottom = 8;
ssd1306_display_text(&dev, 0, "SSD1306 128x64", 14, false);
ssd1306_display_text(&dev, 1, "ABCDEFGHIJKLMNOP", 16, false);
ssd1306_display_text(&dev, 2, "abcdefghijklmnop",16, false);
ssd1306_display_text(&dev, 3, "Hello World!!", 13, false);
ssd1306_display_text(&dev, 4, "SSD1306 128x64", 14, true);
ssd1306_display_text(&dev, 5, "ABCDEFGHIJKLMNOP", 16, true);
ssd1306_display_text(&dev, 6, "abcdefghijklmnop",16, true);
ssd1306_display_text(&dev, 7, "Hello World!!", 13, true);
#endif // CONFIG_SSD1306_128x64
Display Numbers
Next we will display a series of numbers in the middle of the screen that will count down form 9 to 0. Each number will stay on the screen for a second and then it will disappear and the next number appears in its place.
// Display Count Down
uint8_t image[24];
memset(image, 0, sizeof(image));
ssd1306_display_image(&dev, top, (6*8-1), image, sizeof(image));
ssd1306_display_image(&dev, top+1, (6*8-1), image, sizeof(image));
ssd1306_display_image(&dev, top+2, (6*8-1), image, sizeof(image));
for(int font=0x39;font>0x30;font--) {
memset(image, 0, sizeof(image));
ssd1306_display_image(&dev, top+1, (7*8-1), image, 8);
memcpy(image, font8x8_basic_tr[font], 8);
if (dev._flip) ssd1306_flip(image, 8);
ssd1306_display_image(&dev, top+1, (7*8-1), image, 8);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
Scroll Up and Down
Now we will scroll some texts up and down the screen. First, we will clear the screen and set the contrast. Then we will display the text “—Scroll UP—“. Then we call the function ssd1306_software_scroll() and pass three parameters inside it. The first parameter is the address of the SSD1306_t structure. The second parameter is start which is set as (dev._pages – 1) and the third parameter is end which is set as 1. Then we use a for loop to display a scrolling text that will start from Line 00 and end at Line 17 while scrolling from bottom to top (scroll up). This will be achieved by using the function ssd1306_scroll_text().
// Scroll Up
ssd1306_clear_screen(&dev, false);
ssd1306_contrast(&dev, 0xff);
ssd1306_display_text(&dev, 0, "---Scroll UP---", 16, true);
ssd1306_software_scroll(&dev, (dev._pages - 1), 1);
for (int line=0;line<bottom+10;line++) {
lineChar[0] = 0x01;
sprintf(&lineChar[1], " Line %02d", line);
ssd1306_scroll_text(&dev, lineChar, strlen(lineChar), false);
vTaskDelay(500 / portTICK_PERIOD_MS);
}
vTaskDelay(3000 / portTICK_PERIOD_MS);
After the scroll up is complete we will move to scroll down. First, we will clear the screen and set the contrast. Then we will display the text “—Scroll DOWN—“. Then we call the function ssd1306_software_scroll() and pass three parameters inside it. The first parameter is the address of the SSD1306_t structure. The second parameter is start which is set as 1 and the third parameter is end which is set as (dev._pages – 1). Then we use a for loop to display a scrolling text that will start from Line 00 and end at Line 17 while scrolling from top to bottom (scroll down). This will be achieved by using the function ssd1306_scroll_text().
// Scroll Down
ssd1306_clear_screen(&dev, false);
ssd1306_contrast(&dev, 0xff);
ssd1306_display_text(&dev, 0, "--Scroll DOWN--", 16, true);
//ssd1306_software_scroll(&dev, 1, 7);
ssd1306_software_scroll(&dev, 1, (dev._pages - 1) );
for (int line=0;line<bottom+10;line++) {
lineChar[0] = 0x02;
sprintf(&lineChar[1], " Line %02d", line);
ssd1306_scroll_text(&dev, lineChar, strlen(lineChar), false);
vTaskDelay(500 / portTICK_PERIOD_MS);
}
vTaskDelay(3000 / portTICK_PERIOD_MS);
Page Down
Next, we have a section of code for page down. It is similar to scrolling down however in this case the texts do not automatically scroll down but when they reach the end of the screen, they disappear and new ones take their place.
// Page Down
ssd1306_clear_screen(&dev, false);
ssd1306_contrast(&dev, 0xff);
ssd1306_display_text(&dev, 0, "---Page DOWN---", 16, true);
ssd1306_software_scroll(&dev, 1, (dev._pages-1) );
for (int line=0;line<bottom+10;line++) {
if ( (line % (dev._pages-1)) == 0) ssd1306_scroll_clear(&dev);
lineChar[0] = 0x02;
sprintf(&lineChar[1], " Line %02d", line);
ssd1306_scroll_text(&dev, lineChar, strlen(lineChar), false);
vTaskDelay(500 / portTICK_PERIOD_MS);
}
vTaskDelay(3000 / portTICK_PERIOD_MS);
Horizontal and Vertical Scroll
Next up we scroll the text “Horizontal”, horizontally across the screen. This is accomplished through the following section of code. Like always, it starts by clearing the screen and setting the contrast value. Next it displays the text “Horizontal” in the center with a black background and white text (invert is false). Then we use the ssd1306_hardware_scroll() function to first scroll the text towards right (SCROLL_RIGHT) and then after a delay of 5 seconds scroll it towards left (SCROLL_LEFT) and then stop (SCROLL_STOP) after another 5 seconds. This function only takes in two parameters. The first parameter is the address of the SSD1306_t structure and the second parameter is the scroll type.
// Horizontal Scroll
ssd1306_clear_screen(&dev, false);
ssd1306_contrast(&dev, 0xff);
ssd1306_display_text(&dev, center, "Horizontal", 10, false);
ssd1306_hardware_scroll(&dev, SCROLL_RIGHT);
vTaskDelay(5000 / portTICK_PERIOD_MS);
ssd1306_hardware_scroll(&dev, SCROLL_LEFT);
vTaskDelay(5000 / portTICK_PERIOD_MS);
ssd1306_hardware_scroll(&dev, SCROLL_STOP);
Similarly, we will scroll the text “Vertical”, vertically across the screen. This is accomplished through the following section of code. Like always, it starts by clearing the screen and setting the contrast value. Next it displays the text “Vertical” in the center with a black background and white text (invert is false). Then we use the ssd1306_hardware_scroll() function to first scroll the text down (SCROLL_DOWN) and then after a delay of 5 seconds scroll it back up (SCROLL_UP) and then stop (SCROLL_STOP) after another 5 seconds. This function only takes in two parameters. The first parameter is the address of the SSD1306_t structure and the second parameter is the scroll type.
// Vertical Scroll
ssd1306_clear_screen(&dev, false);
ssd1306_contrast(&dev, 0xff);
ssd1306_display_text(&dev, center, "Vertical", 8, false);
ssd1306_hardware_scroll(&dev, SCROLL_DOWN);
vTaskDelay(5000 / portTICK_PERIOD_MS);
ssd1306_hardware_scroll(&dev, SCROLL_UP);
vTaskDelay(5000 / portTICK_PERIOD_MS);
ssd1306_hardware_scroll(&dev, SCROLL_STOP);
Finally, after clearing the screen and setting the contrast, we will display the text ” Good Bye!!” in the center. The background will be white and the color of the text will be black. This is because invert is set as true in this case.
// Invert
ssd1306_clear_screen(&dev, true);
ssd1306_contrast(&dev, 0xff);
ssd1306_display_text(&dev, center, " Good Bye!!", 12, true);
vTaskDelay(5000 / portTICK_PERIOD_MS);
Then the screen slowly fades out and turns black. Shortly, the ESP32 board restarts again.
ssd1306_fadeout(&dev);
esp_restart();
Compiling the Sketch
To flash your chip, type the following command in the serial terminal. Remember to replace the COM port with the one through which your board is connected.
idf.py -p COMX flash monitor
After the code flashes successfully, you can view the informational messages being printed showing the SSD1306 configuration parameters and its status.
The OLED will start displaying all the different texts and scrolling features. Watch the video below to have a better insight.
ESP32 OLED with ESP-IDF Display Animation
After showing you how the to use SSD1306 driver to display text and apply various scrolling effects, let’s include some output results for some more examples that use the SSD1306/SH1106 Driver for ESP-IDF, provided by nopnop2002 on GitHub. We will demonstrate AnimationDemo by nopnop2002 uploaded on GitHub at the following link but use different image frames for demonstration.
Create Project
Open your VS Code and head over to View > Command Palette. Type ESP-IDF: New Project in the search bar and press enter.
Specify the project name and directory. We have named our project ‘ESP_IDF_SSD1306_AnimationDemo.’ For the ESP-IDF board, we have chosen the custom board option. For ESP-IDF target, we have chosen ESP32 module. Click ‘Choose Template’ button to proceed forward.
In the Extension, select ESP-IDF option:
We will click the ‘sample_project’ under the get-started tab. Now click ‘Create project using template sample_project.’
You will get a notification that the project has been created. To open the project in a new window, click ‘Yes.’
Add Libraries
This opens project that we created, inside the EXPLORER tab. There are several folders inside our project folder. Create a new folder named ‘components’ and copy the files from this destination into your project folder. This will contain the libraries that will be required for this project.
SSD1306 Configuration
Let’s first head over to the menuconfig. Opens the ESP-IDF SDK Configuration Editor. Scroll down and open the SSD1306 Configuration. Here we can set the SSD1306 configuration parameter according to our needs. This includes the UART interface, panel type, SCL GPIO pin, SDA GPIO pin and the reset GPIO pin. Here you can view that by default, ESP-IDF is using the interface as I2C, panel type as 128×64, SCL GPIO pin as 22, SDA GPIO pin as 21 and Reset GPIO pin as 33. You can alter these parameters according to your OLED display and then click the Save button found at the top. We will leave the configuration settings as default as they match our module.
Alternatively, we can also set this config value with menuconfig. Open menuconfig by typing idf.py menuconfig in the terminal. This command opens the Espressif IoT Development Framework Configuration. Head over to SSD1306 Configuration and set the parameters accordingly.
Code
Go to main > main.c and open it. We will define the functions and the program code here. This is our main.c file.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "ssd1306.h"
#include "font8x8_basic.h"
/*
You have to set this config value with menuconfig
CONFIG_INTERFACE
for i2c
CONFIG_MODEL
CONFIG_SDA_GPIO
CONFIG_SCL_GPIO
CONFIG_RESET_GPIO
for SPI
CONFIG_CS_GPIO
CONFIG_DC_GPIO
CONFIG_RESET_GPIO
*/
#define TAG "SSD1306"
const unsigned char myBitmap[4] [1024] = {
// 'frame1, 64x128px
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf8, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xff, 0xfe, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xff, 0xf8, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0xf8, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x01, 0xff, 0x07, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x01, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x01, 0xff, 0x07, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x01, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x7c, 0x07, 0xff, 0xff,
0xff, 0xff, 0xf8, 0x00, 0x7c, 0x07, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x7c, 0x07, 0xff, 0xff,
0xff, 0xff, 0xf8, 0x00, 0x7c, 0x07, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0xf8, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0xfe, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xff, 0xfe, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xfe, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xfc, 0x1f,
0xff, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xfc, 0x1f, 0xff, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xfc, 0x1f,
0xff, 0xff, 0xfe, 0x00, 0x00, 0x1f, 0xf0, 0x1f, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x1f, 0xf0, 0x1f,
0xff, 0xff, 0xfe, 0x00, 0x00, 0x1f, 0xf0, 0x1f, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x1f, 0xf0, 0x1f,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x7f,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x7f,
0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff,
0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x47, 0xf3, 0xff,
0xff, 0x80, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff,
0xff, 0x80, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
0xf8, 0x00, 0x78, 0x00, 0x03, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x78, 0x00, 0x03, 0xff, 0xff, 0xff,
0xf8, 0x00, 0x78, 0x00, 0x03, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x78, 0x00, 0x03, 0xff, 0xff, 0xff,
0xf8, 0x0f, 0xf8, 0x00, 0x03, 0xff, 0xff, 0xff, 0xf8, 0x0f, 0xf8, 0x00, 0x03, 0xff, 0xff, 0xff,
0xf8, 0x0f, 0xf8, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x03, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf8, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x03, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf8, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x03, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf8, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x03, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf8, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf8, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf8, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0xfe, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0xe2, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xfc, 0x00, 0xc0, 0x00, 0x01, 0xcf, 0xff,
0xff, 0xfc, 0x00, 0xc0, 0x00, 0x01, 0xcf, 0xff, 0xff, 0xfc, 0x00, 0xc0, 0x00, 0x01, 0x8f, 0xff,
0xff, 0xf0, 0x00, 0x00, 0x0f, 0xc0, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xc0, 0x0f, 0xff,
0xff, 0xf0, 0x00, 0x00, 0x0f, 0xc0, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xc0, 0x0f, 0xff,
0xff, 0xf3, 0xe0, 0x00, 0x3f, 0xe0, 0x3f, 0xff, 0xff, 0xf3, 0xe0, 0x00, 0x7f, 0xf8, 0x3f, 0xff,
0xff, 0xf3, 0xe0, 0x00, 0x7f, 0xf8, 0x3f, 0xff, 0xff, 0xf3, 0xe0, 0x00, 0x7f, 0xf8, 0x3f, 0xff,
0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
},
// 'frame2, 64x128px
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x7f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfe, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x7f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfe, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xff,
0xff, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xff,
0xff, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff,
0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff,
0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff,
0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff,
0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff,
0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff,
0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff,
0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff,
0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff,
0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff,
0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff,
0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff,
0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff,
0xff, 0xf8, 0x00, 0x3f, 0xe0, 0x7f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x3f, 0xe0, 0x7f, 0xff, 0xff,
0xff, 0xf8, 0x00, 0x3f, 0xe0, 0x7f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x3f, 0xe0, 0x7f, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x0f, 0x80, 0x7f, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x0f, 0x80, 0x7f, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x0f, 0x80, 0x7f, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x0f, 0x80, 0x7f, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff,
0xff, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xff,
0xff, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf8, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x7f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf8, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x1f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff,
0xff, 0xf8, 0x00, 0x00, 0x03, 0xff, 0x07, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x03, 0xff, 0x07, 0xff,
0xff, 0xf8, 0x00, 0x00, 0x03, 0xff, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x78, 0x07, 0xff,
0xff, 0xe0, 0x00, 0x00, 0x00, 0x78, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x78, 0x07, 0xff,
0xff, 0xe0, 0x00, 0x00, 0x00, 0x78, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff,
0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff,
0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff,
0xe0, 0x06, 0x00, 0x00, 0x7c, 0x00, 0xff, 0xff, 0xe0, 0x06, 0x00, 0x00, 0x7c, 0x00, 0xff, 0xff,
0xe0, 0x06, 0x00, 0x00, 0x7c, 0x00, 0xff, 0xff, 0x80, 0xfe, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff,
0x80, 0xfe, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0x80, 0xfe, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff,
0x80, 0xfe, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0x83, 0xfe, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff,
0x83, 0xfe, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0x83, 0xfe, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff,
0x83, 0xfe, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x03, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf0, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x03, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf0, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x01, 0x80, 0x67, 0xff, 0xff,
0xff, 0xe0, 0x00, 0x01, 0x80, 0x67, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x01, 0x80, 0x67, 0xff, 0xff,
0xff, 0x00, 0x00, 0x01, 0x80, 0x07, 0xff, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xe0, 0x07, 0xff, 0xff,
0xff, 0x00, 0x00, 0x0f, 0xe0, 0x07, 0xff, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xe0, 0x07, 0xff, 0xff,
0xff, 0x00, 0x00, 0x0f, 0xe0, 0x07, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x3f, 0xfc, 0x1f, 0xff, 0xff,
0xff, 0x1e, 0x00, 0x3f, 0xfc, 0x1f, 0xff, 0xff, 0xff, 0x1e, 0x00, 0x3f, 0xfc, 0x1f, 0xff, 0xff,
0xff, 0x1e, 0x00, 0x3f, 0xfc, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
},
// 'frame3, 64x128px
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x03, 0xff, 0xff,
0xff, 0xff, 0xfc, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x03, 0xff, 0xff,
0xff, 0xff, 0xfc, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0xff, 0xc1, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0xff, 0xc1, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0xff, 0xc1, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0xff, 0xc1, 0xff, 0xff,
0xff, 0xff, 0xfc, 0x00, 0x3e, 0x01, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x3e, 0x01, 0xff, 0xff,
0xff, 0xff, 0xfc, 0x00, 0x3e, 0x01, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x3e, 0x01, 0xff, 0xff,
0xff, 0xff, 0xfc, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x01, 0xff, 0xff,
0xff, 0xff, 0xfc, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x01, 0xff, 0xff,
0xff, 0xff, 0xfc, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x01, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xe0, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x01, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x80, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xff, 0x80, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xff, 0x80, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xff, 0x80, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xff, 0x80, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xff, 0x80, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x0c, 0x0f, 0xff,
0xff, 0xff, 0x80, 0x00, 0x00, 0x0c, 0x0f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x0c, 0x0f, 0xff,
0xff, 0xff, 0x80, 0x00, 0x00, 0x0c, 0x0f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x0f, 0xff,
0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x0f, 0xff,
0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x01, 0x80, 0x7f, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x01, 0xc0, 0x7f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x01, 0xc0, 0x7f, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x01, 0xc0, 0x7f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x01, 0xc0, 0x7f, 0xff,
0xff, 0xff, 0xfc, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x01, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfc, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x01, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfc, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x01, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfc, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xff, 0xff, 0xc0, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0xff, 0xc0, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x01, 0xff, 0xff,
0xff, 0xff, 0x80, 0x00, 0x10, 0x01, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x10, 0x01, 0xff, 0xff,
0xff, 0xff, 0x80, 0x00, 0x10, 0x01, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x10, 0x01, 0x8f, 0xff,
0xff, 0xff, 0x9f, 0xff, 0xfe, 0x01, 0x8f, 0xff, 0xff, 0xff, 0x9f, 0xff, 0xfe, 0x01, 0x8f, 0xff,
0xff, 0xff, 0x9f, 0xff, 0xfe, 0x01, 0x8f, 0xff, 0xff, 0xff, 0x9f, 0xff, 0xfe, 0x01, 0x8f, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x7f, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x7f, 0xff
},
// 'frame4, 64x128px
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf8, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf8, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0xff, 0xff,
0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0xff, 0xff,
0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x1f, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x1f, 0xff,
0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff,
0xff, 0xff, 0x00, 0x00, 0x7f, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xf8, 0x1f, 0xff,
0xff, 0xff, 0x00, 0x00, 0x7f, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x0f, 0xc0, 0x1f, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x0f, 0xc0, 0x1f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x0f, 0xc0, 0x1f, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x0f, 0xc0, 0x1f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x1f, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x1f, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x1f, 0xff,
0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0xff, 0xff,
0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0xff, 0xff,
0xff, 0xff, 0xff, 0xc0, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xff, 0xff, 0xc0, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0xfc, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0xfc, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xff, 0xff, 0x80, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xff, 0xff, 0x80, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x01, 0xff, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe1, 0xf8, 0x0f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xe1, 0xf8, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe1, 0xf8, 0x0f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xe1, 0xf8, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x0f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf8, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x0f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf8, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff
}
};
void app_main(void)
{
SSD1306_t dev;
#if CONFIG_I2C_INTERFACE
ESP_LOGI(TAG, "INTERFACE is i2c");
ESP_LOGI(TAG, "CONFIG_SDA_GPIO=%d",CONFIG_SDA_GPIO);
ESP_LOGI(TAG, "CONFIG_SCL_GPIO=%d",CONFIG_SCL_GPIO);
ESP_LOGI(TAG, "CONFIG_RESET_GPIO=%d",CONFIG_RESET_GPIO);
i2c_master_init(&dev, CONFIG_SDA_GPIO, CONFIG_SCL_GPIO, CONFIG_RESET_GPIO);
#endif // CONFIG_I2C_INTERFACE
#if CONFIG_SPI_INTERFACE
ESP_LOGI(TAG, "INTERFACE is SPI");
ESP_LOGI(TAG, "CONFIG_MOSI_GPIO=%d",CONFIG_MOSI_GPIO);
ESP_LOGI(TAG, "CONFIG_SCLK_GPIO=%d",CONFIG_SCLK_GPIO);
ESP_LOGI(TAG, "CONFIG_CS_GPIO=%d",CONFIG_CS_GPIO);
ESP_LOGI(TAG, "CONFIG_DC_GPIO=%d",CONFIG_DC_GPIO);
ESP_LOGI(TAG, "CONFIG_RESET_GPIO=%d",CONFIG_RESET_GPIO);
spi_master_init(&dev, CONFIG_MOSI_GPIO, CONFIG_SCLK_GPIO, CONFIG_CS_GPIO, CONFIG_DC_GPIO, CONFIG_RESET_GPIO);
#endif // CONFIG_SPI_INTERFACE
#if CONFIG_SSD1306_128x64
ESP_LOGI(TAG, "Panel is 128x64");
ssd1306_init(&dev, 128, 64);
#endif // CONFIG_SSD1306_128x64
#if CONFIG_SSD1306_128x32
ESP_LOGE(TAG, "Panel is 128x32. This demo cannot be run.");
while(1) { vTaskDelay(1); }
#endif // CONFIG_SSD1306_128x32
ssd1306_contrast(&dev, 0xff);
ssd1306_clear_screen(&dev, false);
int count = 3;
uint8_t segs[128];
while(1) {
TickType_t startTick = xTaskGetTickCount();
// 1Ticks required
for (int page=0;page<8;page++) {
for (int seg=0;seg<128;seg++) {
segs[seg] = ssd1306_rotate_byte(myBitmap[count][seg*8+page]);
}
ssd1306_display_image(&dev, page, 0, segs, 128);
}
TickType_t endTick = xTaskGetTickCount();
ESP_LOGD(TAG, "diffTick=%d", endTick - startTick);
count--;
if (count<0) count = 3;
vTaskDelay(10);
}
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
Compiling the Sketch
To flash your chip, type the following command in the serial terminal. Remember to replace the COM port with the one through which your board is connected.
idf.py -p COMX flash monitor
After the code flashes successfully, you can view the informational messages being printed showing the SSD1306 configuration parameters and its status.
The OLED will start displaying the moving animation. Watch the video below to have a better insight.
Display Counter value on OLED with ESP32 and ESP-IDF
In this section, we will demonstrate CounterDemo by nopnop2002 uploaded on GitHub at the following link:
Create Project
Open your VS Code and head over to View > Command Palette. Type ESP-IDF: New Project in the search bar and press enter.
Specify the project name and directory. We have named our project ‘ESP_IDF_SSD1306_CounterDemo.’ For the ESP-IDF board, we have chosen the custom board option. For ESP-IDF target, we have chosen ESP32 module. Click ‘Choose Template’ button to proceed forward.
In the Extension, select ESP-IDF option:
We will click the ‘sample_project’ under the get-started tab. Now click ‘Create project using template sample_project.’
You will get a notification that the project has been created. To open the project in a new window, click ‘Yes.’
Add Libraries
This opens project that we created, inside the EXPLORER tab. There are several folders inside our project folder. Create a new folder named ‘components‘ and copy the files from this destination into your project folder. This will contain the libraries that will be required for this project.
SSD1306 Configuration
Let’s first head over to the menuconfig. Opens the ESP-IDF SDK Configuration Editor. Scroll down and open the SSD1306 Configuration. Here we can set the SSD1306 configuration parameter according to our needs. This includes the UART interface, panel type, SCL GPIO pin, SDA GPIO pin, and the reset GPIO pin. Here you can view that by default, ESP-IDF is using the interface as I2C, panel type as 128×64, SCL GPIO pin as 22, SDA GPIO pin as 21 and Reset GPIO pin as 33. You can alter these parameters according to your OLED display and then click the Save button found at the top. We will leave the configuration settings as default as they match our module.
Alternatively, we can also set this config value with menuconfig. Open menuconfig by typing idf.py menuconfig in the terminal. This command opens the Espressif IoT Development Framework Configuration. Head over to SSD1306 Configuration and set the parameters accordingly.
Code
Go to main > main.c and open it. We will define the functions and the program code here. Copy the code from this link here.
This is our main.c file.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "ssd1306.h"
#include "font8x8_basic.h"
/*
You have to set this config value with menuconfig
CONFIG_INTERFACE
for i2c
CONFIG_MODEL
CONFIG_SDA_GPIO
CONFIG_SCL_GPIO
CONFIG_RESET_GPIO
for SPI
CONFIG_CS_GPIO
CONFIG_DC_GPIO
CONFIG_RESET_GPIO
*/
#define TAG "SSD1306"
#define IMAGES 10
uint8_t segmentDisplay[IMAGES][192] = {
{
// https://www.iconspng.com/image/5656/seven-segment-display-gray-0
// 'seven-segment-display-gray-0', 32x48px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xe0, 0x06, 0xff, 0xff, 0x60,
0x07, 0x7f, 0xfe, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0,
0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0,
0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0,
0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x02, 0x00, 0x00, 0x40,
0x02, 0x00, 0x00, 0x40, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0,
0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0,
0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0,
0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0xff, 0xff, 0xe0,
0x07, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
},
{
// https://www.iconspng.com/image/5657/seven-segment-display-gray-1
// 'seven-segment-display-gray-1', 32x48px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x60,
0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x40,
0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0xe0,
0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
},
{
// https://www.iconspng.com/image/5658/seven-segment-display-gray-2
// 'seven-segment-display-gray-2', 32x48px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x03, 0xff, 0xff, 0xe0, 0x01, 0xff, 0xff, 0x60,
0x00, 0xff, 0xfe, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x7f, 0xfe, 0xe0, 0x01, 0xff, 0xff, 0xc0,
0x03, 0xff, 0xff, 0x00, 0x07, 0x7f, 0xfe, 0x00, 0x07, 0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00,
0x07, 0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00,
0x07, 0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00,
0x07, 0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x07, 0xff, 0xff, 0x00,
0x07, 0xff, 0xff, 0x80, 0x07, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
},
{
// https://www.iconspng.com/image/5659/seven-segment-display-gray-3
// 'seven-segment-display-gray-3', 32x48px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x03, 0xff, 0xff, 0xe0, 0x01, 0xff, 0xff, 0x60,
0x00, 0xff, 0xfe, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x7f, 0xfe, 0xe0, 0x01, 0xff, 0xff, 0x80,
0x01, 0xff, 0xff, 0x40, 0x00, 0x7f, 0xfe, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0xff, 0xff, 0xe0,
0x01, 0xff, 0xff, 0xe0, 0x03, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
},
{
// https://www.iconspng.com/image/5660/seven-segment-display-gray-4
// 'seven-segment-display-gray-4', 32x48px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x06, 0x00, 0x00, 0x60,
0x07, 0x00, 0x00, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0,
0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0,
0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0,
0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x7f, 0xfe, 0xe0, 0x03, 0xff, 0xff, 0x80,
0x00, 0xff, 0xff, 0x40, 0x00, 0x7f, 0xfe, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0xe0,
0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
},
{
// https://www.iconspng.com/image/5661/seven-segment-display-gray-5
// 'seven-segment-display-gray-5', 32x48px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xc0, 0x06, 0xff, 0xff, 0x80,
0x07, 0x7f, 0xff, 0x00, 0x07, 0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00,
0x07, 0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00,
0x07, 0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00,
0x07, 0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x07, 0x7f, 0xfe, 0x00, 0x03, 0xff, 0xff, 0x80,
0x00, 0xff, 0xff, 0xc0, 0x00, 0x7f, 0xfe, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0xff, 0xff, 0xe0,
0x01, 0xff, 0xff, 0xe0, 0x03, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
},
{
// https://www.iconspng.com/image/5662/seven-segment-display-gray-6
// 'seven-segment-display-gray-6', 32x48px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xc0, 0x06, 0xff, 0xff, 0x80,
0x07, 0x7f, 0xff, 0x00, 0x07, 0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00,
0x07, 0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00,
0x07, 0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00,
0x07, 0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x07, 0x7f, 0xfe, 0x00, 0x01, 0xff, 0xff, 0x80,
0x02, 0xff, 0xff, 0xc0, 0x07, 0x7f, 0xfe, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0,
0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0,
0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0,
0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0xff, 0xff, 0xe0,
0x07, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
},
{
// https://www.iconspng.com/image/5663/seven-segment-display
// 'seven-segment-display-gray-7', 32x48px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x03, 0xff, 0xff, 0xe0, 0x01, 0xff, 0xff, 0x60,
0x00, 0xff, 0xfe, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x40,
0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0xe0,
0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
},
{
// https://www.iconspng.com/image/5664/seven-segment-display-gray-8
// 'seven-segment-display-gray-8', 32x48px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xe0, 0x06, 0xff, 0xff, 0x60,
0x07, 0x7f, 0xfe, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0,
0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0,
0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0,
0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x7f, 0xfe, 0xe0, 0x01, 0xff, 0xff, 0x80,
0x02, 0xff, 0xff, 0x40, 0x07, 0x7f, 0xfe, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0,
0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0,
0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0,
0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0xff, 0xff, 0xe0,
0x07, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
},
{
// https://www.iconspng.com/image/5665/seven-segment-display
// 'seven-segment-display-gray-9', 32x48px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xe0, 0x06, 0xff, 0xff, 0x60,
0x07, 0x7f, 0xfe, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0,
0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0,
0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0,
0x07, 0x80, 0x01, 0xe0, 0x07, 0x80, 0x01, 0xe0, 0x07, 0x7f, 0xfe, 0xe0, 0x03, 0xff, 0xff, 0x80,
0x00, 0xff, 0xff, 0x40, 0x00, 0x7f, 0xfe, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0xff, 0xff, 0xe0,
0x01, 0xff, 0xff, 0xe0, 0x03, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}
};
void app_main(void)
{
SSD1306_t dev;
#if CONFIG_I2C_INTERFACE
ESP_LOGI(TAG, "INTERFACE is i2c");
ESP_LOGI(TAG, "CONFIG_SDA_GPIO=%d",CONFIG_SDA_GPIO);
ESP_LOGI(TAG, "CONFIG_SCL_GPIO=%d",CONFIG_SCL_GPIO);
ESP_LOGI(TAG, "CONFIG_RESET_GPIO=%d",CONFIG_RESET_GPIO);
i2c_master_init(&dev, CONFIG_SDA_GPIO, CONFIG_SCL_GPIO, CONFIG_RESET_GPIO);
#endif // CONFIG_I2C_INTERFACE
#if CONFIG_SPI_INTERFACE
ESP_LOGI(TAG, "INTERFACE is SPI");
ESP_LOGI(TAG, "CONFIG_MOSI_GPIO=%d",CONFIG_MOSI_GPIO);
ESP_LOGI(TAG, "CONFIG_SCLK_GPIO=%d",CONFIG_SCLK_GPIO);
ESP_LOGI(TAG, "CONFIG_CS_GPIO=%d",CONFIG_CS_GPIO);
ESP_LOGI(TAG, "CONFIG_DC_GPIO=%d",CONFIG_DC_GPIO);
ESP_LOGI(TAG, "CONFIG_RESET_GPIO=%d",CONFIG_RESET_GPIO);
spi_master_init(&dev, CONFIG_MOSI_GPIO, CONFIG_SCLK_GPIO, CONFIG_CS_GPIO, CONFIG_DC_GPIO, CONFIG_RESET_GPIO);
#endif // CONFIG_SPI_INTERFACE
#if CONFIG_FLIP
dev._flip = true;
ESP_LOGW(TAG, "Flip upside down");
#endif
#if CONFIG_SSD1306_128x64
ESP_LOGI(TAG, "Panel is 128x64");
ssd1306_init(&dev, 128, 64);
#endif // CONFIG_SSD1306_128x64
#if CONFIG_SSD1306_128x32
ESP_LOGE(TAG, "Panel is 128x32. This demo cannot be run.");
while(1) { vTaskDelay(1); }
#endif // CONFIG_SSD1306_128x32
ssd1306_contrast(&dev, 0xff);
// Allocate memory
uint8_t *buffer = (uint8_t *)malloc(8*128); // 8 page 128 pixel
if (buffer == NULL) {
ESP_LOGE(TAG, "malloc failed");
while(1) { vTaskDelay(1); }
}
uint8_t *segmentImage = (uint8_t *)malloc(IMAGES*8*32); // 10 image 8 page 32pixel
if (segmentImage == NULL) {
ESP_LOGE(TAG, "malloc failed");
while(1) { vTaskDelay(1); }
}
// Convert from segmentDisplay to segmentImage
for (int imageIndex=0;imageIndex<IMAGES;imageIndex++) {
ssd1306_clear_screen(&dev, false);
ssd1306_bitmaps(&dev, 0, 8, segmentDisplay[imageIndex], 32, 48, false);
vTaskDelay(200 / portTICK_PERIOD_MS);
// Get from internal buffer to local buffer
// buffer is [8][128] 8 page 128 pixel
ssd1306_get_buffer(&dev, buffer);
// Save from buffer to segmentImage
// segmentImage is [10][8][32] 10 image 8 page 32 pixel
int segmentImageIndex = imageIndex * 256;
for (int page=0;page<8;page++) {
//ESP_LOGI(TAG, "segmentImageIndex+page*32=%d", segmentImageIndex+page*32);
memcpy(&segmentImage[segmentImageIndex+page*32], &buffer[page*128], 32);
//ESP_LOGI(TAG, "page=%d", page);
//ESP_LOG_BUFFER_HEXDUMP(TAG, &buffer[page*128], 32, ESP_LOG_INFO);
}
#if 0
ssd1306_clear_screen(&dev, false);
for (int page=0;page<8;page++) {
ssd1306_display_image(&dev, page, 0, &segmentImage[segmentImageIndex+page*32], 32);
//ESP_LOGI(TAG, "page=%d", page);
//ESP_LOG_BUFFER_HEXDUMP(TAG, &segmentImage[segmentImageIndex+page*32], 32, ESP_LOG_INFO);
}
vTaskDelay(1000 / portTICK_PERIOD_MS);
#endif
}
// I don't use this anymore
free(buffer);
int digit1 = 0;
int digit2 = 0;
int digit3 = 0;
int digit4 = 0;
ssd1306_clear_screen(&dev, false);
for (int page=0;page<8;page++) {
ssd1306_display_image(&dev, page, 0, &segmentImage[page*32], 32);
ssd1306_display_image(&dev, page, 32, &segmentImage[page*32], 32);
ssd1306_display_image(&dev, page, 64, &segmentImage[page*32], 32);
ssd1306_display_image(&dev, page, 96, &segmentImage[page*32], 32);
vTaskDelay(2);
}
while(1) {
digit4++;
if (digit4 == 10) {
digit4 = 0;
int segmentImageIndex4 = digit4 * 256;
for (int page=0;page<8;page++) {
ssd1306_display_image(&dev, page, 96, &segmentImage[segmentImageIndex4+page*32], 32);
}
digit3++;
if (digit3 == 10) {
digit3 = 0;
digit2++;
if (digit2 == 10) {
digit2 = 0;
digit1++;
if (digit1 == 10) {
digit1 = 0;
digit2 = 0;
digit3 = 0;
digit4 = 0;
}
// Update digit1
int segmentImageIndex1 = digit1 * 256;
for (int page=0;page<8;page++) {
ssd1306_display_image(&dev, page, 00, &segmentImage[segmentImageIndex1+page*32], 32);
}
}
// Update digit2
int segmentImageIndex2 = digit2 * 256;
for (int page=0;page<8;page++) {
ssd1306_display_image(&dev, page, 32, &segmentImage[segmentImageIndex2+page*32], 32);
}
}
// Update digit3
int segmentImageIndex3 = digit3 * 256;
for (int page=0;page<8;page++) {
ssd1306_display_image(&dev, page, 64, &segmentImage[segmentImageIndex3+page*32], 32);
}
} else {
// Update digit4
int segmentImageIndex4 = digit4 * 256;
for (int page=0;page<8;page++) {
ssd1306_display_image(&dev, page, 96, &segmentImage[segmentImageIndex4+page*32], 32);
}
}
vTaskDelay(8);
} // end while
}
Compiling the Sketch
To flash your chip, type the following command in the serial terminal. Remember to replace the COM port with the one through which your board is connected.
idf.py -p COMX flash monitor
After the code flashes successfully, you can view the informational messages being printed showing the SSD1306 configuration parameters and its status.
The OLED will start displaying the counter. Watch the video below to have a better insight.
ESP32 OLED with ESP-IDF Display Image
In this section, we will use ImageDemo by nopnop2002 uploaded on GitHub at the following link but use different images to demonstrate.
Create Project
Open your VS Code and head over to View > Command Palette. Type ESP-IDF: New Project in the search bar and press enter.
Specify the project name and directory. We have named our project ‘ESP_IDF_SSD1306_ImageDemo.’ For the ESP-IDF board, we have chosen the custom board option. For ESP-IDF target, we have chosen ESP32 module. Click ‘Choose Template’ button to proceed forward.
In the Extension, select ESP-IDF option:
We will click the ‘sample_project’ under the get-started tab. Now click ‘Create project using template sample_project.’
You will get a notification that the project has been created. To open the project in a new window, click ‘Yes.’
Add Libraries
This opens project that we created, inside the EXPLORER tab. There are several folders inside our project folder. Create a new folder named ‘components‘ and copy the files from this destination in your project folder. This will contain the libraries that will be required for this project.
SSD1306 Configuration
Let’s first head over to the menuconfig. Opens the ESP-IDF SDK Configuration Editor. Scroll down and open the SSD1306 Configuration. Here we can set the SSD1306 configuration parameter according to our needs. This includes the UART interface, panel type, SCL GPIO pin, SDA GPIO pin and the reset GPIO pin. Here you can view that by default, ESP-IDF is using the interface as I2C, panel type as 128×64, SCL GPIO pin as 22, SDA GPIO pin as 21 and Reset GPIO pin as 33. You can alter these parameters according to your OLED display and then click the Save button found at the top. We will leave the configuration settings as default as they match our module.
Alternatively, we can also set this config value with menuconfig. Open menuconfig by typing idf.py menuconfig in the terminal. This command opens the Espressif IoT Development Framework Configuration. Head over to SSD1306 Configuration and set the parameters accordingly.
Code
Go to main > main.c and open it. We will define the functions and the program code here. This is our main.c file.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "ssd1306.h"
#include "font8x8_basic.h"
/*
You have to set this config value with menuconfig
CONFIG_INTERFACE
for i2c
CONFIG_MODEL
CONFIG_SDA_GPIO
CONFIG_SCL_GPIO
CONFIG_RESET_GPIO
for SPI
CONFIG_CS_GPIO
CONFIG_DC_GPIO
CONFIG_RESET_GPIO
*/
#define TAG "SSD1306"
uint8_t image1[] = {
// 'image1', 32x13px
0xfc, 0x00, 0x00, 0x3f, 0xf1, 0x03, 0x00, 0x0f, 0xc4, 0x3f, 0xf8, 0x23, 0x88, 0x07, 0xff, 0xf1,
0xe0, 0x00, 0x00, 0xc7, 0xf8, 0x00, 0x00, 0x1f, 0xfc, 0x7f, 0xe0, 0x3f, 0xff, 0x01, 0xf8, 0xff,
0xff, 0x80, 0x01, 0xff, 0xff, 0xe3, 0xc7, 0xff, 0xff, 0xf1, 0x8f, 0xff, 0xff, 0xfc, 0x3f, 0xff,
0xff, 0xff, 0xff, 0xff
};
uint8_t image2 [1024] = {
// 'image2', 128x64px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0c, 0x00, 0xff, 0xff, 0xe0, 0x00, 0x7f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x1e, 0x03, 0xff, 0xff, 0xfe, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xf0, 0x01, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xe0, 0x07, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x7f, 0xff, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x03, 0xc0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x0f, 0xff, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x07, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xf8, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0x00, 0xff, 0xf8, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x80, 0x3f, 0xfc, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3c, 0x07, 0xff, 0xfc, 0x00, 0x01, 0xff, 0xff, 0xf0, 0x0f, 0xfe, 0x00, 0x00, 0x00,
0x00, 0x00, 0x70, 0x3f, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xfc, 0x03, 0xff, 0x00, 0x00, 0x00,
0x00, 0x00, 0xf0, 0x7f, 0xff, 0xff, 0xff, 0x80, 0x07, 0xff, 0xff, 0x01, 0xff, 0x80, 0x00, 0x00,
0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0x80, 0x7f, 0x80, 0x00, 0x00,
0x00, 0x01, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x7f, 0xff, 0xc0, 0x3f, 0xc0, 0x00, 0x00,
0x00, 0x01, 0xc1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x0f, 0xff, 0xf0, 0x1f, 0xc0, 0x00, 0x00,
0x00, 0x01, 0xc1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x07, 0xff, 0xf8, 0x0f, 0xe0, 0x00, 0x00,
0x00, 0x01, 0xc1, 0xc0, 0x00, 0x00, 0xff, 0xff, 0xfe, 0x01, 0xff, 0xfc, 0x07, 0xe0, 0x00, 0x00,
0x00, 0x01, 0xc3, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0x80, 0xff, 0xff, 0x03, 0xe0, 0x00, 0x00,
0x00, 0x03, 0xc3, 0xc0, 0x1e, 0x00, 0x00, 0xff, 0xff, 0xe0, 0x3f, 0xff, 0x81, 0xf0, 0x00, 0x00,
0x00, 0x01, 0xc3, 0xcf, 0xff, 0xfe, 0x00, 0x1f, 0xff, 0xf0, 0x1f, 0xff, 0x80, 0xf0, 0x00, 0x00,
0x00, 0x01, 0xc1, 0xff, 0xff, 0xff, 0xf0, 0x07, 0xff, 0xf8, 0x0f, 0xff, 0xc0, 0x40, 0x00, 0x00,
0x00, 0x01, 0xc1, 0xff, 0xff, 0xff, 0xfc, 0x01, 0xff, 0xfe, 0x07, 0xff, 0xe0, 0x00, 0x00, 0x00,
0x00, 0x01, 0xc1, 0xff, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x00,
0x00, 0x01, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x3f, 0xff, 0x01, 0xff, 0xf0, 0x00, 0x00, 0x00,
0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0x80, 0xff, 0xf8, 0x00, 0x00, 0x00,
0x00, 0x00, 0xe0, 0x7f, 0x00, 0x3f, 0xff, 0xf8, 0x0f, 0xff, 0xc0, 0xff, 0xf8, 0x00, 0x00, 0x00,
0x00, 0x00, 0x70, 0x10, 0x00, 0x03, 0xff, 0xfe, 0x07, 0xff, 0xc0, 0x7f, 0xfc, 0x00, 0x00, 0x00,
0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0xff, 0xfe, 0x07, 0xff, 0xc0, 0x7f, 0xfc, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x7f, 0xff, 0x03, 0xff, 0xe0, 0x7f, 0xfc, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1e, 0x00, 0x3f, 0x00, 0x1f, 0xff, 0x01, 0xff, 0xf0, 0x7f, 0xf8, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0f, 0x01, 0xff, 0xe0, 0x0f, 0xff, 0x81, 0xff, 0xf0, 0x3f, 0xf0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x07, 0x81, 0xff, 0xf0, 0x0f, 0xff, 0x81, 0xff, 0xf0, 0x3f, 0xe0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0xc3, 0xff, 0xf0, 0x0f, 0xff, 0x81, 0xff, 0xf0, 0x3f, 0x80, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xf1, 0xff, 0xf0, 0x0f, 0xff, 0x81, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3d, 0xff, 0xe0, 0x0f, 0xff, 0x81, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x1f, 0xff, 0x80, 0x1f, 0xff, 0x01, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x3f, 0xff, 0x03, 0xff, 0xe0, 0x00, 0xf0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0xf0, 0x00, 0x7f, 0xff, 0x07, 0xff, 0xe0, 0x03, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x1f, 0xfe, 0x03, 0xff, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x01, 0xf8, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 0x01, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0xe1, 0x0c, 0x78, 0xfe, 0x1f, 0xf0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0xc0, 0x0c, 0x18, 0x07, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0xf0, 0x0c, 0x18, 0x06, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x07, 0xf8, 0x3e, 0x0c, 0x70, 0x7c, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x03, 0x8c, 0x00, 0x07, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x8c, 0x00, 0x03, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x07, 0xfc, 0x87, 0x0c, 0x01, 0x8f, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x07, 0xfc, 0xfe, 0x0c, 0x00, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
void app_main(void)
{
SSD1306_t dev;
#if CONFIG_I2C_INTERFACE
ESP_LOGI(TAG, "INTERFACE is i2c");
ESP_LOGI(TAG, "CONFIG_SDA_GPIO=%d",CONFIG_SDA_GPIO);
ESP_LOGI(TAG, "CONFIG_SCL_GPIO=%d",CONFIG_SCL_GPIO);
ESP_LOGI(TAG, "CONFIG_RESET_GPIO=%d",CONFIG_RESET_GPIO);
i2c_master_init(&dev, CONFIG_SDA_GPIO, CONFIG_SCL_GPIO, CONFIG_RESET_GPIO);
#endif // CONFIG_I2C_INTERFACE
#if CONFIG_SPI_INTERFACE
ESP_LOGI(TAG, "INTERFACE is SPI");
ESP_LOGI(TAG, "CONFIG_MOSI_GPIO=%d",CONFIG_MOSI_GPIO);
ESP_LOGI(TAG, "CONFIG_SCLK_GPIO=%d",CONFIG_SCLK_GPIO);
ESP_LOGI(TAG, "CONFIG_CS_GPIO=%d",CONFIG_CS_GPIO);
ESP_LOGI(TAG, "CONFIG_DC_GPIO=%d",CONFIG_DC_GPIO);
ESP_LOGI(TAG, "CONFIG_RESET_GPIO=%d",CONFIG_RESET_GPIO);
spi_master_init(&dev, CONFIG_MOSI_GPIO, CONFIG_SCLK_GPIO, CONFIG_CS_GPIO, CONFIG_DC_GPIO, CONFIG_RESET_GPIO);
#endif // CONFIG_SPI_INTERFACE
#if CONFIG_FLIP
dev._flip = true;
ESP_LOGW(TAG, "Flip upside down");
#endif
#if CONFIG_SSD1306_128x64
ESP_LOGI(TAG, "Panel is 128x64");
ssd1306_init(&dev, 128, 64);
#endif // CONFIG_SSD1306_128x64
#if CONFIG_SSD1306_128x32
ESP_LOGI(TAG, "Panel is 128x32");
ssd1306_init(&dev, 128, 32);
#endif // CONFIG_SSD1306_128x32
ssd1306_contrast(&dev, 0xff);
while(1) {
ssd1306_clear_screen(&dev, false);
#if CONFIG_SSD1306_128x64
ssd1306_display_text(&dev, 0, "OLED IMAGE DEMO", 15, false);
#endif // CONFIG_SSD1306_128x64
#if CONFIG_SSD1306_128x32
ssd1306_display_text(&dev, 0, "SSD1306 128x32", 14, false);
#endif // CONFIG_SSD1306_128x32
int bitmapWidth = 4*8;
int width = ssd1306_get_width(&dev);
int xpos = width / 2; // center of width
xpos = xpos - bitmapWidth/2;
int ypos = 16;
ESP_LOGD(TAG, "width=%d xpos=%d", width, xpos);
ssd1306_bitmaps(&dev, xpos, ypos, image1, 32, 13, false);
vTaskDelay(3000 / portTICK_PERIOD_MS);
for(int i=0;i<128;i++) {
ssd1306_wrap_arround(&dev, SCROLL_RIGHT, 2, 3, 0);
}
vTaskDelay(2000 / portTICK_PERIOD_MS);
#if CONFIG_SSD1306_128x64
ssd1306_clear_screen(&dev, false);
ssd1306_bitmaps(&dev, 0, 0, image2, 128, 64, false);
vTaskDelay(2000 / portTICK_PERIOD_MS);
for(int i=0;i<64;i++) {
ssd1306_wrap_arround(&dev, SCROLL_UP, 0, 127, 0);
}
vTaskDelay(2000 / portTICK_PERIOD_MS);
#endif
}
}
Compiling the Sketch
To flash your chip, type the following command in the serial terminal. Remember to replace the COM port with the one through which your board is connected.
idf.py -p COMX flash monitor
After the code flashes successfully, you can view the informational messages being printed showing the SSD1306 configuration parameters and its status.
The OLED will start displaying the images. Watch the video below to have a better insight.
ESP32 OLED with ESP-IDF Display Scrolling Image
In this section, we will demonstrate ImageScrollDemo by nopnop2002 uploaded on GitHub at the following link:
Create Project
Open your VS Code and head over to View > Command Palette. Type ESP-IDF: New Project in the search bar and press enter.
Specify the project name and directory. We have named our project ‘ESP_IDF_SSD1306_ImageScrollDemo.’ For the ESP-IDF board, we have chosen the custom board option. For ESP-IDF target, we have chosen ESP32 module. Click ‘Choose Template’ button to proceed forward.
In the Extension, select ESP-IDF option:
We will click the ‘sample_project’ under the get-started tab. Now click ‘Create project using template sample_project.’
You will get a notification that the project has been created. To open the project in a new window, click ‘Yes.’
Add Libraries
This opens project that we created, inside the EXPLORER tab. There are several folders inside our project folder. Create a new folder named ‘components‘ and copy the files from this destination into your project folder. This will contain the libraries that will be required for this project.
SSD1306 Configuration
Let’s first head over to the menuconfig. Opens the ESP-IDF SDK Configuration Editor. Scroll down and open the SSD1306 Configuration. Here we can set the SSD1306 configuration parameter according to our needs. This includes the UART interface, panel type, SCL GPIO pin, SDA GPIO pin and the reset GPIO pin. Here you can view that by default, ESP-IDF is using the interface as I2C, panel type as 128×64, SCL GPIO pin as 22, SDA GPIO pin as 21 and Reset GPIO pin as 33. You can alter these parameters according to your OLED display and then click the Save button found at the top. We will leave the configuration settings as default as they match our module.
Alternatively, we can also set this config value with menuconfig. Open menuconfig by typing idf.py menuconfig in the terminal. This command opens the Espressif IoT Development Framework Configuration. Head over to SSD1306 Configuration and set the parameters accordingly.
Code
Go to main > main.c and open it. We will define the functions and the program code here. Copy the code from this link here.
This is our main.c file.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "ssd1306.h"
#include "font8x8_basic.h"
/*
You have to set this config value with menuconfig
CONFIG_INTERFACE
for i2c
CONFIG_MODEL
CONFIG_SDA_GPIO
CONFIG_SCL_GPIO
CONFIG_RESET_GPIO
for SPI
CONFIG_CS_GPIO
CONFIG_DC_GPIO
CONFIG_RESET_GPIO
*/
#define TAG "SSD1306"
#define NUM_IMAGES 7
#define IMAGE_WIDTH 48
// (48/6)*62=372
#define BITMAPS 372
uint8_t segmentDisplay[NUM_IMAGES][BITMAPS] = {
{
// https://www.iconspng.com/image/94065/16-segment-display-h
// '16-segment-display-h', 48x62px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x30, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x70,
0x00, 0x0f, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00,
0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x1e, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x1e,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x1e, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x1e, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x1e, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x1e, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x3c, 0x00, 0x00,
0x03, 0xc0, 0x00, 0x3c, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x3c, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x3c,
0x00, 0x00, 0x03, 0xc0, 0x00, 0x3c, 0x00, 0x00, 0x07, 0x80, 0x00, 0x78, 0x00, 0x00, 0x07, 0x80,
0x00, 0x78, 0x00, 0x00, 0x07, 0x80, 0x00, 0x78, 0x00, 0x00, 0x07, 0x80, 0x00, 0x78, 0x00, 0x00,
0x07, 0x80, 0x00, 0x78, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x70, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x27,
0xf8, 0x1f, 0xf6, 0x00, 0x00, 0x1f, 0xfe, 0x7f, 0xf8, 0x00, 0x00, 0x1f, 0xfc, 0x7f, 0xf0, 0x00,
0x00, 0x6f, 0xf0, 0x1f, 0xee, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x1e, 0x00, 0x01, 0xe0, 0x00, 0x00,
0x1e, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x1e, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x1e, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x3e, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x3c, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x3c, 0x00,
0x03, 0xc0, 0x00, 0x00, 0x3c, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x3c, 0x00, 0x03, 0xc0, 0x00, 0x00,
0x3c, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x78, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x78, 0x00, 0x07, 0x80,
0x00, 0x00, 0x78, 0x00, 0x07, 0x80, 0x00, 0x00, 0x78, 0x00, 0x07, 0x80, 0x00, 0x00, 0x78, 0x00,
0x07, 0x80, 0x00, 0x00, 0x78, 0x00, 0x07, 0x80, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0x00,
0xf0, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00,
0x00, 0x00, 0xf0, 0x00, 0x0e, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x60, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
},
{
// https://www.iconspng.com/image/94062/16-segment-display-e
// '16-segment-display-e', 48x62px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0xc0, 0xff, 0x80, 0x00, 0x01, 0xff, 0xe1, 0xff, 0xc0, 0x00, 0x01,
0xff, 0xf3, 0xff, 0xc0, 0x00, 0x06, 0xff, 0xe3, 0xff, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e,
0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00,
0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00,
0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27,
0xf8, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfc, 0x00, 0x00, 0x00,
0x00, 0x6f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00,
0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80,
0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00,
0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0xff, 0xc7, 0xff, 0x00, 0x00,
0x03, 0xff, 0xcf, 0xff, 0x80, 0x00, 0x07, 0xff, 0x87, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
},
{
// '16-segment-display-l', 48x62px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e,
0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00,
0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00,
0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00,
0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80,
0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00,
0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0xff, 0xc7, 0xff, 0x00, 0x00,
0x03, 0xff, 0xcf, 0xff, 0x80, 0x00, 0x07, 0xff, 0x87, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
},
{
// '16-segment-display-o', 48x62px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0xc0, 0xff, 0xc0, 0x00, 0x01, 0xff, 0xe1, 0xff, 0xc0, 0x00, 0x01,
0xff, 0xf3, 0xff, 0xc0, 0x00, 0x06, 0xff, 0xe3, 0xff, 0x30, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x70,
0x00, 0x0f, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00,
0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x1e, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x1e,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x1e, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x1e, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x1e, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x1e, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x3c, 0x00, 0x00,
0x03, 0xc0, 0x00, 0x3c, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x3c, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x3c,
0x00, 0x00, 0x03, 0xc0, 0x00, 0x3c, 0x00, 0x00, 0x07, 0x80, 0x00, 0x78, 0x00, 0x00, 0x07, 0x80,
0x00, 0x78, 0x00, 0x00, 0x07, 0x80, 0x00, 0x78, 0x00, 0x00, 0x07, 0x80, 0x00, 0x78, 0x00, 0x00,
0x07, 0x80, 0x00, 0x78, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x70, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x20,
0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x60, 0x00, 0x00, 0x0e, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x1e, 0x00, 0x01, 0xe0, 0x00, 0x00,
0x1e, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x1e, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x1e, 0x00, 0x01, 0xe0,
0x00, 0x00, 0x3e, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x3c, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x3c, 0x00,
0x03, 0xc0, 0x00, 0x00, 0x3c, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x3c, 0x00, 0x03, 0xc0, 0x00, 0x00,
0x3c, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x78, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x78, 0x00, 0x07, 0x80,
0x00, 0x00, 0x78, 0x00, 0x07, 0x80, 0x00, 0x00, 0x78, 0x00, 0x07, 0x80, 0x00, 0x00, 0x78, 0x00,
0x07, 0x80, 0x00, 0x00, 0x78, 0x00, 0x07, 0x80, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0x00,
0xf0, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00,
0x00, 0x00, 0xf0, 0x00, 0x0e, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x0d, 0xff, 0xc7, 0xff, 0x60, 0x00,
0x03, 0xff, 0xcf, 0xff, 0x80, 0x00, 0x07, 0xff, 0x87, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
},
{
// '16-segment-display-w', 48x62px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x30, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x70,
0x00, 0x0f, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00,
0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x1e, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x1e,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x1e, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x1e, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x1e, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x1e, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x3c, 0x00, 0x00,
0x03, 0xc0, 0x00, 0x3c, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x3c, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x3c,
0x00, 0x00, 0x03, 0xc0, 0x00, 0x3c, 0x00, 0x00, 0x07, 0x80, 0x00, 0x78, 0x00, 0x00, 0x07, 0x80,
0x00, 0x78, 0x00, 0x00, 0x07, 0x80, 0x00, 0x78, 0x00, 0x00, 0x07, 0x80, 0x00, 0x78, 0x00, 0x00,
0x07, 0x80, 0x00, 0x78, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x70, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x20,
0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
0x00, 0x60, 0x06, 0xc0, 0x0e, 0x00, 0x00, 0xf0, 0x1c, 0xe0, 0x1e, 0x00, 0x01, 0xe0, 0x1c, 0x60,
0x1e, 0x00, 0x01, 0xe0, 0x38, 0x70, 0x1e, 0x00, 0x01, 0xe0, 0x78, 0x70, 0x1e, 0x00, 0x01, 0xe0,
0xf0, 0x70, 0x3e, 0x00, 0x01, 0xe0, 0xf0, 0x78, 0x3c, 0x00, 0x03, 0xe1, 0xe0, 0x78, 0x3c, 0x00,
0x03, 0xc3, 0xe0, 0x78, 0x3c, 0x00, 0x03, 0xc3, 0xc0, 0x3c, 0x3c, 0x00, 0x03, 0xc7, 0xc0, 0x3c,
0x3c, 0x00, 0x03, 0xcf, 0x80, 0x3e, 0x78, 0x00, 0x07, 0xdf, 0x00, 0x1e, 0x78, 0x00, 0x07, 0x9e,
0x00, 0x1e, 0x78, 0x00, 0x07, 0xbe, 0x00, 0x1f, 0x78, 0x00, 0x07, 0xbc, 0x00, 0x0f, 0x78, 0x00,
0x07, 0xf8, 0x00, 0x0f, 0x78, 0x00, 0x07, 0xf8, 0x00, 0x07, 0xf0, 0x00, 0x0f, 0x70, 0x00, 0x07,
0xf0, 0x00, 0x0f, 0x40, 0x00, 0x02, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x0f, 0x00,
0x00, 0x00, 0xf0, 0x00, 0x0e, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x60, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
},
{
// '16-segment-display-r', 48x62px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0xc0, 0xff, 0xc0, 0x00, 0x01, 0xff, 0xe1, 0xff, 0xc0, 0x00, 0x01,
0xff, 0xf3, 0xff, 0xc0, 0x00, 0x06, 0xff, 0xe3, 0xff, 0x30, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x70,
0x00, 0x0f, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00,
0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x1e, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x1e,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x1e, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x1e, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x1e, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x1e, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x3c, 0x00, 0x00,
0x03, 0xc0, 0x00, 0x3c, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x3c, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x3c,
0x00, 0x00, 0x03, 0xc0, 0x00, 0x3c, 0x00, 0x00, 0x07, 0x80, 0x00, 0x78, 0x00, 0x00, 0x07, 0x80,
0x00, 0x78, 0x00, 0x00, 0x07, 0x80, 0x00, 0x78, 0x00, 0x00, 0x07, 0x80, 0x00, 0x78, 0x00, 0x00,
0x07, 0x80, 0x00, 0x78, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x70, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x27,
0xf8, 0x1f, 0xf6, 0x00, 0x00, 0x1f, 0xfe, 0x7f, 0xf8, 0x00, 0x00, 0x1f, 0xfc, 0xff, 0xf0, 0x00,
0x00, 0x6f, 0xf0, 0xdf, 0xe0, 0x00, 0x00, 0xf0, 0x00, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x60,
0x00, 0x00, 0x01, 0xe0, 0x00, 0x70, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x70, 0x00, 0x00, 0x01, 0xe0,
0x00, 0x70, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x78, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x78, 0x00, 0x00,
0x03, 0xc0, 0x00, 0x78, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x3c, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x3c,
0x00, 0x00, 0x03, 0xc0, 0x00, 0x3e, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x1e, 0x00, 0x00, 0x07, 0x80,
0x00, 0x1e, 0x00, 0x00, 0x07, 0x80, 0x00, 0x1f, 0x00, 0x00, 0x07, 0x80, 0x00, 0x0f, 0x00, 0x00,
0x07, 0x80, 0x00, 0x0f, 0x00, 0x00, 0x07, 0x80, 0x00, 0x07, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x07,
0x00, 0x00, 0x0f, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0f, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
},
{
// '16-segment-display-d', 48x62px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0xc0, 0xff, 0xc0, 0x00, 0x01, 0xff, 0xe1, 0xff, 0xc0, 0x00, 0x01,
0xff, 0xf3, 0xff, 0xc0, 0x00, 0x00, 0xff, 0xeb, 0xff, 0x30, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x70,
0x00, 0x00, 0x00, 0x3c, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x3c, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x3c,
0x00, 0xf0, 0x00, 0x00, 0x00, 0x7c, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x78, 0x01, 0xe0, 0x00, 0x00,
0x00, 0x78, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x78, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x78, 0x01, 0xe0,
0x00, 0x00, 0x00, 0xf8, 0x01, 0xc0, 0x00, 0x00, 0x00, 0xf0, 0x03, 0xc0, 0x00, 0x00, 0x00, 0xf0,
0x03, 0xc0, 0x00, 0x00, 0x00, 0xf0, 0x03, 0xc0, 0x00, 0x00, 0x00, 0xf0, 0x03, 0xc0, 0x00, 0x00,
0x01, 0xf0, 0x03, 0xc0, 0x00, 0x00, 0x01, 0xf0, 0x07, 0x80, 0x00, 0x00, 0x01, 0xe0, 0x07, 0x80,
0x00, 0x00, 0x01, 0xe0, 0x07, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x80, 0x00, 0x00, 0x00, 0xc0,
0x07, 0x80, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x00,
0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x03, 0x00,
0x1e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x1e, 0x00, 0x00, 0x00,
0x07, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x07, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x3c, 0x00,
0x00, 0x00, 0x0f, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x0f, 0x00,
0x3c, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x78, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x78, 0x00, 0x00, 0x00,
0x1e, 0x00, 0x78, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x78, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x78, 0x00,
0x00, 0x00, 0x1e, 0x00, 0x78, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x3c, 0x00,
0xf0, 0x00, 0x00, 0x00, 0x3c, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x3c, 0x00, 0xf0, 0x00, 0x00, 0x00,
0x3c, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x38, 0x00, 0xf0, 0x00, 0x01, 0xff, 0xc7, 0xff, 0x60, 0x00,
0x03, 0xff, 0xcf, 0xff, 0x80, 0x00, 0x07, 0xff, 0x87, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
}
};
// H E L L O SP W O R L D
int imageTable[] = {0, 1, 2, 2, 3, -1, 4, 3, 5, 2, 6};
void app_main(void)
{
SSD1306_t dev;
#if CONFIG_I2C_INTERFACE
ESP_LOGI(TAG, "INTERFACE is i2c");
ESP_LOGI(TAG, "CONFIG_SDA_GPIO=%d",CONFIG_SDA_GPIO);
ESP_LOGI(TAG, "CONFIG_SCL_GPIO=%d",CONFIG_SCL_GPIO);
ESP_LOGI(TAG, "CONFIG_RESET_GPIO=%d",CONFIG_RESET_GPIO);
i2c_master_init(&dev, CONFIG_SDA_GPIO, CONFIG_SCL_GPIO, CONFIG_RESET_GPIO);
#endif // CONFIG_I2C_INTERFACE
#if CONFIG_SPI_INTERFACE
ESP_LOGI(TAG, "INTERFACE is SPI");
ESP_LOGI(TAG, "CONFIG_MOSI_GPIO=%d",CONFIG_MOSI_GPIO);
ESP_LOGI(TAG, "CONFIG_SCLK_GPIO=%d",CONFIG_SCLK_GPIO);
ESP_LOGI(TAG, "CONFIG_CS_GPIO=%d",CONFIG_CS_GPIO);
ESP_LOGI(TAG, "CONFIG_DC_GPIO=%d",CONFIG_DC_GPIO);
ESP_LOGI(TAG, "CONFIG_RESET_GPIO=%d",CONFIG_RESET_GPIO);
spi_master_init(&dev, CONFIG_MOSI_GPIO, CONFIG_SCLK_GPIO, CONFIG_CS_GPIO, CONFIG_DC_GPIO, CONFIG_RESET_GPIO);
#endif // CONFIG_SPI_INTERFACE
#if CONFIG_FLIP
dev._flip = true;
ESP_LOGW(TAG, "Flip upside down");
#endif
#if CONFIG_SSD1306_128x64
ESP_LOGI(TAG, "Panel is 128x64");
ssd1306_init(&dev, 128, 64);
#endif // CONFIG_SSD1306_128x64
#if CONFIG_SSD1306_128x32
ESP_LOGE(TAG, "Panel is 128x32. This demo cannot be run.");
while(1) { vTaskDelay(1); }
#endif // CONFIG_SSD1306_128x32
ssd1306_contrast(&dev, 0xff);
int numOfTable = sizeof(imageTable)/sizeof(int);
ESP_LOGI(TAG, "numOfTable=%d", numOfTable);
// Allocate memory
uint8_t *buffer = (uint8_t *)malloc(8*128); // 8 page 128 pixel
if (buffer == NULL) {
ESP_LOGE(TAG, "malloc failed");
while(1) { vTaskDelay(1); }
}
uint8_t *segmentImage = (uint8_t *)malloc(NUM_IMAGES*8*IMAGE_WIDTH); // 10 image 8 page 48 pixel
if (segmentImage == NULL) {
ESP_LOGE(TAG, "malloc failed");
while(1) { vTaskDelay(1); }
}
// Convert from segmentDisplay to segmentImage
for (int imageIndex=0;imageIndex<NUM_IMAGES;imageIndex++) {
ssd1306_clear_screen(&dev, false);
ssd1306_bitmaps(&dev, 0, 1, segmentDisplay[imageIndex], IMAGE_WIDTH, 62, false);
vTaskDelay(200 / portTICK_PERIOD_MS);
// Get from internal buffer to local buffer
// buffer is [8][128] 8 page 128 pixel
ssd1306_get_buffer(&dev, buffer);
// Save from buffer to segmentImage
// segmentImage is [10][8][IMAGE_WIDTH] 10 image 8 page 48 pixel
int segmentImageIndex = imageIndex * BITMAPS;
for (int page=0;page<8;page++) {
//ESP_LOGI(TAG, "segmentImageIndex+page*IMAGE_WIDTH=%d", segmentImageIndex+page*IMAGE_WIDTH);
memcpy(&segmentImage[segmentImageIndex+page*IMAGE_WIDTH], &buffer[page*128], IMAGE_WIDTH);
//ESP_LOGI(TAG, "page=%d", page);
//ESP_LOG_BUFFER_HEXDUMP(TAG, &buffer[page*128], IMAGE_WIDTH, ESP_LOG_INFO);
}
#if 0
ssd1306_clear_screen(&dev, false);
for (int page=0;page<8;page++) {
ssd1306_display_image(&dev, page, 0, &segmentImage[segmentImageIndex+page*IMAGE_WIDTH], IMAGE_WIDTH);
//ESP_LOGI(TAG, "page=%d", page);
//ESP_LOG_BUFFER_HEXDUMP(TAG, &segmentImage[segmentImageIndex+page*IMAGE_WIDTH], IMAGE_WIDTH, ESP_LOG_INFO);
}
vTaskDelay(1000 / portTICK_PERIOD_MS);
#endif
}
int imageIndex = 0;
int imageSegment = 0;
ssd1306_clear_screen(&dev, false);
while(1) {
// Shift segment data left by 2 bits
for (int page=0;page<8;page++) {
int bufferIndex = page*128;
memcpy(&buffer[bufferIndex], &buffer[bufferIndex+2], 126);
}
// Insert 2 bits at the end of segment data
if (imageTable[imageIndex] >= 0) {
int segmentImageIndex = imageTable[imageIndex] * BITMAPS;
for (int page=0;page<8;page++) {
int bufferIndex = page*128+126;
buffer[bufferIndex] = segmentImage[segmentImageIndex+page*IMAGE_WIDTH+imageSegment];
buffer[bufferIndex+1] = segmentImage[segmentImageIndex+page*IMAGE_WIDTH+imageSegment+1];
}
} else {
for (int page=0;page<8;page++) {
int bufferIndex = page*128+126;
buffer[bufferIndex] = 0;
buffer[bufferIndex+1] = 0;
}
}
imageSegment=imageSegment+2;
ssd1306_set_buffer(&dev, buffer);
ssd1306_show_buffer(&dev);
//vTaskDelay(5);
// End of display of one character
if (imageSegment == IMAGE_WIDTH) {
imageIndex++;
if (imageIndex == numOfTable) {
// All characters have been displayed.
// Scroll to last character.
for (int segs=0;segs<64;segs++) {
for (int page=0;page<8;page++) {
int bufferIndex = page*128;
memcpy(&buffer[bufferIndex], &buffer[bufferIndex+2], 126);
}
for (int page=0;page<8;page++) {
int bufferIndex = page*128+126;
buffer[bufferIndex]=0;
buffer[bufferIndex+1]=0;
}
ssd1306_set_buffer(&dev, buffer);
ssd1306_show_buffer(&dev);
}
imageIndex = 0;
}
imageSegment = 0;
}
} // end while
free(buffer);
}
Compiling the Sketch
To flash your chip, type the following command in the serial terminal. Remember to replace the COM port with the one through which your board is connected.
idf.py -p COMX flash monitor
After the code flashes successfully, you can view the informational messages being printed showing the SSD1306 configuration parameters and its status.
The OLED will start displaying the alphabets images that will scroll across the screen, showing the message HELLO WORLD. Watch the video below to have a better insight.
You may also like to read:
- I2C LCD with ESP32 using ESP-IDF
- ESP32 UART Communication using ESP-IDF
- ESP32 Set an Access Point (AP) using ESP-IDF
- ESP32 ESP-IDF Connect with WiFi – Station Mode Example
- ESP32 ESP-IDF FreeRTOS Semaphore – Tasks Synchronization Examples
- ESP32 PWM ESP-IDF LED Brightness Control Example
We are a team of experienced Embedded Software Developers with skills in developing Embedded Linux, RTOS, and IoT products from scratch to deployment with a demonstrated history of working in the embedded software industry. Contact us for your projects: admin@esp32tutorials.com
Nice tutorial.
I was strugling to make it works. I looked for some detailed instructions, but found just some pieces of code and videos using arduino IDE.
Nice work.
I am not getting ssd1306 configuration option in menuconfig. That’s why the code is not able to build. how to solve this?
Please download all files from here:
https://github.com/nopnop2002/esp-idf-ssd1306
I’m facing the same problem. I have downloaded all the files and copied them into the components folder, but I not getting the ssd1306 configuration option.
These examples only show how to display characters and bitmaps. What if i had a temp sensor and i wanted to display the temperature which is a float datatype. How to display that to the oled?
Thanks
And why OLED only displays how the whole system is connected as you can see on your Demo. So the whole system is powered via USB from the ESP board. Note and if the voltage is 5V or 3.3V from the power supply to the ESP, the display does not display anything. Such a cool problem Why doesn’t the OLED light up.