OLED SSD1306 SPI Examples
Welcome to the SPI Display Lab
In this lab, you will connect an SSD1306 OLED display using the Serial Peripheral Interface (SPI). SPI uses more wires than I2C, but it refreshes the screen about 13 times faster!
Using the SSD1306 with SPI Interfaces
Add the ssd1306 Python Module
You need to add the SSD1306 driver to your Pico before you can use it. You can do this in Thonny using the Tools → Manage Packages... menu. Search for ssd1306 and install it. You need to do this once for each new device type you use.
If the Manage Packages menu is grayed out, go to the Shell at the bottom of Thonny and type the install command there.
Install SSD1306 Module
ssd1306 module
SSD1306 Library — click the RAW button, then right-click and choose "Save As" to download the file.
The SPI Interface
The four-wire Inter-Integrated Circuit (I2C) connection is great for beginners who do not want to hook up many wires. But sometimes you need a faster screen with faster refresh times. This is when the Serial Peripheral Interface (SPI) connection is useful.
SPI needs seven wires total, but it can update a 128 x 64 pixel screen about 13 times faster than I2C.
Displaying SPI Defaults
Run this short program to see the default SPI settings on your Pico.
1 2 3 4 5 6 7 | |
SPI Baudrate
The baud rate is the number of signals the SPI bus sends per second. You can read more about Pico SPI baud rates here: https://raspberrypi.github.io/pico-sdk-doxygen/group__hardware__spi.html#ga37f4c04ce4165ac8c129226336a0b66c
The seven wires on the back of the SPI OLED screens are the following, reading from top to bottom when looking at the back of the display:
- CS — Chip Select — pin 4
- DC — Data/Command — pin 5
- RES — Reset — pin 6
- SDA — Data — SPI0 TX GP7 pin 10
- SCL — Clock — Connect to SPI0 SCK GP6 pin 9
- VCC — Connect to the 3.3V Out pin 36
- GND — pin 38 or any other GND pin
Pico Pins
1 2 3 4 5 6 7 8 9 10 | |
- SCK is the clock — connect this to the OLED SCL pin.
- MOSI is the line carrying data from your Pico to the display. Connect this to the SDA pin.
From the SDK: https://datasheets.raspberrypi.org/pico/raspberry-pi-pico-python-sdk.pdf Section 3.7
- SPI0_SCK — pin 6
- SPI0_MOSI — pin 7
- SPI0_MISO — pin 8
This contradicts p122 in GET STARTED WITH MICROPYTHON ON RASPBERRY PI PICO
1 2 3 | |
We send the data to the SPI RX (Receive) port on the Pico. These are pin 1 (GP0) or pin 6 (GP4).
Key Idea
SPI uses five signal wires: Clock, Data, Chip Select, Data/Command, and Reset. Each wire has its own job. Together they let your Pico and display talk very fast!
Sample Nonworking SPI Code
From the documentation:
From
spi is an SPI object, which has to be created beforehand and tells the ports for SCLJ and MOSI. MISO is not used.
dc is the GPIO Pin object for the Data/Command selection. It will be initialized by the driver.
res is the GPIO Pin object for the reset connection. It will be initialized by the driver. If it is not needed, it can be set to None or omitted. In this case the default value of None applies.
cs is the GPIO Pin object for the CS connection. It will be initialized by the driver. If it is not needed, it can be set to None or omitted. In this case the default value of None applies.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | |
What each line does:
import machine— loads the hardware library.import utime— loads the time library (used forsleep).import ssd1306— loads the display driver.led = machine.Pin(25, machine.Pin.OUT)— sets up the built-in LED as an output.spi_sck = machine.Pin(6)— names the SPI clock pin.spi_tx = machine.Pin(7)— names the SPI data pin (also called MOSI).spi = machine.SPI(0, ...)— creates the SPI bus at 100,000 signals per second.CS = machine.Pin(8)— Chip Select pin. The driver pulls this low when talking to the display.DC = machine.Pin(9)— Data/Command pin. Tells the display if you are sending a drawing command or pixel data.RES = machine.Pin(10)— Reset pin. Restarts the display chip.oled = ssd1306.SSD1306_SPI(...)— creates the display object using all the SPI pins.oled.fill(1)— turns on all pixels (white screen).oled.show()— sends the image to the screen.utime.sleep(0.5)— waits 0.5 seconds so you can see the white screen.oled.fill(0)— clears the screen to black.oled.text(...)— draws text at the top-left corner.oled.show()— sends the text to the screen. 18–20. LED flash — blinks the Pico's built-in LED to show the program finished.
Watch Out!
Double-check that VCC goes to the 3.3V pin on your Pico, not the 5V pin. Most small OLED displays only work at 3.3V. Connecting to 5V can damage the display.
References
https://www.mfitzp.com/article/oled-displays-i2c-micropython/
https://github.com/adafruit/Adafruit_CircuitPython_SSD1306/blob/master/examples/ssd1306_stats.py
https://github.com/robert-hh/SH1106/blob/master/sh1106.py
DIY More OLED Product Description
SSD1306
https://www.solomon-systech.com/en/product/advanced-display/oled-display-driver-ic/ssd1306/
SSD1307
https://www.solomon-systech.com/en/product/advanced-display/oled-display-driver-ic/ssd1307/
Great Work!
You learned about the SPI interface and how all seven wires work together. SPI displays are fast and powerful. Next, you will build a wiring harness to make connecting displays easier!


