How to interface the OLED display with Raspberry Pi.

Today we will see how to interface the OLED display with Raspberry Pi. OLED stands for organic light-emitting diode. It is one of the popular display technique similar to LCD.

LCD vs OLED

If you take the LCD display for example, by controlling the voltage applied across the liquid crystal layer in each pixel, light can be allowed to pass through in varying amounts thus constituting different levels of gray. Colour LCD systems use the same technique, with colour filters used to generate red, green, and blue pixels. As LCDs do not produce light by themselves, a back light is used in liquid crystal displays. In contrast an OLED display consists of an array of Organic LEDs. Each OLED is a unique and an addressable pixel. An OLED display works without a back light because it emits visible light. Thus, it can display deep black levels and can be thinner and lighter than a liquid crystal display (LCD).

Now that we got a overview of OLED and how it is different from LCD let us get back to our project. The display we are using is a 128X64 monochrome display. Below is the front and back side of the OLED display. You can notice that the I2C address is printed here.

“SSD1306 is a single-chip CMOS OLED/PLED driver with controller for organic / polymer light emitting diode dot-matrix graphic display system. It consists of 128 segments and 64 commons. This IC is designed for Common Cathode type OLED panel. The SSD1306 embeds with contrast control, display RAM and oscillator, which reduces the number of external components and power consumption. It has 256-step brightness control. Data/Commands are sent from MCU through the hardware selectable 6800/8000 series compatible Parallel Interface, I2C interface or Serial Peripheral Interface. It is suitable for compact portable applications, such as mobile phone sub-display, MP3 player and calculator, etc.”

OLED display with Raspberry PI

Schematics:

The OLED should be connected as shown the in the below picture.

The display is connected to the I2C pins of thr Raspberry Pi i.e SDA (Data) and SCL (Clock). If you want to know more about the Raspberry Pi pinout refer to http://pinout.xyz/ . The pin placement order is shown the same way the board is placed in the below picture. The VCC is connected to 3.3V supply since the OLED and driver require a 3.3V power supply and 3.3V logic levels for communication. According to adafruit on an average the display uses about 20mA from the 3.3V supply, which is much less than what the 3v3 is capable of.

Hardware connection:

After setting up the connection the circuit looks like shown below.

OLED display with Raspberry PI

I2C Driver:

In order to access the I2C device the I2C driver needs to be enabled in the Linux kernel and rightly configure to used the hardware. The Rasbian Linux distribution which we use for our Raspberry Pi disables the loading of I2C by default, that means we need to enable that it always gets loaded when booting up.

To enable the I2C driver open the file /etc/modules as root and insert the below line. now you can open the file using nano or vim depending on your choice.

sudo vim /etc/modules
i2c-dev

In Linux when the I2C driver is loaded correctly and configured properly, it will appear as devices /dev/i2c-X where X can be 0, 1 so on. In Rasbian it appears as shown below.

pi@raspberrypi:~ $ ls /dev/i2c-*
/dev/i2c-1

Note: Though there exists two I2c interfaces in Raspberry Pi, Only one is available across all the Pi versions.

These are character devices (/dev/i2c-1) which are created by I2C driver. To access the devices that are connected to the bus you can either use I2C utilities or programs that are specifically written using I2C libraries. Now that we know about the I2C devices nodes let us install the utilities that can be used for scanning and debugging the I2C bus .

Install i2c tools

root@raspberrypi:~# apt-get install i2c-utils

We have connected the OLED display to the /dev/i2c-1 of the Raspberry Pi.
In order to know what is the I2C Address of the device (Though I know it already, it might help some where). We need to scan the I2C bus and there is a command for that, its called i2cdetect. It can be used as follows.

Now we know that the I2C address of the device is 0x3C. But wait, we found that Address printed in the display as 0x78 and here it shows 0x3C, how is that possible? The answer is that the actual address of the device is 0X3C and you use address 0x78 or 0x79, for write or read. As an additional information the I2C bus allows devices to be plugged and unplugged without rebooting Pi. It’ll mess up some accesses, but I2C will recover.

OLED python Library

With the emergence of Pi board and the Linux distros along with it there are always more than one library available for each interface. Likewise for OLED display there are many libraries and many variants of libraries . For the OLED with SSD1306 I choose this library https://github.com/rm-hull/luma.oled .

This is library is already available as part of python repository or as they called cheese cake factory ;). Type the below command to install all the required dependencies for using the OLED display.

Here I import the display hardware related module which can speak with ssd1306 controller.

from luma.core.interface.serial import i2c

Since the hardware uses I2C, I am importing the I2C handler related module from luma.core.interface.serial

from luma.core.render import canvas

Assume the canvas to be the buffer, which is used to transfer the content to the display controller.

device = ssd1306(port=1, address=0x3C) # rev.1 users set port=0

We specify which I2C bus and the device address to the display controller object and get a device handler as return. port represents the /dev/i2c-1, in case if the device is /dev/i2c-2 then port will be 2.

with canvas(device) as draw:

We pass this device handler to the canvas and it returns a canvas handler, which can be used like an Image and apply ImageFont and ImageDraw functions.

draw.rectangle(device.bounding_box, outline=”white”, fill=”black”)

The canvas handler has many methods one of them is to draw a rectangle. The border i.e the outline, is filled with white and the rectangle is filled with black.

draw.text((10, 40), “WWW.CODELECTRON.COM”, fill=”white”)

Here I display the text WWW.CODELECTRON.COM in white colour.

Now lets try to see another example which plots pixels

draw.point((5,9),fill=255)

If you want to plot a pixel then use the point method with X and Y co-ordinate to plot.

Going forward, lets see another example of how to plot a line instead of connecting dots manually 🙂

draw.line((0,0 , 20 , 20 ), fill=“white“)

Here I use the method line with start co-ordinates (X1,Y1) and end co-ordinates (X2, Y2)

Font example:

Here I am loading the font to the variable “font”, using the ImageFont.truetype method. Here I am using the font Volter__28Goldfish_29.ttf , but you can use any ttf font with the complete path. The number 20 is the font size you can play around with by reducing and increasing to see its effect on the screen.

draw.text((0, 0), “Hello World“, font=font, fill=255)

The font object is used as the font to display the text “Hello World”.

We covered examples of plot a pixel then we drew line using line method, drew rectangle, displayed text with font style. Hurrah, we have completed the basics of the luma OLED library, the final part of the process is to download some demo code from luma and play with it.

Install example codes:

clock.py

invaders.py

font_awesome.py

At the end we have setup the OLED connection, learnt about the I2C bus scanner for detecting I2C devices, installed luma library and played around with some couple of examples to display different types of graphic objects.

“Your code is your limit”, so keep coding and do share in the comments section below, if you have done any projects.