
Using an SSD1315 OLED with the Raspberry Pi Pico
A couple of weeks back we started stocking an interesting new OLED display from our friends over at Waveshare - a two-colour SSD1315 0.96" OLED to be exact.
Funky dual-colours aside, the part we weren't sure about is the use of an SSD1315 driver chip rather than the much more common SSD1306 which has attracted lots of libraries and support over the years.
We thought this might make it difficult to find libraries for, but it turns out you can use existing SSD1306 libraries - with a few tweaks.
Waveshare don't currently offer connection/code examples for using this SSD1315 OLED with the Raspberry Pi Pico, so we had a play and figured it out!
What You'll Need
This tutorial is specifically based around the 0.96" OLED Display Module - Upper Yellow/Lower Blue (128x94) that we have in the store, but it'll likely work with any SSD1315 OLED.
You'll also need a Raspberry Pi Pico and Micro-USB cable of course!
Wiring can be connected however you like. Either use the included jumper wire assembly that comes with the display and connect directly to the Pico's pins, or use a breadboard and some male to male jumper wires like we did.
Setting I2C Mode
The display we're using offers both SPI or I2C mode (if you're using a different display, you may not need to do this). The mode is set according to the arrangement of the tiny SMT resistors on the rear of the display.
By default the display is set to SPI mode. As we've never had much joy using SPI with OLEDs like these with the Pico, we set ours to I2C mode.
To set the display to I2C mode, grab your soldering iron, heat resistor R1 (highlighted in the image below) and remove it using tweezers or a similar tool. You may just be able to snip it off with some precision diagonal cutters, but de-soldering is the 'proper' way!
Wiring the Circuit
Whether you're using a breadboard or connecting directly to the Pico's pins - the connections are the same and involves just four wires. The table below shows which pin connects from the OLED to your Pico:
Display | Pico |
VCC | Pin 40 (VBUS) |
GND | Pin 38 (GND) |
DIN | Pin 1 (SDA) |
CLK | Pin 2 (SCL) |
Here's a Fritzing diagram to confirm where these pins are too:
Install the MicroPython SSD1306 Library
We're using MicroPython and Thonny
We'll be using MicroPython to code this little example, so that means we're using Thonny.
We're assuming that you're familiar with Thonny and have it all set up, but if not, go check out our Raspberry Pi Pico Getting Started Guide which will tell you everything you need to know.
Install the library
We need to install a library to make our display work. Don't let the name confuse you - although we're using an SSD1315 OLED display, the SSD1306 library works with it - we just have to tweak it slightly once installed to make it work.
Here are the steps to follow:
- In Thonny, from the top menu bar select Tools > Manage packages
- In the search bar, enter "micropython-ssd1306" then select the search button
- Select the micropython-ssd1306 option (usually top of the list)
- Select Install
Editing the MicroPython SSD1306 Library
By default, the SSD1306 library looks for a specific I2C address of 0x3C, because that's what most SSD1306 modules usually use.
Our rogue SSD1315 OLED, with the resistors/pads on the rear as they are, uses address 0x3D. If we don't tell the library about this, it won't work (you'd see an error message of OSError: [Errno 5] EIO otherwise).
On the left of your Thonny window you should see the library files that would have appeared after adding it. Open the ssd1306.py file by double-clicking it:
Scroll down the file that opens and find the section below, a code block called class SSD1306_I2C.
See the 0x3C address we've highlighted with the arrow? Change that to 0x3D then save the file and close it. That's all the updates we need to make.
The Code
We're going to run a very simple demo program just to show that it works, then you're free to code whatever it is your project needs.
We've re-used the code from our Maker Advent Calendar Day #11 blog post, with just a tweak to the OLED size (128x64) and some larger gaps to show the text in the different colours that this display offers.
Copy the code below over to Thonny then hit the green button to run it:
# Imports
from machine import Pin, I2C
from ssd1306 import SSD1306_I2C
import time
# Set up I2C and the pins we're using for it
i2c=I2C(0,sda=Pin(0), scl=Pin(1), freq=400000)
# Short delay to stop I2C falling over
time.sleep(1)
# Define the display and size (128x32)
display = SSD1306_I2C(128, 64, i2c)
# Clear the display first
display.fill(0)
# Write a line of text to the display
display.text("Hello Yellow!",0,0)
display.text("Hello Blue!",0,17)
display.text("Hello Blue!",0,27)
display.text("Hello Blue!",0,37)
display.text("Hello Blue!",0,47)
display.text("Hello Blue!",0,57)
# Update the display
display.show()
How it works
First we import the things we need, including the SSD1306 library we installed and tweaked:
# Imports
from machine import Pin, I2C
from ssd1306 import SSD1306_I2C
import time
These lines set up I2C, with a short delay afterwards which is required to stop it getting stroppy and crashing out:
# Set up I2C and the pins we're using for it
i2c=I2C(0,sda=Pin(0), scl=Pin(1), freq=400000)
# Short delay to stop I2C falling over
time.sleep(1)
Next we tell the program what display we're using. Well, kind of!
We lie and tell it we're using an SSD1306 as this is what the library is expecting, but it works with our SSD1315 just fine thanks to our tweaks. As part of this we define the size (128x64) and communication type (I2C) too:
# Define the display and size (128x32)
display = SSD1306_I2C(128, 64, i2c)
We always clear the display first, just in case something is lurking from our last run:
# Clear the display first
display.fill(0)
Then we tell the display what we'd like to show. For this simple example we're just showing lines of text one after the other.
The last two numbers of each of these lines determines where the text is displayed - the first number is how far from the left, the second number is how far down from the top.
The top section of our OLED displays in yellow, so the first line includes text to reflect that. The other lines are lower than this, which is controlled by the last number in the brackets.
Note that nothing will show on the display yet. That happens next.
# Write a line of text to the display
display.text("Hello Yellow!",0,0)
display.text("Hello Blue!",0,17)
display.text("Hello Blue!",0,27)
display.text("Hello Blue!",0,37)
display.text("Hello Blue!",0,47)
display.text("Hello Blue!",0,57)
The last part of our program updates the display with the lines we entered above:
# Update the display
display.show()
As with all things in the makerverse, there are likely better or alternative ways to achieve this (maybe even using SPI but we didn't fancy that headache!).
Feel free to leave a comment with your methods, suggestions or even some code for people to try.
We used Fritzing to create the breadboard wiring diagram images for this page.
3 comments
Keith
Giving a reference to https://docs.micropython.org/en/latest/esp8266/tutorial/ssd1306.html (or something with similar content) which shows at least some of the other display commands would be helpful for beginners who want to go beyond the demo and play with or use the display.
Giving a reference to https://docs.micropython.org/en/latest/esp8266/tutorial/ssd1306.html (or something with similar content) which shows at least some of the other display commands would be helpful for beginners who want to go beyond the demo and play with or use the display.
The Pi Hut
@Tony – You may be able to use the Arduino example on Waveshare’s Wiki (as the Pico can be programmed in the Arduino IDE), however you’ll likely need to tweak pin numbers etc: https://www.waveshare.com/wiki/0.96inch_OLED_Module#Arduino_User_Guide
@Tony – You may be able to use the Arduino example on Waveshare’s Wiki (as the Pico can be programmed in the Arduino IDE), however you’ll likely need to tweak pin numbers etc: https://www.waveshare.com/wiki/0.96inch_OLED_Module#Arduino_User_Guide
tony
Many thanks for the readme. Is there anything out there in ‘C’ or C++ that you know of?
Many thanks for the readme. Is there anything out there in ‘C’ or C++ that you know of?