In this tutorial, we will learn to easily interface Raspberry Pi Pico with an SSD1306 OLED display(2.44cm/0.96 inches). Adding a display to your projects becomes crucial to view outputs from sensors. Many kinds of displays are used in microcontroller projects, such as e-ink displays, LCDs, dot matrix displays, and OLED displays. OLED displays are convenient as they have a fast refresh rate, better visibility, low power consumption, and high pixel density. Moreover, they can be easily interfaced using the I2C communication protocol. The coding in this guide is in MicroPython.
Overview of SSD1306 OLED Display
SSD1306 is a controller chip that can control 128×64 dot matrix diode displays. 128 and 64 refer to the horizontal and vertical pixels respectively i.e there are 128 pixels horizontally on the display and 64 pixels vertically, arranged in a rectangular matrix.
Features of SSD1306:
- Power Supply: 3V – 5V.
- On-chip low-power RC oscillator.
- Communication interface: Parallel interface, 3/4 wire SPI, I2C interface.
- Programmable Frame Rate.
- Operating temperature range: -40°C to 85°C.
Click below for the detailed datasheet of SSD1306 provided by Adafruit.
Prerequisites For Interfacing OLED Display to Pi Pico
- A Raspberry Pi Pico running MicroPython.
- 4 Pin I2C OLED display module(size: 0.96inch/2.44cm; 128×64).
- Breadboard and connecting wires.
Your Raspberry Pi Pico needs to be preloaded with a MicroPython UF2 file to program it in MicroPython. You can read our getting started guide for Raspberry Pi Pico where we show all the steps required to start programming Raspberry Pi Pico & Pico W. If you are using macOS, follow our guide to program Raspberry Pi Pico on macOS using Thonny IDE.
I2C is a communication protocol commonly used in embedded systems. It can facilitate communication between multiple devices using just a two-wire bus. Read more about I2C and how we can use the I2C in Pi Pico in our article Raspberry Pi Pico I2C Communication Guide.
Installation of MicroPython OLED Library in Thonny IDE
To communicate with the OLED display, we need to send certain commands with precise delays between the commands. Thankfully, there is a library that takes care of all the commands.
- Connect your Raspberry Pi Pico to your computer.
- Open Thonny IDE. On the bottom right corner of your IDE, ensure that the interpreter is set to MicroPython(Raspberry Pi Pico).
- On the top toolbar, click on Tools>Manage Packages.
- Type “micropython-ssd1306” on the search bar and press Enter. From the search results that appear, click on the library that you searched for.
- In the next window, you can view some details of the library. The author of this library is Stefan Lehmann. Click on Install.
The library will be installed in a folder called lib in Pico. If you wish to view the code in this library, in Thonny IDE, go to File>Open>Raspberry Pi Pico>lib and open the file called ssd1306.py.
Wiring Raspberry Pi Pico W with OLED Display
The Raspberry Pi Pico has two I2C ports. You can access these ports with various GPIO pins. Take a look at the pin diagram below.
As evident from the pinout diagram, many pins function as SDA and SCL. Each of these pins is connected to either of the two I2C ports internally. For our purpose, we can choose any of these pins to interface with the OLED display.
I2C requires 4 wires for communication- Positive voltage, Ground, SDA, and SCL. SDA stands for Serial Data. This wire sends the bits to communicate between two or more entities. SCL stands for Serial Clock. This wire is responsible for the synchronization of data.
Here we shall use the pin GP0 as SDA and GP1 as SCL. Note that these are pins 1 and 2 on our Pico.
Connect your Raspberry Pi Pico/Pico W to the 128×64 SSD1306 OLED display module as shown below.
Pin-to-Pin connection details:
|Raspberry Pi Pico Pin||OLED Display Pin|
|Pin 1 (GP0)||4(SDA)|
|Pin 2 (GP1)||3(SCL)|
|Pin 36(3.3 Volts Out)||2(VDD)|
Two 10K resistors are recommended to pull-up the SDA and SCL lines to 3.3V.
MicroPython Code for Raspberry Pi Pico OLED Display Interfacing
We will now write the script to interface the OLED display with Raspberry Pi Pico. This part of the sketch will make function calls to the ‘micropython-ssd1306’ library we installed earlier. We will learn how to print words in different rows easily.
Make sure your Pico is still connected to your computer. Open Thonny IDE and paste the following code into the main editor space.
# Source: Electrocredible.com, Language: MicroPython from machine import Pin, I2C from ssd1306 import SSD1306_I2C WIDTH =128 HEIGHT= 64 i2c=I2C(0,scl=Pin(1),sda=Pin(0),freq=200000) oled = SSD1306_I2C(WIDTH,HEIGHT,i2c) while True: oled.fill(0) oled.text("Electrocredible", 0, 0) oled.text("OLED interfacing", 0, 20) oled.text("Tutorial", 0, 40) oled.show()Code language: Python (python)
Click the run button in the top toolbar or press F5. Using the pop-up that appears, save it to Raspberry Pi Pico.
Give your script a file name with a ‘.py’ file name extension. If you wish to start the script as soon as Pico boots during power-up, save your script as main.py. Click OK when you are done.
Your OLED display should now display the words as shown in the image below.
Code Explanation For Displaying Text
We first import three modules-
SSD1306_I2C. Then in lines that follow, we specify the width and height of our display as 128 pixels and 64 pixels respectively.
from machine import Pin, I2C from ssd1306 import SSD1306_I2C WIDTH =128 HEIGHT= 64Code language: Python (python)
In the next line, we create an
i2c instance of the
machine.I2C class in MicroPython. In this constructor, we initialize four parameters inside the brackets- Peripheral ID(0), SCL pin(1), SDA pin(0), and the maximum frequency of the Serial Clock(200KHz).
The code under the “While True” block will keep on running till power is withdrawn. The function
oled.text() takes three parameters- the String of text to be displayed, the value of the starting x-axis pixel, and the value of the y-axis pixel. For example,
oled.text("OLED interfacing", 0, 20) will print the letters starting at the pixel number 0 on the x-axis and pixel 20 on y-axis.
oled.text("Electrocredible", 0, 0) oled.text("OLED interfacing", 0, 20) oled.text("Tutorial", 0, 40)Code language: Python (python)
oled.show() will display the above three lines of text.
Tip: If you want to display dynamic text or values, such as data from sensors, be sure to type
oled.fill(0) at the beginning or end of the main loop. This will clear the display every time the main loop runs. If you don’t clear the display, the characters will overlap each other and the text will be incomprehensible.
Scrolling Text Animation
The ‘framebuf’ module of MicroPython comes with a built-in method to display scrolling text. We can scroll text by using
oled.scroll(xstep, ystep) function. It takes two arguments. The arguments specify the number of pixels by which the text will be shifted on the x-axis and y-axis respectively. We scroll the text by one step to the right by setting ‘xstep’ to -1. We repeat this in a loop 128 times by setting the loop range to ‘WIDTH’.
Upload the following script to scroll a line of text:
# Source: Electrocredible.com, Language: MicroPython from machine import Pin, I2C from ssd1306 import SSD1306_I2C import time WIDTH =128 HEIGHT= 64 i2c=I2C(0,scl=Pin(1),sda=Pin(0),freq=200000) oled = SSD1306_I2C(WIDTH,HEIGHT,i2c) while True: oled.text("Scrolling text", 0, 0) for i in range (WIDTH): oled.scroll(-1,0) oled.show() time.sleep_ms(1)Code language: Python (python)
If you have an LCD that you want to interface with Pi Pico, visit our article – Raspberry Pi Pico LCD Tutorial-16×2 I2C Display(PCF8574) Interfacing Using MicroPython.
Display Graphics On OLED Display
The framebuf module has some useful prebuilt functions to display simple Bitmap graphics on an OLED display.
Display Horizontal line
We can use the oled.hline(x, y, w, c) function which takes four parameters. The x-position of the starting end of the line is the argument ‘x’, the y-position is ‘y’, ‘w’ is the width of the line, and ‘c’ should be set to ‘1’ for monochrome display. Enter the following code in your main program to see the results.
oled.text("Horizontal Line", 0, 0) oled.hline(0,32,128,1) oled.show() time.sleep(2) oled.fill(0)Code language: Python (python)
Display Vertical line
The oled.vline(x, y, w, c) function works in the same way as the one above. Here ‘w’ indicated the vertical length of the line in pixels.
oled.text("Vertical Line", 0, 0) oled.vline(64,20,40,1) oled.show() time.sleep(2) oled.fill(0)Code language: Python (python)
Use the function oled.rect(x, y, w, h, c) to display a rectangle. x,y indicates the top-left starting pixel, and w and h denote the width and height of the rectangle respectively.
oled.text("Rectangle", 0, 0) oled.rect(32,16,64,32,1) oled.show() time.sleep(2) oled.fill(0)Code language: Python (python)
You can also display a filled rectangle by using oled.fill_rect(x, y, w, h, c)
oled.text("Filled Rectangle", 0, 0) oled.fill_rect(32, 16, 64, 32, 1) oled.show() time.sleep(4) oled.fill(0)Code language: Python (python)
Troubleshooting: “OSError: [Errno 5] EIO” In Raspberry Pi Pico
This issue is often caused by wrong or loose wire connections. I faced this issue because of a defective jumper wire. Ensure that the pins you are connecting your Pico to the OLED are correct. This problem may also occur if you are not using pull-up resistors. Such pull-up resistors are recommended to be used while using I2C communication.
If you want to experiment further, here is a project that uses an OLED display: Raspberry Pi Pico DHT22(AM2302) Interfacing Tutorial. Please comment below if you have any queries regarding this Raspberry Pi Pico OLED display tutorial. Thanks for reading and have a fun time making projects!