Using Standard HD44780 LCDs on LoPy4

Discuss development of drivers for external hardware and components, such as LCD screens, sensors, motor drivers, etc.
Target audience: Users and developers of drivers.
gatorchu
Posts: 15
Joined: Sun Sep 22, 2019 3:50 pm

Using Standard HD44780 LCDs on LoPy4

Post by gatorchu » Fri Sep 27, 2019 4:58 am

Dear friends,

As a very beginner of the Micropython, I'm playing with a Standard HD44780 LCDs mounted with Adafruit i2c/SPI LCD Backpack arduino-i2c-use connected to LoPy4 through the default I2C interface.

Unlike the multiple drivers showed over there (https://github.com/dhylands/python_lcd), I haven't seen any drivers specifically for the Pycom board. I suppose that one can simply modify the driver by using the given I2C address of the backpack. So I try the code below to retrieve the address of the Adafruit backpack, and I was returned nothing.

Code: Select all

>>> from machine import I2C
>>> i2c=I2C()
>>> i2c.scan()
[]
>>>
I quota from the Adafruit "You can set the address by jumpering the A0 A1 and A2 solder jumpers. By default, no jumpers are soldered, giving an address of 0. If you want to have an address of 3 you would solder A0 (bit 0) and A1 (bit 1) for an address of "011" = 3 in binary. Then in the code change:".

My question is most I2C slave address is 98, 63, etc. What does mean for "address of 0"?

Can anyone give any instruction? That will be greatly helpful for me! Thank you in advance.
Last edited by gatorchu on Fri Sep 27, 2019 3:47 pm, edited 1 time in total.

User avatar
Roberthh
Posts: 1642
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Using Standard HD44780 LCDs on Wipy4

Post by Roberthh » Fri Sep 27, 2019 7:24 am

Hello @gatorchu,

I think the documentation of Adafruit is misleading. First, please look at the board, if the SPI jumper is closed. Then SPI has to be used. In any case, the addresses define by A0, A1, A2 are 64 through 67. A0, A1, A3 only change the lower address bits. Still the scan should reveal the proper addresses. So either:
- the connection is wrong, with respectr to wiring or the GPIO pins you used in the code.
- the pull-up resistors are missing. That is unlikely. Adafruit devices have usually the pull-ups installed, and the schematics of the board show them.
- it is configured as SPI device.

And one comment: There is no WiPy4. There is a Wipy, supported here, and WiPy2 and WiPy3, supported by Pycom. The Pycom forum is at https://forum.pycom.io.

gatorchu
Posts: 15
Joined: Sun Sep 22, 2019 3:50 pm

Re: Using Standard HD44780 LCDs on LoPy4

Post by gatorchu » Fri Sep 27, 2019 3:40 pm

Hi @Roberthh,

Thank you so much for your instructive reply!

Now the backpack is responding my i2c.scan().

While a new problem arises, that is each time it responds to me with a different address which is very weird. I have no jumper on A0, A1, and A2. I have two sets of backpack and LCDs. They all behave the same. Could you please give me some clues?

Code: Select all

>>> i2c.scan()
[10, 14, 46, 48, 83, 116, 118]
>>> i2c.scan()
[]
>>> i2c.scan()
[40, 80]
>>> i2c.scan()
[56]
>>> i2c.scan()
[42, 119, 120]
>>> i2c.scan()
[12, 88]
>>>
Last edited by gatorchu on Fri Sep 27, 2019 7:59 pm, edited 1 time in total.

User avatar
Roberthh
Posts: 1642
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Using Standard HD44780 LCDs on LoPy4

Post by Roberthh » Fri Sep 27, 2019 3:53 pm

If that is the only device on the I2C bus, it still looks like a connection problem. Do you power the backpack properly?
How do you set-up I2C? And which Wipy pins do you use for the connection?
And which firmware version do you use? Push Ctrl-B to get the information.

gatorchu
Posts: 15
Joined: Sun Sep 22, 2019 3:50 pm

Re: Using Standard HD44780 LCDs on LoPy4

Post by gatorchu » Fri Sep 27, 2019 6:28 pm

Hi Roborthh,

Thank you so much for your clue! I finally found that it was due to I used the external 5V power supply (as HD44780 required) without sharing the ground with the Pycom board! So each time I query the i2c address, the board returns me a floating number! After I connect the two ground together, the board give me a constant address of 32.

Now I'm facing a new question - which and how the driver should be used?

I read one of your reply in the Pycom Forum (https://forum.pycom.io/topic/4841/1602- ... th-pycom/7) and found that you said "The one for esp8266_i2c works". While I found this driver is for "Implements a HD44780 character LCD connected via PCF8574 on I2C. My backpack is MCP23008 from Adafruit. Thus, my thought is using pyb_i2c_adafruit_lcd.py driver, and replace

Code: Select all

from pyb import I2C
from pyb import delay
to

Code: Select all

import time
from machine import I2C
and corresponding delay() to time.sleep_ms() in the body. Would it be the correct direction? Could you please comment about this?

User avatar
Roberthh
Posts: 1642
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Using Standard HD44780 LCDs on LoPy4

Post by Roberthh » Fri Sep 27, 2019 6:49 pm

Offset 32 was right. The wiring of the adafruit backpack to the LCD is different to the backpack I used. So you would have to change line 13-17 into (hope it works):

Code: Select all

MASK_RS = 0x02
MASK_RW = 0x00 # dummy. RW is not connected and not used
MASK_E = 0x04
SHIFT_BACKLIGHT = 7
SHIFT_DATA = 3
The pyb_i2c_adafruit_lcd.py script needs more changes than you told, since the pyb.I2c methods differ quite a lot from the machine.I2c methods.
One note: the LCD needs 5V. The WiPy1 is definitely NOT 5V tolerant. The ESP32 WiPy2 and WiPy3 are not guaranteed to be 5V tolerant, but in your set-up it should be OK.

gatorchu
Posts: 15
Joined: Sun Sep 22, 2019 3:50 pm

Re: Using Standard HD44780 LCDs on LoPy4

Post by gatorchu » Fri Sep 27, 2019 9:54 pm

@Roberthh Thank you again for your help!

I modified the code based on your instruction.
Part of test code (change to i2c = I2C()):

Code: Select all

def test_main():
    """Test function for verifying basic functionality."""
    print("Running test_main")
    i2c = I2C()
    lcd = I2cLcd(i2c, DEFAULT_I2C_ADDR, 4, 20)      # for LCD 20*4
    lcd.putstr("It Works!\nSecond Line")
    sleep_ms(3000)
    lcd.clear()
    count = 0
The error message finally pointed to "esp8266_i2c_lcd.py", line 34, in __init__"

Code: Select all

ho 0 tail 12 room 4
load:0x4009fa00,len:19208
entry 0x400a05f4
Initializing filesystem as FatFS!
Running test_main
Traceback (most recent call last):
  File "main.py", line 47, in <module>
  File "main.py", line 15, in test_main
  File "esp8266_i2c_lcd.py", line 34, in __init__
OSError: I2C bus error
Pycom MicroPython 1.20.0.rc13 [v1.9.4-94bb382] on 2019-08-22; LoPy4 with ESP32
Type "help()" for more information.
>>>
In the modified esp8266_i2c_lcd.py, line 34 is:

Code: Select all

self.i2c.writeto(self.i2c_addr, bytearray([0]))
Is there anything else that needs to be modified?

Seems like it is not a simple problem, so I buy several PCF8574 backpacks. While before I get them, I still would like to investigate deeper.

User avatar
Roberthh
Posts: 1642
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Using Standard HD44780 LCDs on LoPy4

Post by Roberthh » Sat Sep 28, 2019 6:21 am

You might have to adapt the DEFAULT_I2C_ADDRESS in line 9. Since i2c.scan() returns 32, you have to set it to 32.
In my code line 34 is "sleep_ms(1)", so I do not understand your comment.

gatorchu
Posts: 15
Joined: Sun Sep 22, 2019 3:50 pm

Re: Using Standard HD44780 LCDs on LoPy4

Post by gatorchu » Sat Sep 28, 2019 3:28 pm

Hi Roberthh,

Sorry about my misleading comments!

I added your codes and commented out the original codes (just my personal habits), which made the line number was not matching with yours anymore. Please see the codes below (As you can see, I did modify the DEFAULT_I2C_ADDR = 0x32):

Code: Select all

"""Implements a HD44780 character LCD connected via PCF8574 on I2C.
   This was tested with: https://www.wemos.cc/product/d1-mini.html"""

from lcd_api import LcdApi
from machine import I2C
from time import sleep_ms

# The PCF8574 has a jumper selectable address: 0x20 - 0x27
DEFAULT_I2C_ADDR = 0x32

# Defines shifts or masks for the various LCD line attached to the PCF8574
"""
# Original code
MASK_RS = 0x01
MASK_RW = 0x02
MASK_E = 0x04
SHIFT_BACKLIGHT = 3
SHIFT_DATA = 4
"""
# Specifically for HD44780 character LCD mounted with MCP23008 backpack
MASK_RS = 0x02
MASK_RW = 0x00 # dummy. RW is not connected and not used
MASK_E = 0x04
SHIFT_BACKLIGHT = 7
SHIFT_DATA = 3


class I2cLcd(LcdApi):
    """Implements a HD44780 character LCD connected via PCF8574 on I2C."""

    def __init__(self, i2c, i2c_addr, num_lines, num_columns):
        self.i2c = i2c
        self.i2c_addr = i2c_addr
        self.i2c.writeto(self.i2c_addr, bytearray([0]))
        sleep_ms(20)   # Allow LCD time to powerup
        # Send reset 3 times
        self.hal_write_init_nibble(self.LCD_FUNCTION_RESET)
        sleep_ms(5)    # need to delay at least 4.1 msec
        self.hal_write_init_nibble(self.LCD_FUNCTION_RESET)
        sleep_ms(1)
        self.hal_write_init_nibble(self.LCD_FUNCTION_RESET)
        sleep_ms(1)
        # Put LCD into 4 bit mode
        self.hal_write_init_nibble(self.LCD_FUNCTION)
        sleep_ms(1)
        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)


That makes the line 34 (where the error message pointed to) is:

Code: Select all

self.i2c.writeto(self.i2c_addr, bytearray([0]))

User avatar
Roberthh
Posts: 1642
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Using Standard HD44780 LCDs on LoPy4

Post by Roberthh » Sat Sep 28, 2019 3:31 pm

The address is 32 decimal or 0x20 hex.

Post Reply