How to setup OLED display with Raspberry Pi – Python – SSD1306

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 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. Color LCD systems use the same technique, with color filters used to generate red, green, and blue pixels. As LCDs do not produce light by themselves A backlight is used in liquid crystal displays. In contrast an OLED display consist of an array of Organic LED. Each OLED is an unique and addressable pixel . An OLED display works without a backlight 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 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.

Raspberry Pi

Banggood: https://goo.gl/wrcUS3
Amazon US: http://amzn.to/2Dw3oKT
Amazon Germany : http://amzn.to/2FUW5Sj

 OLED Display:

Banggood https://goo.gl/rxy2yZ
Amazon US http://amzn.to/2tNAw0X
Amazon Germany http://amzn.to/2Dt9bk6

Female to Female Jumper Cable Wires 20cm

Banggood: https://goo.gl/E93MCh
Amazon US: http://amzn.to/2FISFmg
Amazon Germany: http://amzn.to/2pkj27N

SSD1306 controller

The display uses SSD1306 as its display controller. The data sheet for the controller can be found here https://cdn-shop.adafruit.com/datasheets/SSD1306.pdf
An Excerpt of the data sheet is given below for technical overview.

“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 general 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.

OLED display with Raspberry PI

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 average the display uses about 20mA from the 3.3V supply which is much less than what the 3v3 is capable of.

https://upload.wikimedia.org/wikipedia/commons/6/61/Raspberry-pi-gpio.png
https://upload.wikimedia.org/wikipedia/commons/6/61/Raspberry-pi-gpio.png

Hardware connection:

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

OLED display with Raspberry PI
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 correct 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 exist two i2c interface 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.

Capture1

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 dependancies for using the OLED display.

$ sudo apt-get install python-dev python-pip libfreetype6-dev libjpeg-dev build-essential
$ sudo -H pip install --upgrade luma.oled

Now during the installation if you get any error like shown below

NameError: name 'platform_system' is not defined

Then type the below command and then try again to install the above packages.

sudo pip install -U pip

For the latest information about the installation always refer to
https://luma-oled.readthedocs.io/en/latest/install.html 

Now lets download the example codes that I have developed for explaing the luma-oled library.

Example code:

git clone https://github.com/codelectron/codelectron_projects
cd codelectron_projects/Rpi/OLED
python first.py

Now I will run the first python example first.py

OLED display with Raspberry PI

from luma.oled.device import ssd1306, ssd1325, ssd1331, sh1106

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 the the buffer which will be used to transfer the content to display controller.

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

We specifiy 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 the is draw a rectangle. The border i.e 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 color.

Now lets try to see another example which plots pixels

OLED display with Raspberry PI

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.

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

OLED display with Raspberry PI

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:

OLED display with Raspberry PI

font = ImageFont.truetype(./ssd1306/fonts/Volter__28Goldfish_29.ttf,20)

Here I 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 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”.

OLED display with Raspberry PI

 

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

Install example codes:

git clone https://github.com/rm-hull/luma.examples
cd luma.examples/examples

Try some examples such as

clock.py

OLED display with Raspberry PI

invaders.py 

 font_awesome.py 

At end we have setup the OLED connection, learnt about the I2C bus scanner for detecting I2C devices, Installed luma library and played around some couple of examples to display different type of graphic objects. There is a lot that can be done using this small OLED device “your code is your limit” so keep coding and do share in the comments section ,if you have done any projects or any comments or feedback. I will come up with next article with something new and interesting.

Leave a Reply

Your email address will not be published. Required fields are marked *