Organic Light Emitting Diode (OLED) displays are very popularly used in embedded systems
First, let us set up the circuit. Connect the OLED display to the NodeMCU as shown in the diagram below.
OLED VCC – NodeMCU 3.3V
OLED GND – NodeMCU GND
OLED SCL – NodeMCU D1
OLED SDA – NodeMCU D2
To begin with the code download and install the library found in the link below.
https://github.com/ThingPulse/esp8266-oled-ssd1306
For the 1.3 inch OLED display used in this tutorial, the header file we need to use is SH1106.h
First, let us have a look at displaying text on the OLED.
//Include the necessary libraries
#include <Wire.h>
#include <SH1106Wire.h>
//Initialize the display
//I2C address is 0x3c
//SH1106Wire display(I2C_ADDRESS, SDA, SCL);
SH1106Wire display(0x3c, D2, D1);
void setup()
{
// Initialize the display
display.init();
//if you want to invert the display
display.flipScreenVertically();
}
void loop()
{
//set the font face and font size
display.setFont(ArialMT_Plain_24);
//clear the display
display.clear();
//center align the text
display.setTextAlignment(TEXT_ALIGN_CENTER);
//draw the text on the screen
display.drawString(64, 10, “Robocraze”);
//left align the text
display.setTextAlignment(TEXT_ALIGN_LEFT);
//draw the text on the screen
display.drawString(0, 40, String(millis()));
//update the display to show the text
display.display();
delay(10);
}
In the code above the display.drawString() method is used to draw text on the screen. The two arguments to this function are the x and y coordinates in of where you want to place the text given in pixels and the third argument is the text to be drawn.
This text can be customized in multiple ways. The display.setFont() method sets the font face and size. In the example above we are using ArialMT Plain with font size 24 points. The display.setTextAlignment() method can be used to make the text left, right or centre aligned. Custom fonts can also be designed but that is not covered within the scope of this article.
The display.flipScreenVertically() method can be used to invert the display in case it is mounted in such a way and is desired to be flipped.
The display.clear() method clears the screen contents and display.display() method draws all the buffered graphics onto the OLED.
Let us now look at how to draw images onto the OLED display. The images displayed on the OLED have to be in XBM format. Take an image in BMP format and use the conversion tool provided in the following website to convert it to XBM format.
Or if you wish to design a small XBM image pixel by pixel you can find a useful tool here
Given below is an example image.
static char img[] = { 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0xf8, 0x1f, 0x0c, 0x30, 0xe6, 0x67, 0xf3, 0xcf, 0x19, 0x98, 0xcc, 0x33, 0xe6, 0x67, 0x30, 0x0c, 0x90, 0x09, 0xc0, 0x03, 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01 };
This is a 16x16 image of the wifi symbol.
Following code covers drawing images on the OLED display.
//Include the necessary libraries
#include <Wire.h>
#include <SH1106Wire.h>
//Initialize the display
//I2C address is 0x3c
SH1106Wire display(0x3c, D2, D1);
//declare the image
#define WiFi_Logo_width 60
#define WiFi_Logo_height 36
const uint8_t WiFi_Logo_bits[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00,
0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF,
0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
0xFF, 0x03, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0xFF, 0xFF, 0xFF, 0x07, 0xC0, 0x83, 0x01, 0x80, 0xFF, 0xFF, 0xFF,
0x01, 0x00, 0x07, 0x00, 0xC0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0C, 0x00,
0xC0, 0xFF, 0xFF, 0x7C, 0x00, 0x60, 0x0C, 0x00, 0xC0, 0x31, 0x46, 0x7C,
0xFC, 0x77, 0x08, 0x00, 0xE0, 0x23, 0xC6, 0x3C, 0xFC, 0x67, 0x18, 0x00,
0xE0, 0x23, 0xE4, 0x3F, 0x1C, 0x00, 0x18, 0x00, 0xE0, 0x23, 0x60, 0x3C,
0x1C, 0x70, 0x18, 0x00, 0xE0, 0x03, 0x60, 0x3C, 0x1C, 0x70, 0x18, 0x00,
0xE0, 0x07, 0x60, 0x3C, 0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C,
0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00,
0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00, 0xE0, 0x8F, 0x71, 0x3C,
0x1C, 0x70, 0x18, 0x00, 0xC0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x08, 0x00,
0xC0, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x0C, 0x00, 0x80, 0xFF, 0xFF, 0x1F,
0x00, 0x00, 0x06, 0x00, 0x80, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x07, 0x00,
0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0xF8, 0xFF, 0xFF,
0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00,
0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF,
0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00,
0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
void setup()
{
// Initialize the display
display.init();
//if you want to invert the display
display.flipScreenVertically();
//clear the display
display.clear();
//draw the image on the screen
display.drawXbm(34, 14, WiFi_Logo_width, WiFi_Logo_height, WiFi_Logo_bits);
//write the buffer to the display
display.display();
}
void loop() {}
In the code above we see the method display.drawXbm() being used. This takes 5 arguments. First, two are the coordinates of the image in pixels, the next two arguments are the width and height of the image in pixels. Since we are using a 60x36 image hence we pass those to the method. The final argument is the image itself to be drawn onto the display.