Adding a display to Raspberry PI Pico allows getting real time information from connected devices without using a computer from USB port. I2C LCD displays (with PCF8574 backpack) are one of best solution to keep wiring simple
In this tutorial I’m going to show you how to connect and use an I2C LCD display to Raspberry PI Pico.
I2C LCD displays are common LCD displays, usually composed of 16 columns x 2 rows blocks, but also different configurations can be found. Differently from simple LCD displays, they include a small panel soldered in its backside, including chips able to reduce their connection wires. The I2C LCD display usually has a PCF8574 chip, which is a device able to convert I2C serial communication into parallel connections.
A working solution uses the dhylands-python_lcd module including a generic API to interface to LCD displays. But this class implements commands to be sent to the LCD without caring about how to send them. The reason is that there are many different backpacks and every solution can be implemented in many different ways. The ones created with a PCF8574 use I2C as communication protocol, in this case, you need a sort of driver able to send commands via I2C. This function is implemented with a second module from T-622 user, also available from T-622 GitHub page.
What We Need
As usual, I suggest adding from now to your favourite e-commerce shopping cart all needed hardware, so that at the end you will be able to evaluate overall costs and decide if continuing with the project or removing them from the shopping cart. So, hardware will be only:
- A common computer (maybe with Windows, Linux, or Mac). It can also be a Raspberry PI Computer board
- Raspberry PI Pico microcontroller (with a common micro USB cable)
- I2C LCD Display (with PCF8574 backpack)
- dupont wirings
Check hardware prices with following links:
Please find in following picture my wiring diagram:
Following pictures give some additional details on my cabling:
Prepare cabling according to the previous paragraph. Connect RPI Pico to Thonny (you can refer to my tutorial about First steps with Raspberry PI Pico).
Download required micropython modules:
- the LCD_API: https://raw.githubusercontent.com/dhylands/python_lcd/master/lcd/lcd_api.py
- the I2C LCD: https://raw.githubusercontent.com/T-622/RPI-PICO-I2C-LCD/main/pico_i2c_lcd.py
You can also get them from my download area:
Download these files and save them in your Raspberry PI Pico root or under “lib” folder.
Before going into the usage explanation, you have to be sure that your LCD’s I2C address is correct. This is a unique address shared between I2C devices to make them able to talk on the same shared wire. This is usually a hexadecimal value and all devices connected to your RPI Pico can be scanned by copy-paste of the following code in your Thonny shell (you can copy all lines together):
import machine sdaPIN=machine.Pin(0) sclPIN=machine.Pin(1) i2c=machine.I2C(0,sda=sdaPIN, scl=sclPIN, freq=400000) devices = i2c.scan() if len(devices) == 0: print("No i2c device !") else: print('i2c devices found:',len(devices)) for device in devices: print("Hexa address: ",hex(device))
As I2C LCD with PCF8574 backpack use PCF8574 chip for I2C communication, you will probably get its default address (0x27). But if your project includes more PCF8574-based chips, then you will need to identify the LCD one between those that will be shown. In case of missing devices, please check your cabling.
Starting to use your LCD device, you can run a generic test with the T-622 test script, which I have pre-configured for 16×2 LCDs using I2C0 channel (ports GP0 and GP1 according to my wiring diagram). This modified script can be get from my download area (use the following link: i2c_lcd_test). Save this file in your Raspberry PI Pico root folder or in your computer and open it with Thonny IDE.
If your LCD display has a different I2C address, you will need to set it changing following line:
I2C_ADDR = 0x27
If your LCD display has a different number of total columns or rows, you will need to set them changing following lines:
I2C_NUM_ROWS = 2 I2C_NUM_COLS = 16
At this point, you are ready to test your display. From Tonny IDE run the “i2c_lcd_test.py” file (F5) and you will start seeing some tests in a loop.
If you will see nothing, please check your cabling. Another common issue with I2C LCD display is getting a clean screen which is only powering on and off. This means that your connection is correct and everything is working, you have only to adjust your LCD contrast by rotating the screw positioned in your LCD backside, which controls a potentiometer managing contrast:
This should solve your issue.
Showing Special Characters
The LCD API used has a flexible feature allowing users to display also complex icons inside a single cell. Some special characters are already available and depend on your LCD ROM (Read Only Memory, space not visible to the user). You can use these chars with “lcd.putchar(chr())” function.
In your Thonny shell, paste following code (you can copy all lines together):
from machine import I2C from lcd_api import LcdApi from i2c_lcd import I2cLcd I2C_ADDR = 0x27 I2C_NUM_ROWS = 2 I2C_NUM_COLS = 16 i2c = I2C(0, sda=machine.Pin(0), scl=machine.Pin(1), freq=400000) lcd = I2cLcd(i2c, I2C_ADDR, I2C_NUM_ROWS, I2C_NUM_COLS) lcd.putchar(chr(247))
If you get a “π” char, then you have a Japanese ROM. If you get a “÷”, then you have an European ROM.
As reported from LCD API author, characters match ASCII characters in range 32-127 (0x20-0x7F) with a few exceptions:
- 0x5C is a Yen symbol instead of backslash
- 0x7E is a right arrow instead of tilde
- 0x7F is a left arrow instead of delete
Only the ASCII characters are common between the two ROMs 32-125 (0x20-0x7D). You can refer to the HD44780 datasheet for the table of characters.
The first 8 characters (from 0 to 7) character-generator RAM. This means that you can define and design any icon you want to display by identifying pixels to be put on/off for each char block, made of 8 rows and 5 columns of pixels. Each row A good description of how to define a generic icon is explained in https://github.com/dhylands/python_lcd.
I’ve also prepared a simple MS Excel file that can help you designing your personal icon and generating related code to use in your script. You can download it from this link: bytearray code generator.
With this file, while you set to 1 or 0 (zero) the cells in the drawing zone, these cells will change color according to their value and the code will be generated. In this way, you will have an immediate preview of what you are drawing and related code to use:
You can use the generated code with “lcd.custom_char()” command. An example usage is built in my pico_i2c_lcd script. Download and open it in your Thonny IDE.
This scripts starts importing required modules:
import machine from machine import I2C from lcd_api import LcdApi from i2c_lcd import I2cLcd
Then common variables are set (please remember to set according to your device, if different from mine one):
I2C_ADDR = 0x27 I2C_NUM_ROWS = 2 I2C_NUM_COLS = 16
The i2c instance is initialized and lcd object is initialized:
i2c = I2C(0, sda=machine.Pin(0), scl=machine.Pin(1), freq=400000) lcd = I2cLcd(i2c, I2C_ADDR, I2C_NUM_ROWS, I2C_NUM_COLS)
Following part is where the custom icon is generated, using the code coming from my generator. This icon is associated to custom char (with id value going from 0 to 7):
heart = bytearray([0x00,0x0a,0x1f,0x1f,0x0e,0x04,0x00,0x00]) lcd.custom_char(0, heart)
Final line uses a concatenation (the “+” operator concatenates strings in MicroPython) of text strings and custom char to be printed on LCD display:
lcd.putstr("Hello from\n"+chr(0)+" peppe8o.com "+chr(0))
And following result comes from script running:
We are sorry that this post was not useful for you!
Let us improve this post!
Tell us how we can improve this post?