Skip to content

OLED SSD1351 Color Display

Welcome to the SSD1351 Color OLED Lab

Monty waving welcome In this lab, you will connect a small but stunning color OLED display. Every pixel glows with its own light — no backlight needed!

What Is This Display?

The SSD1351 is a driver chip for small color Organic Light-Emitting Diode (OLED) displays. OLED is different from LCD. In an LCD, a backlight shines through the screen. In an OLED, each pixel makes its own light. This gives you much deeper blacks and brighter colors.

This display is 1.5 inches diagonal. It shows 128 pixels wide by 128 pixels tall. The price is about $40, which makes it more expensive than most LCD displays. But the color quality and viewing angle are excellent.

It uses a Serial Peripheral Interface (SPI) connection to talk to the Pico.

OLED vs LCD

Monty thinking An OLED pixel that shows black is completely turned off — no light at all. An LCD showing black still has the backlight glowing behind it. This is why OLEDs have much deeper, truer blacks.

Drawing Shapes Demo

This program shows how to draw many different shapes on the display. It starts with simple lines and rectangles, then moves on to circles and polygons.

 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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
"""SSD1351 shapes demo — draws lines, rectangles, circles, and polygons."""
from time import sleep                      # import sleep to pause between drawings
from ssd1351 import Display, color565      # import the display driver and color helper
from machine import Pin, SPI               # import GPIO and SPI tools


def test():
    """Draw a series of shapes on the OLED display."""
    # set up SPI bus 2 — 14,500,000 bits per second is about the fastest this driver supports
    spi = SPI(2, baudrate=14500000, sck=Pin(18), mosi=Pin(23))
    print('spi started')

    # create the display object with its control pins
    display = Display(spi, dc=Pin(17), cs=Pin(5), rst=Pin(16))
    print('display started')

    # fill the whole screen with a blue-purple color
    display.clear(color565(64, 0, 255))
    sleep(1)

    display.clear()   # clear the screen to black

    # draw a horizontal magenta line at row 127, starting at column 10, going 63 pixels right
    display.draw_hline(10, 127, 63, color565(255, 0, 255))
    sleep(1)

    # draw a vertical cyan line at column 10, from row 0 down 127 pixels
    display.draw_vline(10, 0, 127, color565(0, 255, 255))
    sleep(1)

    # fill a white rectangle starting at (23, 50), 30 pixels wide and 75 pixels tall
    display.fill_hrect(23, 50, 30, 75, color565(255, 255, 255))
    sleep(1)

    # draw a red horizontal line across the very top of the screen
    display.draw_hline(0, 0, 127, color565(255, 0, 0))
    sleep(1)

    # draw a yellow diagonal line from (127, 0) to (64, 127)
    display.draw_line(127, 0, 64, 127, color565(255, 255, 0))
    sleep(2)

    display.clear()   # clear the screen to black

    # draw a connected series of cyan lines through a list of (x, y) points
    coords = [[0, 63], [78, 80], [122, 92], [50, 50], [78, 15], [0, 63]]
    display.draw_lines(coords, color565(0, 255, 255))
    sleep(1)

    display.clear()   # clear the screen

    # fill a green 7-sided polygon centered at (63, 63), radius 50
    display.fill_polygon(7, 63, 63, 50, color565(0, 255, 0))
    sleep(1)

    # fill a red rectangle on the left edge: x=0, y=0, width=15, height=127
    display.fill_rectangle(0, 0, 15, 127, color565(255, 0, 0))
    sleep(1)

    display.clear()

    # fill a light-blue square in the top-left corner
    display.fill_rectangle(0, 0, 63, 63, color565(128, 128, 255))
    sleep(1)

    # draw a magenta rectangle outline in the bottom-left corner (not filled)
    display.draw_rectangle(0, 64, 63, 63, color565(255, 0, 255))
    sleep(1)

    # fill a purple square in the top-right corner
    display.fill_rectangle(64, 0, 63, 63, color565(128, 0, 255))
    sleep(1)

    # draw a blue triangle outline centered at (96, 96), radius 30, rotated 15 degrees
    display.draw_polygon(3, 96, 96, 30, color565(0, 64, 255), rotate=15)
    sleep(3)

    display.clear()

    # fill a green circle centered at (32, 32), radius 30
    display.fill_circle(32, 32, 30, color565(0, 255, 0))
    sleep(1)

    # draw a blue circle outline centered at (32, 96), radius 30
    display.draw_circle(32, 96, 30, color565(0, 0, 255))
    sleep(1)

    # fill a red ellipse centered at (96, 32), 30 pixels wide and 16 pixels tall
    display.fill_ellipse(96, 32, 30, 16, color565(255, 0, 0))
    sleep(1)

    # draw a yellow ellipse outline centered at (96, 96), 16 pixels wide and 30 pixels tall
    display.draw_ellipse(96, 96, 16, 30, color565(255, 255, 0))

    sleep(5)           # wait 5 seconds so you can admire the last shape
    display.cleanup()  # shut down the display cleanly


test()   # run the test function

What Each Line Does

  1. from ssd1351 import Display, color565 — loads the SSD1351 driver and the color converter function.
  2. spi = SPI(2, baudrate=14500000, sck=Pin(18), mosi=Pin(23)) — starts SPI bus 2 at 14.5 million bits per second (close to the maximum for this driver).
  3. display = Display(spi, dc=Pin(17), cs=Pin(5), rst=Pin(16)) — creates the display with its three control pins.
  4. display.clear(color565(64, 0, 255)) — fills the whole screen with a blue-purple color.
  5. display.clear() — clears the screen to black (no color given means black).
  6. draw_hline(x, y, length, color) — draws a horizontal line from point (x, y) going length pixels to the right.
  7. draw_vline(x, y, length, color) — draws a vertical line from point (x, y) going length pixels down.
  8. fill_hrect(x, y, width, height, color) — fills a rectangle starting at (x, y).
  9. draw_line(x1, y1, x2, y2, color) — draws a straight line between two points.
  10. draw_lines(coords, color) — draws a series of connected lines through a list of (x, y) points.
  11. fill_polygon(sides, x, y, radius, color) — fills a regular polygon with the given number of sides.
  12. fill_circle(x, y, radius, color) — fills a circle centered at (x, y).
  13. draw_circle(x, y, radius, color) — draws only the outline of a circle.
  14. fill_ellipse(x, y, r_x, r_y, color) — fills an ellipse (a stretched circle) with horizontal radius r_x and vertical radius r_y.
  15. draw_ellipse(x, y, r_x, r_y, color) — draws only the outline of an ellipse.
  16. display.cleanup() — sends a shutdown command to the display and closes the SPI connection cleanly.

Monty's Tip

Monty giving a tip The color565() function takes red, green, and blue values from 0 to 255. Try mixing values to create your own custom colors!

SSD1351 MicroPython Driver

You need to install the driver before running this code. The driver file is ssd1351.py.

You can find the driver here:

Download ssd1351.py and copy it to your Pico using Thonny or mpremote.

Watch Out!

Monty warning Make sure the SSD1351 driver file is saved on the Pico, not just on your computer. The Pico runs the code from its own storage, so the driver must be there too.

SSD1351 Datasheet

You can read all the technical details about the SSD1351 chip here:

SSD1351 Datasheet (PDF) — NewHaven Displays

Great Work!

Monty celebrating You learned how to draw lines, shapes, circles, and polygons on a color OLED display! Next, try writing a program that draws your own pattern or picture using these drawing functions.