Raspberry Pi Pico OLED Display (SSD1306)
“As an Amazon Associates Program member, clicking on links may result in Maker Portal receiving a small commission that helps support future projects.”
The Raspberry Pi Pico microcontroller and SSD1306 OLED display are the central components used in this tutorial, while a Raspberry Pi 4 computer is recommended for interfacing and programming on the Pico. A breadboard and some jumper wires will be helpful as well, and any sensor or motor that may be used in parallel with the SSD1306. The full parts list used to follow along with this tutorial is given below, with links:
The wiring diagram between the Pico (see the Pico pinout for reference) and SSD1306 display is given below:
The SSD1306 is wired to one of the Raspberry Pi Pico’s I2C port. On the Pico, there are two different I2C ports: I2C0, I2C1. We are wiring to the I2C1 port via GPIO pins 26/27 (physical pins 31/32). Any of the I2C-compatible pins can be used with the SSD1306. We are using GPIO26/27 due to their proximity to the power and ground pins being used. In the next section, the SSD1306 MicroPython library will be introduced and used to create a simple Raspberry Pi logo and text, based on the Pico’s MicroPython SDK document.
All of the codes used in this tutorial can be found at the project’s GitHub page:
Under the ‘micropython’ folder at the repository above there is a series of subfolders that contain examples that use the I2C MicroPython library that interfaces with the SSD1306. The file called sssd1306.py is the actual SSD1306 library, which must be uploaded to the Pico upon running each example file. The ssd1306.py library is given below for reference:
The library above is taken directly from the MicroPython GitHub page. The set of registers given at the top of the code above outline many of the commands used to control and interact with the SSD1306. The I2C port on the Pico carries out the commands that set the parameters relevant to the SSD1306, for example, the width, height, frequency, color mapping, etc. Going forward, the library will be used for each example but will not be referenced further. Instead, the examples will focus on applications of the library, such as displaying images, writing and coordinating text, inverting the display, among others.
This section focuses on displaying an image and writing text next to the image at the same time. Two examples are given on the GitHub page, as follows:
Raspberry Pi Logo Display - This is the Raspberry Pi Pico demonstration for the SSD1306. It displays the Raspberry Pi logo with the text ‘Raspberry Pi Pico’ displayed next to it
Custom Logo Display - This code displays a custom logo uploaded to ‘imgfile.py’ created by the custom Python3 script. Using an image, a Python3 script converts an image to a byte array. This byte array needs to be uploaded to the imgfile.py in bytearray() form. Then, the main script displays this image on the SSD1306.
In this section, we focus on the custom logo display. Users can easily copy and paste and try the Raspberry Pi logo display. It is similar to the custom logo display, but uses the RPi logo.
Preparing the Custom Logo for Display
A custom .png image file should be placed in the ‘python3’ folder. Then, on a Raspberry Pi or other computer, the ‘png_to_bytearray.py’ script should be run. It will print out a custom bytearray():
This is the image format that needs to be copied and pasted into the /micropython/logo_display/imgfile.py file:
The script also prints out the image resolution, which in our case is 64x64 pixels, which should also be updated into the main.py file. After copying the byte array above into the imgfile.py, run the main.py file and observe the newly printed logo on the SSD1306 display!
The text display has also been built out from the original Pico demonstration on the MicroPython SDK. The text display snippet is given below as an example (code can be found at the GitHub Page):
The snippet above takes a text array and places the text vertically in the display window. Depending on the starting x,y values and the skip between lines, the text will appear a certain way within the window. It’s a very simple placement of text, without any control over overflow (text past the window extents), text size, or vertical or horizontal centering.
An example output displaying one of our logos on the SSD1306 is given below:
In this section, the limits of the SSD1306 were pushed by testing the display with a real-time signal. A MEMS microphone with analog output was selected as the time-varying signal to be read by the Pico microcontroller. Then, the signal will be plotted on the OLED display in dot format. This emulates an audio signal and is capable of replicating the wave form of a signal in pseudo real-time. The speed of the ADC is fast enough for audio, which is read at high speed, then plotted when the OLED becomes available for refresh again. We were able to get update rates of roughly 15 Hz, or 15 refreshes per second.
For the data display in real time, we must first use the analog-to-digital converter to read a sensor. As stated above, a MEMS microphone was being used, however, any sensor that produces data in real time can be used. The data will be read using the follow snippet of code (full code here):
We are using the analog input pin #2, which correlates to physical pin #34 and GPIO28. Also, the snippet above loops through all 128 pixels on the horizontal display dimension and places a new data point from the ADC onto that point, thus, giving a real-time plot emulator. Of course, there will be a significant delay between each plot update, which is noticeable when using a high-speed input such as a microphone.
Below is a clip of the SSD1306 displaying a real-time wave of 250Hz outputted by a smartphone and being read by a MEMS microphone:
The demonstration above really shows the capabilities of the Raspberry Pi Pico and its ability to capture waveforms of a specific audio signal. Of course, users may want to add axes and labels to the plot for real-time analysis, however, the demonstration proves that the SSD1306 is a highly capable device and able to be integrated with the Pico microcontroller via MicroPython.
In this third entry to the the Raspberry Pi Pico microcontroller tutorial series, an SSD1306 OLED display was interfaced via the I2C port of the Pico. A MicroPython library was introduced to control the SSD1306 display, along with a few scripts that display custom logos and real-time data plots. A separate Python3 program is given that allows users to create their own custom image to be displayed on the OLED. The real-time data display was able to refresh 128 data points at a rate of 15Hz (15 refreshes per second), which was capable of showing waveforms produced by an analog MEMS microphone. The SSD1306 is a useful tool for visualizations and printing out information related to sensors and modules — specifically when developing internet of things (IoT) nodes that wirelessly send and receive data or control motors and actuators. This tutorial was meant as a further exploration into the Raspberry Pi Pico microcontroller, with a focus on I2C communication. In the future of this series, more peripherals will be tested, such as SPI, UART, analog-to-digital conversion specifics, and even the capabilities of the dual-processor!
See More in Raspberry Pi and Pico: