cannot make Grove I2C LCD with Pico to work #12003
-
I have spent quit some time getting a Grove 16x2 I2C LCD to work with Pico. example 1.txt |
Beta Was this translation helpful? Give feedback.
Replies: 20 comments 32 replies
-
What display are you using? Does it have a manual contrast adjustment trimpot on the back? Sometimes they're shipped so that all you see is blocks until you set the contrast. What I2C address is printed? Not all 16x2 LCDs use the same hardware. |
Beta Was this translation helpful? Give feedback.
-
I'm using the Grove-16x2 LCD (White on Blue V2.0) <https://www.seeedstudio.com/Grove-16x2-LCD-White-on-Blue.html> I added the datasheet as attachment.
There is no trimpot available.
It has address 0x3E (62 DEC)
[https://media-cdn.seeedstudio.com/media/catalog/product/cache/7f7f32ef807b8c2c2215b49801c56084/h/t/httpsstatics3.seeedstudio.comseeedfile2018-10bazaar969249_front.jpg]<https://www.seeedstudio.com/Grove-16x2-LCD-White-on-Blue.html>
Grove - 16x2 LCD (White on Blue)<https://www.seeedstudio.com/Grove-16x2-LCD-White-on-Blue.html>
Grove - 16 x 2 LCD is a perfect I2C LCD display for Arduino and Raspberry Pi with high contrast and easy deployment.
www.seeedstudio.com
…________________________________
Van: Stewart Russell ***@***.***>
Verzonden: donderdag 13 juli 2023 18:53
Aan: micropython/micropython ***@***.***>
CC: bartvdg ***@***.***>; Author ***@***.***>
Onderwerp: Re: [micropython/micropython] cannot make Grove I2C LCD with Pico to work (Discussion #12003)
What display are you using? Does it have a manual contrast adjustment trimpot on the back? Sometimes they're shipped so that all you see is blocks until you set the contrast.
What I2C address is printed? Not all 16x2 LCDs use the same hardware.
—
Reply to this email directly, view it on GitHub<#12003 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AKSREBHANQRXI52GK43GGKDXQARXTANCNFSM6AAAAAA2JCWWVU>.
You are receiving this because you authored the thread.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
Pasting the contents of example1.txt above
Is this the repo/file you're referring to? |
Beta Was this translation helpful? Give feedback.
-
HD44780 compatible displays have an 80 character memory. If you have a 20x4 display, it displays all characters on screen:
If you have a 16x2 display, you're only seeing a subset of characters (32 of 80).
You could try moving to top left with You could try initing with
Ideally, you should see this:
If you 2nd display line shows a line of 'c's or 'd's, the display maps to a different location in the 80 char memory. |
Beta Was this translation helpful? Give feedback.
-
Have you tried this one? https://github.com/dhylands/python_lcd |
Beta Was this translation helpful? Give feedback.
-
Many thanks Mike to give me so much detailed feedback.
I'm rather new in this and boxed together below code based on your inputs, result is still same. first row only white boxes, second row blank.
My big toe is saying it is contrast setting, but no clue on how to adjust this?
code used to test:
from machine import I2C, Pin
from pico_i2c_lcd import I2cLcd
from time import sleep
i2c = I2C(0, sda=Pin(8), scl=Pin(9), freq=400000)
I2C_ADDR = i2c.scan()[0]
lcd = I2cLcd(i2c, I2C_ADDR, 4, 20)
count = 0
# print a 20 times on LCD row 1
while count < 20:
count += 1
lcd.move_to(0,0)
lcd.putstr("a")
print("a" + str(count)) # print on shell
sleep(0.25)
count = 0
# print b 20 times on LCD row 2
while count < 20:
count += 1
lcd.move_to(0,1)
lcd.putstr("b")
print("b" + str(count)) # print on shell
sleep(0.25)
count = 0
# print c 20 times on LCD row 3
while count < 20:
count += 1
lcd.move_to(0,0)
lcd.putstr("c")
print("c" + str(count)) # print on shell
sleep(0.25)
count = 0
# print d 20 times on LCD row 4
while count < 20:
count += 1
lcd.move_to(0,1)
lcd.putstr("d")
print("d" + str(count)) # print on shell
sleep(0.25)
count = 0
lcd.putstr("x")
print("x" + str(count)) # print on shell
…________________________________
Van: Mike Causer ***@***.***>
Verzonden: vrijdag 14 juli 2023 02:52
Aan: micropython/micropython ***@***.***>
CC: bartvdg ***@***.***>; Author ***@***.***>
Onderwerp: Re: [micropython/micropython] cannot make Grove I2C LCD with Pico to work (Discussion #12003)
HD44780 compatible displays have an 80 character memory.
If you have a 20x4 display, it displays all characters on screen:
1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
1 # # # # # # # # # # # # # # # # # # # #
2 # # # # # # # # # # # # # # # # # # # #
3 # # # # # # # # # # # # # # # # # # # #
4 # # # # # # # # # # # # # # # # # # # #
If you have a 16x2 display, you're only seeing a subset of characters (32 of 80).
1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
1 # # # # # # # # # # # # # # # # . . . .
2 # # # # # # # # # # # # # # # # . . . .
3 . . . . . . . . . . . . . . . . . . . .
4 . . . . . . . . . . . . . . . . . . . .
You could try moving to top left with lcd.move_to(0,0) then lcd.putchar('a') and repeat for other coordinates until you find where your screen's visible portion of the 80 character memory.
putchar() calls move_to() after it's finished putting to try to start you on the second visible line once you exceeded the first, and wrap back to the top again. If there's something wrong with these calculations, it'll not put the cursor at the right spot.
You could try initing with lcd = I2cLcd(i2c, I2C_ADDR, 4, 20) which should disable the put-wrapping-magic.
* Then move to 0,0, put an 'a' 20 times. 4x 'a's should be offscreen.
* Then put 'b' 20x times and it should fill the 2nd line (4x offscreen).
* Then put 'c' 20x times and it should fill the 3rd line (all offscreen).
* Then put 'd' 20x times and it should fill the 4th line (all offscreen).
* Then finally put an 'x' and it should be back in the first 0,0 character.
Ideally, you should see this:
1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
1 x a a a a a a a a a a a a a a a . . . .
2 b b b b b b b b b b b b b b b b . . . .
3 . . . . . . . . . . . . . . . . . . . .
4 . . . . . . . . . . . . . . . . . . . .
If you 2nd display line shows a line of 'c's or 'd's, the display maps to a different location in the 80 char memory.
—
Reply to this email directly, view it on GitHub<#12003 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AKSREBGF7WBU6T7AY3CA2ULXQCJ4TANCNFSM6AAAAAA2JCWWVU>.
You are receiving this because you authored the thread.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
Yes I have tried it but no luck...
…________________________________
Van: Mike Causer ***@***.***>
Verzonden: vrijdag 14 juli 2023 02:54
Aan: micropython/micropython ***@***.***>
CC: bartvdg ***@***.***>; Author ***@***.***>
Onderwerp: Re: [micropython/micropython] cannot make Grove I2C LCD with Pico to work (Discussion #12003)
Have you tried this one? https://github.com/dhylands/python_lcd
—
Reply to this email directly, view it on GitHub<#12003 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AKSREBBEBY23HOUV2C3CD73XQCKFDANCNFSM6AAAAAA2JCWWVU>.
You are receiving this because you authored the thread.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
You can cross-check your setup and coding with this tutorial: https://www.tomshardware.com/how-to/lcd-display-raspberry-pi-pico |
Beta Was this translation helpful? Give feedback.
-
Decimal address: 62 | Hexa address: 0x3e
I have the resistors R9 & R12 mounted on PCB (see pic) the LCD has version V2.0

thanks for the bonus 😉
…________________________________
Van: Mike Causer ***@***.***>
Verzonden: zaterdag 15 juli 2023 05:19
Aan: micropython/micropython ***@***.***>
CC: bartvdg ***@***.***>; Author ***@***.***>
Onderwerp: Re: [micropython/micropython] cannot make Grove I2C LCD with Pico to work (Discussion #12003)
I have one of the Grove RGB 1602 LCDs<https://wiki.seeedstudio.com/Grove-LCD_RGB_Backlight/>. It presents 2x I2C addresses. One for driving the (HD44780 compatible) display, and one for driving the RGB backlight.
I don't have one of your display modules, but I wonder if Seeed used the same chips, but with a single colour backlight.
Can you do an i2c.scan() and let us know what addresses appear.
Also, according to the wiki page<https://wiki.seeedstudio.com/Grove-16x2_LCD_Series/>, early versions were missing I2C pull-ups. What version is your display?
Without a trimpot for controlling contrast, they must be "hard coding" it with resistors on the back of the display.
Bonus:
count = 0
while count < 20:
count += 1
print(i)
Can be rewritten as simply:
for i in range(20):
print(i)
range(5) gives you steps 0,1,2,3,4.
—
Reply to this email directly, view it on GitHub<#12003 (reply in thread)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AKSREBFDD2QUBIP5BVY4S7DXQID4VANCNFSM6AAAAAA2JCWWVU>.
You are receiving this because you authored the thread.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
You may try my rework of the LCD driver, if you like. |
Beta Was this translation helpful? Give feedback.
-
Do you run the display at 3.3V or 5V? The data sheet of the controller allows both voltages, but all of the LCD displays I worked with required 5V supply. |
Beta Was this translation helpful? Give feedback.
-
So the LCD is powered and connected to the controller. I see that the backlight is on. But for that, the contrast is too weak. Did you drive with 3v3 or 5V for this picture? Nevertheless, we should focus now on the communication. So you tried that i2c.scan() returns the address 62 in the list of Addresses on the bus. I would prefer using this a hardcoded value instead of relying on i2c.scan() returning this as first value in the list. I have used the drivers from dhylands with these LCD devices and they worked well. They were designed for a HD44780 controller, but according to the data sheet of your device the command set is the same. The machine_i2c_lcd.py should be the right one. It uses the 4bit mode of the interface. But the Seeed example code does the same. Two difference I see between the Seeed example and machine_i2c_lcd.py:
Edit: The device reset code of the dhylands code is actually teh code for setting 4 bit mode. So both examples work similar. Anyhow it may be that the DL setting is ignored. The data sheet of the JHD1804 device is not consistent. |
Beta Was this translation helpful? Give feedback.
-
Looking at the examples, it seems that from the dhylands code the one for grove displays may match better, which uses the device in 8 bit mode, |
Beta Was this translation helpful? Give feedback.
-
If you have an extra I2C address (0x62, which should show up in a I2C scan)
|
Beta Was this translation helpful? Give feedback.
-
A data sheet describing the interface would be e.g. https://www.orientdisplay.com/wp-content/uploads/2022/08/AIP31068L.pdf. This part is mentioned in the display data sheet mentioned by Seeed. For sending a command byte, one has to transmit [0x80, command]. For sending a data byte, one has to transmit [0x40, data]. That's done for instance by the Seeed C++ sample code. |
Beta Was this translation helpful? Give feedback.
-
You could try the following simplified version of the machine_i2c_lcd.py driver with the changed way of writing to the controller. from lcd_api import LcdApi
from time import sleep_ms
DEFAULT_I2C_ADDR = 0x3e
# Defines shifts or masks for the various LCD line attached to the PCF8574
MASK_RS = 0x01
MASK_RW = 0x02
MASK_E = 0x04
SHIFT_BACKLIGHT = 3
SHIFT_DATA = 4
class I2cLcd(LcdApi):
def __init__(self, i2c, i2c_addr, num_lines, num_columns):
self.i2c = i2c
self.i2c_addr = i2c_addr
self.i2c.hal_write_command(self.i2c_addr, 0)
sleep_ms(50) # Allow LCD time to powerup
LcdApi.__init__(self, num_lines, num_columns)
cmd = self.LCD_FUNCTION
if num_lines > 1:
cmd |= self.LCD_FUNCTION_2LINES
self.hal_write_command(cmd)
def hal_write_command(self, cmd):
"""Writes a command to the LCD."""
self.i2c.writeto(self.i2c_addr, bytearray([0x80, byte]))
if cmd <= 3:
# The home and clear commands require a worst case delay of 4.1 msec
sleep_ms(5)
def hal_write_data(self, data):
"""Write data to the LCD."""
self.i2c.writeto(self.i2c_addr, bytearray([0x40, data])) |
Beta Was this translation helpful? Give feedback.
-
Some progress. At least the commands seem to be accepted. |
Beta Was this translation helpful? Give feedback.
-
Which test code do you run? Any error messages? |
Beta Was this translation helpful? Give feedback.
-
It is hard to help without the same LCD at hand. You should be able to run dhylands machine_i2c_lcd_test.py code, but without the calls to backlight_on() and backlight_off(). You need the lcd_api.py file on the board as well. |
Beta Was this translation helpful? Give feedback.
-
Nice you got it working. |
Beta Was this translation helpful? Give feedback.
I edited the above code to use the 8 bit interface as Robert described it (with the option grove=True). You may try it out again.