by Floris Wouterlood – October 28, 2019
Summary
For a number of applications with microcontroller boards like the Arduino the addition of a small display can be handy to show information, for instance that collected by a sensor. We discuss here how to wire a very popular monochrome 128×32 pixel graphic OLED display to an Arduino.. The display uses the SSD1306 chip. Communication runs via an I2C interface such that next to power and GND only two pins are required. As this documentation belongs to a series of ‘bare basics’ papers only the minimum requirements are discussed to get a 128×32 OLED display working with an Arduino. The Nano is used here because it is 100% Arduino Uno-compatible and has at the same time such a small footprint that it fits a prototyping breadboard. Nice and clean! Two sketches are presented, running with different libraries.
Introduction
There are many very small displays on the market based on OLED (organic light-emitting diode) technology. OLEDs are energy efficient, they are cheap, and compared with LCD displays they have the big advantage that they do not need background illumination. They also refresh faster. An 128×32 OLED device can be considered as a matrix of 4,096 individual pixels that each can individually be set ON – they light up – or OFF – just background. Because background is ink black the ON pixels stand out pretty nicely and readability is perfect. One sympathetic feature of the pixel array configuration is that it is possible to design and display graphic bitmaps: logos, avatars, sprites. Here we create a primitive static ‘smiley’, but much, much more is possible. The compilation of Arduino sketch instructions to machine language that can be uploaded requires libraries. A sketch is provided that uses the <Adafruit_SSD1306.h> and <Adafruit_GFX.h> libraries, and an alternative sketch that uses the <u8glib.h> library. All these libraries and their user documentation can be found at GitHub (https://github.com).
Figure 1: 128×32 OLED display with SSD1306 driver and I2C interface. The board is equipped with four pins: GND, VCC, SCL and SDA. This display is monochrome and is shipped with a green tag label.
Typical OLED displays are 0.96 inch in width. The PCB on which the current OLED display is mounted measures 39 x 6 millimeters (Figure 1). Each of the 128×32 pixels is in fact an individual OLED that can be switched on or off by the controller through software instructions. OLED displays can be powered by different driver chips. Most popular are the SH1106 and SSD1306. The display discussed here a SSD1306 chip.
128×32 monochrome SSD1306 based OLED with I2C interface: pins and connectivity with an Arduino
Connectivity table
OLED pin labels | connect to pin on the Arduino marked |
GND | GND |
VCC | 5V |
SCL | A5 |
SDA | A4 |
3.3V or 5V?
Most OLED displays, including this one, accepts both 3.3V and 5V DC power. While the Arduino Uno and Nano are typical 5V devices, newer designs such as the Internet of Things (IOT) family of ESP8266 based microcontroller boards use 3.3V logics. The 128×32 OLED display works equally well with these IOT microboards. Actually, all OLED displays run on 3.3V and power to the board as well as input signals are converted to 3.3V by an on-board voltage converter This means that the OLED display can be connected with the microcontroller board without the need of soldering resistors in series.
Figure 2: Wiring is very simple with an I2C 128×32 OLED display. The OLED display has four pins, marked GND. VCC, SCL and SDA. These are wired to, respectively, pins GND, 5V,A5 and A4 on the Nano. No resistors needed.
Electronics and supplies
1x Arduino Nano microcontroller board, breadboard, jumper wires, 128×32 I2C SSD1306 OLED display.
Figure 3: Working 128×32 OLED display on a breadboard with an Arduino Nano. Four jumper wires and action!
Sketches
Two sketches are supplied here. Both are ‘bare’ sketches that first print the text “Hello World” followed by a series of graphic instructions that together produce a ‘smiley’. The smiley consists of circles, lines and pixels.
The first of these sketches features instructions that need the Adafruit libraries <Adafruit_SSD1306.h> and <Adafruit_GFX.h> to get compiled. The second sketch needs Olikraut’s library <U8glib.h>. All these libraries are available at GitHub (https://github.com).
Sketch 1
// 128x32_OLED_Hello_World_Adafruitlib
// based on Adafruit libraries supporting graphic displays
// public domain
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
void setup(void) {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
}
void loop() {
display.clearDisplay (); // clear display
display.setCursor (10,5); // position the cursor
display.setTextSize (2); // medium size font
display.setTextColor (WHITE); // white is not default !
display.print (“Hello”);
display.setCursor (10,23);
display.setTextSize (1); // smallest font
display.print (“World”);
delay (1000); // wait a second
display.drawCircle (110,15,15, WHITE); // head contour
display.drawCircle (105,14,4, WHITE); // left eye
display.drawCircle (115,14,4, WHITE); // right eye
display.drawPixel (103,22, WHITE); // mouth
display.drawPixel (118,22, WHITE); // mouth
display.drawPixel (104,23, WHITE); // mouth
display.drawPixel (117,23, WHITE); // mouth
display.drawPixel (105,24, WHITE); // mouth
display.drawPixel (116,24, WHITE); // mouth
display.drawLine (106,25,115,25, WHITE); // mouth
display.display ();
delay (1000);
}
Sketch 2
// 128x32_OLED_Hello_World_u8glib
// based on the Olikraus u8glib library supporting I2C graphic displays
// public domain
#include <U8glib.h>
U8GLIB_SSD1306_128X32 u8g(U8G_I2C_OPT_NONE | U8G_I2C_OPT_DEV_0);
void setup(void)
{
//Set font.
u8g.setFont(u8g_font_unifont);
u8g.setColorIndex(1); // display draws with pixel on
}
void loop(void)
{
u8g.firstPage();
do {
draw();
} while (u8g.nextPage());
delay(50);
}
void draw(void)
{
u8g.setFont(u8g_font_helvB14); // font change – helvB14
u8g.drawStr(20, 13, “Hello”);
u8g.setFont(u8g_font_unifont); // font change – standard
u8g.drawStr(20, 28, “World”);
u8g.drawCircle (110, 15, 15); // contour
u8g.drawCircle (105, 14, 4); // left eye
u8g.drawCircle (115, 14, 4); // right eye
u8g.drawPixel (103,22); // mouth
u8g.drawPixel (118,22); // mouth
u8g.drawPixel (104,23); // mouth
u8g.drawPixel (117,23); // mouth
u8g.drawPixel (105,24); // mouth
u8g.drawPixel (116,24); // mouth
u8g.drawLine (106, 25, 115,25); // mouth
}
Discussion
OLED displays are a nice addition to the repertoire of displays available for the Arduino. Thanks to Oliver Kraus (‘Olikraus’ a complete library is available at https://github.com/olikraus/u8glib/wiki/userreference that documents all functions. The U8g library does not only work with 128×32 OLED displays but also with 128×64 OLED and LCD graphic displays. Because every individual pixel in an OLED display can be addressed, simple graphical elements can be designed and displayed such as open and filled circles, circle segments, ellipses, lines, rectangles and triangles.
Adafruit provides great demo sketches for OLED displays, and these can be found in the Arduino IDE when the Adafruit libraries have been installed.
Go to: Files → Examples -→Adafruit SSD1306 -→ssd1306_128x32_i2c, compile and upload, and enjoy!
Thanks to the Adafruit and Olikraus libraries the number of possibilities of displaying mixed graphic/numeric elements is seemingly endless. For prolonged static display however OLEDS seem less suitable. There are reports of ‘burning in’ of pixels in OLED displays and OLED TVs that have been endlessly in ‘ON’ state.