LCD1602 i2c waveshare display - not working

Hi, I can’t get the LCD1602 i2c Waveshare (blue background version) to work, even though it is all connected and started up.

Note - I do have a SIM7600X 4G HAT board on top of Raspberry Pi 4b and am running the display from the pass-through pins on the 7600 4G HAT. As far as I can tell the pins i am using are free (not used by the 7600 4G HAT.I checked GPIO PIN use by Hat in 4G and GPS HAT For Raspberry Pi - Waveshare SIM7600X - Tutorial Australia

So with LCD1602 - it is all wired up. LCD is lit up (blue background with one row of squares along the top). So it waiting and ready it seems.

i2c enable and identified as address 3e. Plugged in and unplugged to confirm. Yes.

smbus2 installed, i2c tools installed, libi2c-dev installed,

Checked all the wiring. SCL >SCL, SDA>SDA, GND>GRD, VCC>5V . All correct.

Even tried swapping to another LCD1602 i2c screen - which incidentally has the same 3e address and same problems. so no apparent issues with the screen hardware.

I downloaded various libraries and code and put them in the same folder and tried them with no success.

Tried Waveshare library and code - got lots of errors in the module code. Not sure what the problem was there.(see below)

I did change the i2c address in the waveshare LCD1602.py code to;

LCD_ADDRESS = (0x3e >> 1) # LCD I2C address

So that should not be an issue.

####

Traceback (most recent call last):
File “/home/paul/Downloads/LCD1602_I2C_Module_Demo/Raspberry/python/examples/Character_display.py”, line 7, in
lcd = LCD1602.LCD1602(16, 2)
File “/home/paul/Downloads/LCD1602_I2C_Module_Demo/Raspberry/python/examples/LCD1602.py”, line 55, in init
self.begin(self._row,self._col)
File “/home/paul/Downloads/LCD1602_I2C_Module_Demo/Raspberry/python/examples/LCD1602.py”, line 145, in begin
self.command(LCD_FUNCTIONSET | self._showfunction)
File “/home/paul/Downloads/LCD1602_I2C_Module_Demo/Raspberry/python/examples/LCD1602.py”, line 60, in command
I2C.write_byte_data(LCD_ADDRESS,0x80,cmd)
OSError: [Errno 121] Remote I/O error

######

Tried Toptechboy.com tutorial. Demo lcdDisplay.py code runs with library LCD1602.py in same folder, but shows nothing in the window when code runs in geany then ‘Code 0’. So says it ran and completed the code no errors, but no display on LCD screen.

I also tried: sterlingbeason/LCD-1602-I2C on GitHUB. same result. Code ran with “(program exited with code: 0)” so code completed no errors, but no display on the LCD.

I can see the squares, so the contrast is Ok to see I believe. this version of the screen does not have a screw on the back for contrast adjustment. i believe it is adjustable using coding however.

When I checked the i2c with “lsmod | grep i2c” was active in terminal i got;

i2c_brcmstb 16384 0
i2c_bcm2835 16384 0
i2c_dev 20480 0

I am not sure what the top one means. the second one seems to be the LCD driver??

If anyone can shed some light on why I cannot get this ‘apparently simple’ LCD to work,

it would be hugely appreciated.

cheers

Paul

1 Like

Hi Paul

I too have a Waveshare 1602 display.that refused to work with the Waveshare library. Displayed the “Waveshare” message but that is all. I was using an Arduino but could be a similar problem.
After playing around for an appreciable time i Gave up and put aside.
Sometime later someone suggested I use a DFRobot library. I have not completely checked it yet but last time I played around it seemed to be OK. I intend to get back to it very soon but I tink the library change did the trick.
Cheers and hope this helps. Bob

1 Like

Thanks Bob,

Good to know I’m not alone with the problem. I will have a look at DF Robot LCD library. Let me know if you have any breakthroughs.

Cheers Paul

1 Like

Hi Pau
I haven’t had a play for a while.
Any “breakthroughs” will be with Arduino UNO R3. I don’t know what the differences are with RPi but there must be some similarities. After all the end result is the same.
Cheers Bob

1 Like

Thanks Bob,
Arduino setup from what I have read is quite different to Raspberry Pi, unfortunately.
Though I’m sure others using Arduino would be grateful to know if you succeed.
Cheers Paul

1 Like

Hi Paul
I don’t suppose that it would be the Arduino 5V logic vs RPi 3.3V logic would it. I have not checked if the display tolerates 3.3V or not as I had no need to.
Cheers Bob.

At this stage I believe the display is all good using the DFRobot library.

Just had a quick look at what I think is your display. You have not advised your exact display but I think it is the same as mine.
It will apparently handle 3.3V or 5V.
I note you are connecting Vcc to 5V. I don’t know but maybe if your I2C logic is 3.3V you may have to connect Vcc to 3.3V also. Might be worth a try.

1 Like

Hey there, @Paul264093,

Very few of these are all that ‘simple’, at best they can seem simple.

I take it your using 0x3e because it’s what came up during an i2c scan? Were there any other addresses on the bus?

I ask because the specific I/O error you’re getting is caused by the device not receiving an Acknowledgement from its command. If no Acknowledgement is received, the whole code will crash on a Pi.

I’m wondering then if the later two tutorials are actually the bigger error, if they’re sending the commands to the correct address, the hardware is acknowledging them, but the commands are meaningless to the slave.

Hi Jane, Thanks for your message. Yes, 3e was the only i2c address showing. To double check I unplugged the LCD1602 and then there was no i2c addresses. So Im sure that is the address.

I am thinking of going back to the waveshare LCD1602.py library code and running it again, then trying to solve the code errors.

I am wondering if the LCD1602.py needs to be put into the ‘lib folder’s. Perhaps it is looking for it in the wrong location?

I would have expected it to find LCD1602.py in the same folder however. The demo code from waveshare Character_display.py starts with:

import sys

sys .path.append(‘../lib/‘)

Code reference from:

Page

http://www.waveshare.com/wiki/LCD1602_I2C_Module\_(Blue)

(Python) File download:

https://files.waveshare.com/wiki/LCD1702-I2C-Module/LCD1602_I2C_Module_Demo.zip

I feel I may have tried this, and also tried removing that line of code ( to lib)but will test again to be sure.

Any other suggestions to try are very welcome.

Regards Paul

1 Like

Hey there, @Paul264093,

I mean, that code is certainly a method of importing a library. It does work, otherwise you’d just get an error about no library existing, but it’s really unclean.

I am simple lady, I like my code to start with a main.py at the bottom of the tree and my libraries in a directory called lib so its a nice clean:

from lib import x

Also worth trying it without the 4G HAT just in case.

I’ll try this myself with the waveshare code and see if I can’t get any results. For troubleshooting purposes, what OS are you using, Trixie or Bookworm?

Hi Jane,

I took break from the LCD display and tested my i2c connections on two different OLED displays.

I do realise they use different systems to display, but both the OLED displays were simple to use and worked perfectly. The Oled display however is not as clean and nice looking as the LCD would be .

At least I have confirmed that the i2c connections work just fine, so the problems with the LCD screen is something else.

OK, I think I have solved the problem.

In the waveshare LCD1602.py code line 7 the address is defined as

LCD_ADDRESS = (0x7c>>1)

What this does is effectively change the 0x7c to 0x3e;

Explanation: Breakdown of the Code

  • 0x7c: This is a hexadecimal number. In decimal, it equals 124.

  • >> 1: This is a bitwise right shift operation. It shifts the bits of the number to the right by one position. This effectively divides the number by 2.

Result of the Operation

When you perform the operation:

  • 0x7c (124 in decimal) >> 1 results in 0x3e (62 in decimal)

______

Why Waveshare wrote it like this I do not know.

I made the mistake of changing their code from

LCD_ADDRESS = (0x7c>>1)

to

LCD_ADDRESS = (0x3e>>1)

because my i2c address is 3e. I didn’t not realise they had added the >> had shifted the address.

In Summary:

If I leave as LCD_ADDRESS = (0x7c>>1) it changes the address to 3e and it works.

If I change the address to LCD_ADDRESS = (0x3e) it works.

The whole problem was the way the Waveshare Code shifted the address in LCD1602.py, which seems to have no particular reason and tricked me.

1 Like

Hi Paul

And only WavwShare would know. I will recheck my original problem although the cause will be different I think.

My set up would only display anything within " ". Anything outside these quote marks finished up gibberish. It would not print say the result of an ADC read as a number. I even tried the ASCII codes with no joy. The DFRobot library works fine.

This is the only WaveShare device I have. I do use a couple of others but these are the bare 1602 displays with the small piggy back I2C device mounted on the back. These work fine also.
Cheers Bob

1 Like

While its good to work out why it did not work and fix it…

Part of the challenge I have seen is what people call the “address” for I2C
To be honest the right shift is a little weird.
From memory, the address is 7 bits (or commonly 7 bits). BUT when used in a packet the LSB of the address “byte” is used to flag read or write.
But the term “address byte” as I just used it would be wrong; as its 7 bit address, followed by 1 bit for the R/W flag.
So that would mean addresses would be end at 7F, so a left shift would then make room for the R/W bit, in the LSB of that 8 bit group.

What would be interesting is what a stock I2C scanner finds for that device. I can only assume waveshare does a right shift to allow a simpler application in the packets when it needs to send to the device; but if the address is in fact 0x7C then the right shift would loose the addresses right most bit. On the other hand if the address was reported as 0x7C and the LSB is in fact the R/W bit, then the right shift would be showing the “correct” address.

1 Like