Table of Contents
Overview:
In this quick tutorial, learn how to connect 16X2 LCD display module without I2C adapter with Raspberry Pi Pico board which requires lots of wire connections and also learn connecting Raspberry Pi Pico board with 16X2 LCD display module using I2C adapter which uses only 2 wires for data transfer and 2 wires to power up.
Many latest Microcontroller boards are coming along with WiFi and Bluetooth which can create webservers to display the data on PC or mobile displays but the new Raspberry Pi Pico neither has WiFi nor Bluetooth, To play with projects and to display the output it has only 2 options to display the data either on Serial monitor or by connecting a LCD display or OLED display. We can add WiFi to Raspberry Pi Pico to create a webserver but it moves towards very complex side. So, lets know the process and coding to connect Pico board with 16×2 LCD display and same for 20X4 LCD display and display some simple text on it.
16X2 LCD display module:
As the name indicates 16X2, means it can display characters in 16 columns and 2 rows and LCD is the Liquid crystal Display. It can display total of 16X2=32 characters. Each character is made with 5width x 8height pixel dots =total 40 pixel dots for one character. To make a character, pixel dots should be lit black according to the character shape and other pixels should be in off state. So for every character all the 40 pixel dots are to be instructed weither to be lit on or off.
As our 16X2 LCD display has 32 Characters, there should be 32X40=1280 instructions to be sent to display 32 characters on the display, which is a very complex task for microcontrollers. So, to overcome this issue, an IC HD44780 which can process the data and commands from the microcontrollers and convert them into LCD meaningful instructions to display the data on it. It has a separate library with instructions and commands, if you want to twerk with it to build anything advanced refer its datasheet here.
As you can see from the above LCD display module pinout diagram the display is powered with VCC:5v and GND. It has 8 data pins for 8 bit data but we can also use 4 bit data mode which we are using in this example. has pins for LCD backlight and contrast adjustments using potentiometer.
Method1: Interfacing 16X2 LCD display module with Raspberry Pi Pico with out I2C adapter
Required components (Bill of Materials):
Product Name | Quantity | ||
---|---|---|---|
16X2 LCD module without I2C | 1 | https://amzn.to/3I3Uaax | https://amzn.to/363ki7F |
Raspberry Pi Pico Board(seedstudio) | 1 | https://amzn.to/36gKUlu | https://amzn.to/3sTnD1Z |
10K potentiometer | 1 | https://amzn.to/34RnDGx | https://amzn.to/3vPQSEP |
Few Connecting Wires | https://amzn.to/3H2BV4e | https://amzn.to/3J0WVu2 | |
5V power supply (Micro USB or External). | 1 | https://amzn.to/3s1a8g3 | https://amzn.to/364yInH |
Circuit diagram:
Connect all the required components listed above as shown in the schematic diagram below. for details on pins look at the Raspberry Pi Pico Pinout diagram.
As you can see from the above connection diagram you can see VSS,A pins from LCD display are connected to 5v supply from pin 40 Vbus of Raspberry Pi Pico. VSS, RW and K are connected to GND of Raspberry Pi Pico, RS and E pins of LCD display are connected to 21,22(GP16,GP17) of Pico board. The data pins D4,D5,D6 and D7 of LCD display are connected to 24,25,26 and 27 pins(GP18,GP19,GP20,GP21) of Raspberry pi Pico respectively.
Potentiometer first pin is connected to 5v, second pin to VO of LCD, third pin to GND.
Source code for LCD with no I2C:
After connecting all the required components as shown in the above circuit diagram, next step is to upload the code, Raspberry Pi Pico supports Micro python code which can be installed using PC as explained in our previous projects. After installing Micro Python we need Thonny IDE to compile and upload the code to Raspberry Pi Pico. So, copy the below code and paste it in Thonny IDE workspace.
Note: We need to add few libraries to make the LCD fully functional with multiple commands. Download below files and copy them on the Raspberry Pi Pico root folder.
After opening the library files now click on file-> new and copy the below code and paste in the new workspace and save with name: mainlcd.py
from machine import Pin from gpio_lcd import GpioLcd # Create the LCD object lcd = GpioLcd(rs_pin=Pin(16), enable_pin=Pin(17), d4_pin=Pin(18), d5_pin=Pin(19), d6_pin=Pin(20), d7_pin=Pin(21), num_lines=2, num_columns=16) # #The following line of codes should be tested one by one according to your needs # # #1. To print a string to the LCD, you can use lcd.putstr('circuitschools.') # #2. Now, to clear the display. # lcd.clear() # #3. and to exactly position the cursor location # lcd.move_to(0,1) lcd.putstr('LCD16x2display') # # If you do not set the cursor position, # # the character will be displayed in the # # default cursor position starting from # # 0, x and 0, y location which is the top left-hand side. # # There are other useful functions we can use in using the LCD. # #4. Show the cursor # lcd.show_cursor() # #5. Hide the cursor # lcd.hide_cursor() # #6. Turn ON blinking cursor # lcd.blink_cursor_on() # #7. Turn OFF blinking cursor # lcd.blink_cursor_off() # #8. Disable display # lcd.display_off() # this will only hide the characters # #9. Enable display # lcd.display_on() # #10. Turn backlight OFF # lcd.backlight_off() # #11. Turn backlight ON # lcd.backlight_on() # # 12. Print a single character # lcd.putchar('x') # but this will only print 1 character # #13. Display a custom characters using hex codes, you can create the character from here. # happy_face = bytearray([0x00,0x0A,0x00,0x04,0x00,0x11,0x0E,0x00]) # lcd.custom_char(0, happy_face) # lcd.putchar(chr(0))
After uploading the code you can see the text circuitschools. displayed on the first line and LCD16x2display on the second line of LCD module as shown in the below image output image.
Method2: Interfacing 16X2 LCD display module with Raspberry Pi Pico with I2C adapter
This method is simple and easier than the previous method as it uses I2C interface protocol to transfer the data using only 2 pins SDA and SCL. In this method we are using 16X2 LCD display module which has I2C adapter connected to 16 pins of normal LCD display and outputs only 4 pins.
The I2c adapter has PCF8574 8-Bit I/O Expander IC which converts the I2C data from the microcontrollers to parallel data required to the LCD display module. This adapter has a jumper to turn ON/OFF the backlight which can save the power consumption, and also has an inbuilt potentiometer to adjust the contrast of the LCD display module.
Required components:
- Raspberry Pi Pico microcontroller board
- 16X2 LCD module with i2c adapter
- Few connecting wires.
Circuit diagram
Connect all the required components listed above as shown in the below schematic diagram
As you can see there are only 4 connecting wires, the LCD module VCC and GND are powered from VBUS(pin40) and GND(pin38) pins of Raspberry pi Pico board respectively. The data pins of LCD module SDA and SCL are connected to GP8(pin11) and GP9(pin12) of Pico board which acts as SDA and SCL as you can see from the Raspberry Pi Pico pinout diagram.
If you previously connected a non I2C LCD display module with Pico board and now with this method you feel like “Wow! this is so easy and clean…”.
Related article: Interfacing 16X2 LCD Module with ESP32 with and without I2C
Source code:
After connecting according to the connection diagram, next step is to upload the code, as Raspberry Pi Pico support MicroPython, Install micropython on it and Upload the code using Thonny IDE.
Note: LCD display I2C requires few pre coded libraries, download them from below links.
After downloading the above files copy them into the Raspberry Pi Pico MicroPython directory. Now open Thonny IDE and click new and copy the below code and paste in the workspace.
from machine import I2C, Pin from pico_i2c_lcd import I2cLcd i2c = I2C(0, sda=Pin(8), scl=Pin(9), freq=400000) I2C_ADDR = i2c.scan()[0] lcd = I2cLcd(i2c, I2C_ADDR, 2, 16) while True: print(I2C_ADDR, "| Hex:",hex(I2C_ADDR)) print() lcd.move_to(0,0) lcd.putstr("I2CAddress:"+hex(I2C_ADDR)+"\n") lcd.move_to(0,1) lcd.putstr("CircuitSchools.")
With the above code we are able to get the I2C address of the LCD display and print it on the Shell and LCD display module in line 1 and print simple text in second line of LCD. This code can be also used as an I2C address scanner code as it scans and collect the addresses of I2C devices connected with the below code.
I2C_ADDR = i2c.scan()[0] #[0] is for the first device address connected, as we have only one i2c device connected we are using 0
Mainly the LCD displays with PCF8574 I2C adapter has I2C addresses 0x27 or 0x3F. So after uploading the code you can see the output on the LCD display as shown in the below image.
Video Tutorial:
If you found this project helpful please share our site with your friends and help them learn. If you have any doubts or errors regarding this project please through comments on us from the below comments section. Please subscribe to our YouTube Channel “Circuit Schools“ to encourage us to publish more interesting projects. Thanks with love 🙂
As soon as I connect my display to pin 40 my PC loses the connection to the Raspberry pi Pico. does anyone of you know a solution? otherwise I like the explanations really well
Hi Julius,
I think may be the voltage from the PC is not sufficient, Try connecting the display with an external 5V power supply like mobile chargers.
I hope this solves your problem, Thanks.
Hello. I’m not professionell, but i used for non I2C the other Pico’s Pin-numbering named GPxx. You have 21,22 and 24-27. I changed the numbers in your code to 16,17 and 18-21. But for understanding, at the same pin-connection.
And thank you!!!
Hi
nice tutorial !!
I refer to the first option “Source code for LCD with no I2C:”
I hv no potentiometer on hand… what is the alternative ?
I had connected VO directly with 5 V, but still no light in the display…
Any tipp ?
thank you for ur time!
brdgs
Bernhard form Germany
some resistors can in theory replace the potentiometer, I wouldn’t advise it though
Put a 1k-2k resistor to ground.
Hello. The non-I2C example code has the pin numbers incorrect. It uses physical pin numbers but the library code expects the GPIO pin numbers so to correspond with the wiring diagram replace 21 & 22 with 16 & 17 and 24-27 with 18-21. The backlight on and off examples don’t work unless the A pin on the LCD is connected to a GPIO Pin and the GPIO number is passed to the GpioLcd constructor eg. backlight_pin=Pin(10),
Thanks for letting us know the mistake. updated now.
Leaving SCA and SCL on GP 8/9 as in the diagram gives me an out of range error.
Putting them on pins 0 and 1 allows me to read the location of the LCD as being 39.
The backlight comes on and off but I cannot put text on the screen.
The code above at line 3 seem to assign sda to pin 0 and scl to pin 1,
but the connection diagram shows them connected to gp8 and gp9.
So rewiring them to 0 and 1 seem to be the correct connection.
I am still waiting for my LCD screen to arrive in the mail, so I have not been able to test myself yet.
You might take a look the guide at toms hardware and see if it works for you
https://www.tomshardware.com/how-to/lcd-display-raspberry-pi-pico
Got my LCD here now. Actually it is a 1604 and not a 1602.
But I do get that same out of range error at line 5.
Which I think is because it can not find any i2c devices when trying to scan.
A thread at the official raspberrypi forums suggests that this is a common timing problem with the pico. SOme say they have a bunch of these i2c devices and some work and others not.
I have tried two of these, but no luck. I tried both pin 8/9 and 0/1.
I notice that the pico only delivers 4.73 VDC to the lcd board. If the lcd board need 5V minimun that could be a reason.
It appears you have printed the physical PIN numbers rather than the GP pins. Could explain why I couldn’t get it to work!
Traceback (most recent call last):
File “”, line 5, in
IndexError: list index out of range
in order to use this non I2C in circuitpython I had to change the gpio_lcd.py .
Like this:
import digitalio iso Pin from machine and all the pins similar to
self.rs_pin.direction=digitalio.Direction.OUTPUT
self.rs_pin.value = 0
also utime is not available and I had to use time and sleep
I used sleep(0.01) for all instances.
I also changed
cmd |= self.LCD_FUNCTION_2LINES
into
cmd = self.LCD_FUNCTION_2LINES
because | looks like a keyboard problem. Is it ?
What I don’t understand is
self.hal_write_4bits(nibble >> 4)
what does nibble >> 4 mean/ do?
There is something happening on the display but not the text I’m trying to display.
It would be nice to have a gpio_lcd.py that works with circuitpython.
anyway this guide took me the furthest because I’m using a 1 line lcd display which is 35 years old 🙂
The LCD works on a PI 3B+ with python
I get the Hex address printed on the shell but the LCD is showing only boxes on the top row?
I use a pico WH + Grove 16×2 LCD (White on blue)