Raspberry Pi Pico I2C LCD: Wiring, Code and Simulator
To build this Raspberry Pi Pico I2C LCD project you need a Raspberry Pi Pico and a 16x2 LCD. machine.I2C on GP0/GP1 finds the LCD backpack at 0x27 and drives it with a 30-line driver. Make the 4 connections in the wiring table, upload the MicroPython code, and read the driver: each I2C byte sets the backpack pins, and E pulses latch each nibble.
Open this circuit in the free Raspberry Pi Pico simulator
Parts list
| Qty | Part | What it does |
|---|---|---|
| 1 | Raspberry Pi Pico | the microcontroller board |
| 1 | 16x2 LCD | Character LCD (HD44780). Wiring "full": RS, E and D4–D7 to pins (LiquidCrystal). Wiring "i2c": SDA to A4, SCL to A5 (LiquidCrystal_I2C, address 0x27). |
Wiring
| # | From | To |
|---|---|---|
| 1 | Raspberry Pi Pico GP0 | 16x2 LCD SDA |
| 2 | Raspberry Pi Pico GP1 | 16x2 LCD SCL |
| 3 | Raspberry Pi Pico VBUS | 16x2 LCD VCC |
| 4 | Raspberry Pi Pico GND | 16x2 LCD GND |
Step by step
- Open the simulator. Open the BitForBytes Embedded Lab in your browser and start from the Raspberry Pi Pico. No install or account is needed.
- Add the parts. Add a 16x2 LCD from the parts palette.
- Wire 1. Connect Raspberry Pi Pico GP0 to 16x2 LCD SDA.
- Wire 2. Connect Raspberry Pi Pico GP1 to 16x2 LCD SCL.
- Wire 3. Connect Raspberry Pi Pico VBUS to 16x2 LCD VCC.
- Wire 4. Connect Raspberry Pi Pico GND to 16x2 LCD GND.
- Paste the MicroPython code. Paste the MicroPython code below into the code editor.
- Run it. Press Run. Read the driver: each I2C byte sets the backpack pins, and E pulses latch each nibble.
MicroPython code
# I2C LCD: a 16x2 display with a PCF8574 backpack on I2C0 (SDA = GP0, SCL = GP1).
# MicroPython has no LCD library built in, so the driver is right here: every
# byte on the bus sets the backpack's 8 pins, which are wired to the LCD as
# P0 = RS, P2 = E, P3 = backlight, P4-P7 = D4-D7.
from machine import Pin, I2C
import time
i2c = I2C(0, sda=Pin(0), scl=Pin(1), freq=100000)
print("I2C devices found:", [hex(a) for a in i2c.scan()])
ADDR = 0x27
BACKLIGHT = 0x08
def nibble(value, rs):
data = (value << 4) | BACKLIGHT | rs
i2c.writeto(ADDR, bytes([data | 0x04, data])) # pulse E high, then low
def send(value, rs=0):
nibble(value >> 4, rs)
nibble(value & 0x0F, rs)
def init():
time.sleep_ms(50)
for _ in range(3):
nibble(0x03, 0)
time.sleep_ms(5)
nibble(0x02, 0) # 4-bit mode
send(0x28) # 2 lines, 5x8 font
send(0x0C) # display on, cursor off
send(0x06) # move right after each character
send(0x01) # clear
time.sleep_ms(2)
def write(text, row=0):
send(0x80 | (0x40 * row)) # cursor to the start of the row
for ch in text:
send(ord(ch), 1)
init()
write("Hello from Pico")
count = 0
while True:
write("Count: {} ".format(count), 1)
count += 1
time.sleep(1)
What to try
Read the driver: each I2C byte sets the backpack pins, and E pulses latch each nibble.
Frequently asked questions
How do I wire the I2C LCD project on a Raspberry Pi Pico?
Make 4 connections: Raspberry Pi Pico GP0 to 16x2 LCD SDA; Raspberry Pi Pico GP1 to 16x2 LCD SCL; Raspberry Pi Pico VBUS to 16x2 LCD VCC; Raspberry Pi Pico GND to 16x2 LCD GND.
What parts do I need for this Raspberry Pi Pico project?
A Raspberry Pi Pico and a 16x2 LCD.
Can I simulate this Raspberry Pi Pico project online for free?
Yes. The BitForBytes Embedded Lab runs this exact circuit and MicroPython code in your browser for free, with no install and no hardware. The RP2040 is emulated and runs the official firmware.
What does the code do?
machine.I2C on GP0/GP1 finds the LCD backpack at 0x27 and drives it with a 30-line driver.
More Raspberry Pi Pico projects
- Raspberry Pi Pico LED Blink: Wiring, Code and Simulator
- Raspberry Pi Pico Push Button: Wiring, Code and Simulator
- Raspberry Pi Pico ADC + PWM LED Dimmer: Wiring, Code and Simulator
- Raspberry Pi Pico NeoPixel Ring: Wiring, Code and Simulator
- Raspberry Pi Pico DHT22 Sensor: Wiring, Code and Simulator
- Raspberry Pi Pico LED Blink: Wiring, Code and Simulator