Post

ENG | Raspberry Pi Pico, MicroPython, and Nokia 5110 display

Learn how to connect and use the Nokia 5110 LCD display with a Raspberry Pi Pico using MicroPython. Tutorial covers the wiring, code implementation, and troubleshooting tips.

Introduction

The Nokia 5110 LCD (PCD8544) is a compact and affordable monochrome display that has become a popular choice for hobbyists and makers working with microcontrollers like the Raspberry Pi Pico. Despite its simple design, the Nokia 5110 offers a convenient way to display text, graphics, and basic animations, making it suitable for a wide range of projects, from status displays and user interfaces to games.

In this tutorial, we’ll explore how to connect the Nokia 5110 display to the Raspberry Pi Pico using MicroPython, a lightweight implementation of Python optimized for microcontrollers. We’ll walk through the necessary wiring, explain the code implementation, and provide some helpful tips for troubleshooting and customization.

Raspberry Pi Pico and Nokia 5110 Display

Wiring

LCD
Pin
NameNotePico
Pin
Name
1RSTExternal reset input, active low22GP17
2CEChip enable, active low24GP18
3D/CData high / Command low21GP16
4DINSerial data input15GP11 SPI:MOSI/TX
5CLKSerial clock, up to 4MHz14GP10 SPI:SCK
6VCCSupply voltage 2.7-3.3V363V3
7BLBacklight, active low??Depends
8GNDGround38GND

Backlight is on when BL is connected to ground, so it does not have to be connected to Pico.

Code (adopted from example)

As I understand it numbers in SPI(1, baudrate=1000000, mosi=Pin(11), sck=Pin(10)) and SPI wiring must match Raspberry Pi Pico pinout. There are two SPI drivers that can select from certain combinations of pins.

Wiring is according to YouTube video tutorial, which uses CircuitPython from AdaFruit, and it’s mostly demonstration without much practical information. The following code uses MicroPython.

I used micropython-pcd8544 repository, copied example from README.md file into my main.py file as a starting point. We need to download pcd8544.py from the repository and to put it next to our main.py file into project folder. Then upload it to Pico. That’s all.

Changes from the original example are pins, delays

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
100
101
102
103
104
import pcd8544
from machine import Pin, SPI
import sys
from utime import sleep

"""
Philips PCD8544 / Nokia 5110 LCD pinout according to backside description and
this video tutorial https://educ8s.tv/raspberry-pi-pico-nokia5110-display-tutorial-using-circuitpython/,
https://github.com/educ8s/CircuitPython_PCD8544_Graphics
sadly, this is for CircuitPython and AdaFruit ecosystem

Library used: https://github.com/mcauser/micropython-pcd8544

This code is based on example.

|Pin|Name | Note                             | Pico Pin  |
|--:|-----|----------------------------------|-----------|
| 1 | RST | External reset input, active low | 22: GP17  |
| 2 | CE  | Chip enable, active low          | 24: GP18  |
| 3 | D/C | Data high / Command low          | 21: GP16 |
| 4 | DIN | Serial data input                | 15: GP11 SPI:MOSI/TX |
| 5 | CLK | Serial clock, up to 4MHz         | 14: GP10 SPI:SCK |
| 6 | VCC | Supply voltage 2.7-3.3V          | 36: 3V3 |
| 7 | BL  | Backlight, active low            | Depends |
| 8 | GND | Ground                           | 38: GND |
"""

spi = SPI(1, baudrate=1000000, mosi=Pin(11), sck=Pin(10))
cs  = Pin(18)
dc  = Pin(16)
rst = Pin(17)

lcd = pcd8544.PCD8544(spi, cs, dc, rst)

# test pattern (50% on)
lcd.data(bytearray([0x55, 0xAA] * 42 * 6))
sleep(1)

# bitmap smiley (horzontal msb)
lcd.clear()
# draw 8x16 in bank 0 (rows 0..7)
lcd.position(0, 0)
lcd.data(bytearray(b'\xE0\x38\xE4\x22\xA2\xE1\xE1\x61\xE1\x21\xA2\xE2\xE4\x38\xE0\x00'))

sleep(1)
# draw 8x16 in bank 1 (rows 8..15)
lcd.position(0, 1)
lcd.data(bytearray(b'\x03\x0C\x10\x21\x21\x41\x48\x48\x48\x49\x25\x21\x10\x0C\x03\x00'))
sleep(1)

# toggle display, image persists in DDRAM
lcd.power_off()
lcd.power_on()
sleep(1)

# nokia logo bitmap (84x48/8=504 bytes)
lcd.clear()
lcd.data(bytearray( \
    b'\x80\x00\x00\x80\x00\x00\x80\x00\x00\x80\x00\x00\x80\x00\x00\x80\x00\x00\x80\x80\x40\x40\x40\x80\x80' \
    b'\xC0\xC0\x40\xC0\xA0\xE0\xC0\xE0\xE0\xF0\xF0\xF8\xF8\xF8\xFC\xFC\xFE\xEE\xF4\xF0\xF0\x70\x30\x00\x80' \
    b'\x00\x00\x80\x00\x0C\x9C\x1C\x38\xB8\x38\x38\xB8\xF8\xF0\xF0\xF0\xF0\xF0\xF0\xF0\xF0\xF0\xF0\xF0\xF0' \
    b'\xF0\xF0\xF0\xF0\xF0\xF8\xF8\xF8\xF8\x88\x20\x8A\x20\x08\x22\x08\x00\x0A\x00\x00\x02\x80\x71\xBA\xDA' \
    b'\xFD\xDD\xED\xDE\xEE\xF7\xFF\xFB\xFD\xFD\xFE\xFF\x7F\x3F\x1F\x9F\x3F\x7F\x6F\x0F\xAF\x1F\xBF\x3E\x3C' \
    b'\x7A\x78\x70\x22\x88\xA0\x2A\x80\x08\x62\xE0\xE0\xF2\xF0\x58\xDA\xF8\xFC\x92\xFE\xFF\xFF\xD3\xFF\xFD' \
    b'\xF3\xE1\xF0\xF9\x7F\xBF\x3F\x8F\x2F\x4F\xAF\x0F\x4F\xA7\x0F\xAF\x87\x2F\x82\x80\x20\xC0\x80\x80\x50' \
    b'\x40\xC4\xD0\xA0\xE8\xE4\xEA\xFF\xFB\xFD\xFF\xFF\xFF\xFF\xFF\xEF\x4F\x27\x53\xA8\x54\x29\x4A\xB5\x82' \
    b'\xAC\xA1\x8A\xB6\x50\x4D\x32\xA4\x4A\xB4\xA9\x4A\x52\xB4\xAA\x45\xA8\xDA\x22\xAC\xD2\x2A\x52\xA8\x52' \
    b'\x4C\xB0\xAD\x43\x5B\xB3\x45\xA8\x5B\xA3\xAB\x55\xA8\x52\x54\xA9\x56\xA8\x45\xBA\xA4\x49\x5A\xA2\x54' \
    b'\xAA\x52\xFE\xFF\xFF\xFE\xFD\xFF\xFF\xFF\xFE\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F\xFF' \
    b'\xFE\xBF\x7F\xBF\xBF\xFF\xDF\xBF\x5F\xDF\x7F\xDF\x7F\xDF\xAF\x7F\xEE\x8E\xF1\x6E\x99\xF7\x6A\xDD\xB2' \
    b'\x6E\xD5\x7A\xD7\xAC\x75\xDB\x6D\xD5\x7A\xD7\xAC\x7B\xE5\xDE\xA9\x77\xDA\xB5\xEE\x59\xB6\xEB\xDD\xB6' \
    b'\x69\xD6\xBF\xE8\x55\xEF\xB9\xD6\xED\xB5\x5B\xAB\xFF\xFD\xF7\xFF\x01\x01\x01\x01\xE1\xC1\x81\x03\x05' \
    b'\x0F\x1D\x2F\x7E\x01\x00\x01\x01\xFF\xFE\x03\x01\x01\x00\xF1\xF0\xF1\x71\xF1\xF1\xB1\xF1\x01\x01\x01' \
    b'\x03\xFE\xFF\x01\x01\x01\x01\xBE\x1B\x0D\x07\x03\x41\xE1\xF1\xF9\x6D\xFF\xFF\x00\x01\x01\x01\xFF\xFF' \
    b'\xEB\x3E\x0D\x03\x01\x41\x71\x70\x41\x01\x03\x0E\x3B\xEF\xFE\xFB\xEE\x7D\xF7\xFF\xFF\xFF\xFF\xFE\xFF' \
    b'\xF0\xF0\xF0\xF0\xFF\xFF\xFF\xFF\xFE\xFC\xF8\xF0\xF0\xF0\xF0\xF0\xF0\xFF\xFF\xF8\xF0\xF0\xF0\xF1\xF1' \
    b'\xF1\xF1\xF1\xF1\xF1\xF1\xF0\xF0\xF0\xF8\xFF\xFF\xF0\xF0\xF0\xF0\xFF\xFF\xFE\xFC\xF8\xF0\xF0\xF1\xF3' \
    b'\xF7\xFF\xFF\xF0\xF0\xF0\xF0\xFF\xF3\xF0\xF0\xF0\xFC\xFC\xFC\xFC\xFC\xFC\xFC\xFC\xF0\xF0\xF0\xF3\xFF' \
    b'\xFF\xFF\xFF\xFF'))
sleep(1)

lcd.invert(True)
sleep(1)
lcd.invert(False)
sleep(1)

#lcd.reset()
#lcd.init()

# swtich to vertical addressing
#lcd.init(horizontal=False)

# adjust contrast, bias and temp
lcd.contrast(0x1f, pcd8544.BIAS_1_40, pcd8544.TEMP_COEFF_0)
sleep(1)
lcd.contrast(0x3f, pcd8544.BIAS_1_48, pcd8544.TEMP_COEFF_0)
sleep(1)
lcd.contrast(0x3c, pcd8544.BIAS_1_40, pcd8544.TEMP_COEFF_0)
sleep(1)
lcd.contrast(0x42, pcd8544.BIAS_1_48, pcd8544.TEMP_COEFF_0)
sleep(1)
lcd.contrast(0x3f, pcd8544.BIAS_1_40, pcd8544.TEMP_COEFF_2)
sleep(1)
print("Done")

Troubleshooting

  • Sadly, one of my two displays did not work and briefly blinked when powered on ☠
  • It’s a bit sensitive to timing? errors during data transfer, sometimes nothing is drawn, sometimes Nokia logo is distorted

Conclusion

Congratulations! You’ve successfully learned how to set up and use the Nokia 5110 display with your Raspberry Pi Pico using MicroPython. With this knowledge, you can now incorporate this versatile display into your projects, opening up a world of possibilities for creating interactive and visually engaging applications.

Remember, the code and wiring provided in this tutorial serve as a starting point. Feel free to modify and expand upon them to suit your specific needs. Additionally, consider exploring other display options, sensors, and peripherals that can be integrated with the Raspberry Pi Pico, unlocking even more possibilities for your projects.

Happy coding and keep exploring the exciting world of microcontrollers and displays!

This post is licensed under CC BY 4.0 by the author.