LCD keypad shield on WEMOS D1 R32

Hi guys, I'm very new to programming and arduino.

I'm currently doing my project which part of it was to connect a LCD keypad shield to WeMos D1 R32
(which uses ESP 32). I would like to ask some question here.

  1. Does I2C required in this situation? Can I do it without using I2C? what are the difference?

  2. I found out that the code for esp8266 "LiquidCrystal" is not compatible for ESP32, can anyone guide me on coding and also connection between the microcontroller and the LCD.

Thank you very much for your help.

Below attach the component I'm using.

LCD keypad shield : Arduino LCD 1602 Liquid Crystal Display Keypad Shield LCD1602 | Lazada

PS: I'm not sure about the microcontroller as it wan given by my senior. It is written "WeMos D1 R32" on it.

Please guide me thanks.

That keyboard shield does not use i2c.
From the product page:

This LCD Keypad Shield use total of 6-pins to control the LCD display which is pin-4, 5, 6, 7, 8, 9. For LCD Data, it use pin-4, 5, 6, 7, while for the RS and Enable pin, it use pin-8 and 9. The Arduino-LCD Keypad Shield are only required to plug into the Arduino main board and there was no soldering are required such as shown in figure below.

What is the issue with the library?
What Arduino board type are you using?

--- bill

I'm using a WeMos D1 R32. Or is there any more information I can provide?

When I uses the LiquidCrystal on my WeMos D1 R32, it appears to be some error. After some research online, I found out that LiquidCrystal couldn't be used on ESP32.

You are going to have to provide more information.
In the ESP 32 platform I have installed:
https://dl.espressif.com/dl/package_esp32_index.json
Version 1.0.4 which is the latest version.
I don't see a board type called "WeMos D1 R32"

The LiquidCrystal library uses very generic Arduino API functions so it should work on any platform/core/board.
I tried a few boards from the ESP32 platform that I have and the HelloWorld example compiled on all of them.

What platform/core do you have installed and what board type are you using?
If are you are getting a compilation error, you will need to post the compiler output so we can see it.

--- bill

Wemos D1 R32 uses board "ESP32 Dev Module".

The LiquidCrystal HelloWorld compiles for me with no error when using that board and IDE version 1.8.13
Post the compiler output so we can see the error you are getting.


Also, keep mind that the ESP cores use GPIO bit numbers for the digital pin API functions like pinMode(),digitalRead(), digitalWrite()

And because you are using an Uno form factor it expects Arduino pin numbers to be in specific locations.
On your board the physical locations will map to a different number since the core uses GPIO bit numbers and the GPIO bit numbers are not the same as the expected Arduino pin numbers for a given physical location.

The ESP core variants typically handle this by creating a board type with a corresponding pins_arduino.h file that has Dn symbol names to map the expected Arduino pin number for a physical location to an ESP GPIO bit number.

There does not appear to be a true board and variant file to do this mapping for the board you have.
Because of this, you will have to do the Arduino pin to ESP32 GPIO bit number mapping manually.

So you will need to covert the Arduino digital pin numbers used by the LCD shield: 8,9,4,5,6,7
to the corresponding GPIO bit numbers for each physical position for those Arduino pin numbers.
The numbers are printed on the PCB.
i.e. instead of 8 you would use 12

But the first thing it to figure out why the code is getting an error and not compiling.

--- bill

There is a Uno format board called Wemos R1 D1 with an ESP8266
There is a Uno format board called TTGO D1 R32 with an ESP32

The D1 R1 has a specific Variant entry in the ESP8266 core
It would be a good idea (tm) if there was a specific D1 R32 Variant entry in the ESP32 core that assigned a set of D#n numbers for the digital #n pins on the pcb. (like was done with the D1 R1 ESP8266 board)

However, I think that the "Wemos" name was hijacked for the D1 R32 without Wemos's approval.
So current users of the D1 R32 just code the digital pins manually as if it was a bare "ESP32 Dev Module"

Regarding LiquidCrystal. It should work fine on the D1 R32 board if you use the GPIOnn numbers that are printed on the pcb.

David.

smlee0511,
The LiquidCrystal library should work with that board.

I have a hd44780 lcd library called "hd44780".
It has extra features over LiquidCrystal and is faster.
I also include examples that support for that type of LCD keypad shield "out of the box".
However, currently it doesn't have LCD keypad support for that particular esp32 board.
I ordered one of the "WeMos D1 R32" boards today. (looks like I won't get it in until Aug)
Once I get it in, I'll make sure it works with the hd44780 library and a lcd keypad shield.
Then I'll create a proper board type for it that creates the Dn symbols like the esp8266 Wemos D1 R1 to help make things easier and then generate a PR for them.

On a related note, some of those lcd keypads have a bug in the h/w that can create a short if you use backlight control.
See this thread: Warning to users of some vendors LCD keypad shields - Displays - Arduino Forum
The hd4480_pinIO i/o class auto detects this and has a s/w work around to avoid the issue.
The hd44780 library includes a sketch to test for this h/w issue, but...
you won't be able to use the LCDKeypadCheck sketch as it comes.
You will have to edit the pins to match your board.

Once I get the board, and add support for it, it should work out of the box and be able to test the shield for the h/w issue without having to modify the pins in the sketch.

--- bill

For a different project I had to map pin numbers. This is what I came up with:

	constexpr unsigned int LCD_CS = 5;  // 10; 
	constexpr unsigned int LCD_BL = 13; // 9;  
	constexpr unsigned int LCD_RST = 12; // 8;  
	constexpr unsigned int LCD_DC = 14; // 7;  

	constexpr unsigned int TP_CS = 17;   // 4;
	constexpr unsigned int TP_IRQ = 25;  // 3
	constexpr unsigned int TP_BUSY = 27; // 6

	constexpr unsigned int SD_CS = 16;   // 5;

Ignore the variable names, but the D1 R32 pins numbers here match the UNO pin numbers in the comments.

david_prentice:
There is a Uno format board called Wemos R1 D1 with an ESP8266
There is a Uno format board called TTGO D1 R32 with an ESP32

The D1 R1 has a specific Variant entry in the ESP8266 core
It would be a good idea (tm) if there was a specific D1 R32 Variant entry in the ESP32 core that assigned a set of D#n numbers for the digital #n pins on the pcb. (like was done with the D1 R1 ESP8266 board)

The wemos names were : 'WeMos D1 R1" and "WeMos D1 R2"
The R2 board is TERRIBLE. It moves all the Dn symbols over to skip over the TX and RX pins which means that they are compatible with nothing.

For these new uno form factor ESP32 boards, I think using R32 was not a good thing since the number after the R for the WeMos ESP8266 boards was originally a revision number.

Any idea what the Tn symbols in the TT variants in the ESP32 core are used for?
They don't match up with the GPIO numbers printed on the PCB.
I'm assuming that the printed GPIO labels on the PCB for each pin are correct?

I've also seen a similar board with a printed name on it of "ESPDUINO-32"

I'm going to create a board type and corresponding variant to have the Dn symbols like the Wemos (now Lolin) boards in the ESP8266 core. That I'll push to them through a PR.
The question becomes what to call it?
I'd like to use something like "ESPDUINO-32" or "ESP32 UNO 32" or "ESP32 UNO D1 R32"
But I'm concerned about trademarks.
So it may be tough to come up with an intuitive name and yet try to not step on anyone's trademark name.
I'm leaning towards "ESP32 D1 R32", any ideas for something else better?

But before I do this, I'd like to understand what the Tn symbols are for.
Do the "real" TT boards use a different wiring/pin mapping than the D1 R32 boards?

--- bill

Thanks everyone for providing guidance. I believe I made mistake regarding not assigning i/o pins according to WeMos. What I did earlier was just 100% follow guide online according to Arduino. I will give it a try ASAP and update here.

By the way, I have an issue whereby is it possible to connect LCD keypad shield to I2C , as I have seen some post mentioning it is impossible, but I found a guide online here : https://www.instructables.com/id/1602-LCD-Keypad-Shield-Module-With-I2C-Backpack/

If anyone has experience doing so, please provide some guidance or schematic as well as example codes.

Thank you very much.

1 Like

Ok, so I bought one of these boards and have done some testing to get it to work with an LCD shield.
There are multiple issues. s/w issues as well as a h/w issue.
But the TLDR summary is that there is a h/w compatibility between the LCD keypad shield and the ESPDUINO-32 board that requires a small h/w fix to allow it work.
You have to add a pull down on the D8 / GPIO 12 pin or on the hd44780 RS pin (they are the same for this shield).
I used a 10k resistor.

I will be releasing an updated hd44780 library with a few work arounds for issues in the ESP32 core s/w.
This will come out some time in the next week or so.

Full gory details below
--- bill


issues for using a lcd keypad fall into 2 main areas:

  • h/w pin compatibility issue on the "Wemos D1 R32" / "ESPDUINO-32" board itself.
  • s/w issues in the esp32 platform/core

Use of GPIO 12 for D8 is incompatible with LCD keypad shields.
ESP32 GPIO pin 12 is special. If it is high during the boot process, the processor will not boot from flash.
On the ESPDUINO-32 board, GPIO 12 is connected to the D8 position which on the keypad shield is conned the hd44780 RS signal.
The ESP32 has a weak pulldown on GPIO 12 but it isn't strong enough to over come the internal pullup on the LCD RS signal.
To make this work, an additional external pulldown resistor is necessary.
I used a 10k resistor pulldown.
On my shield without this pulldown, the esp32 would crash when reset and could not be uploaded as the autoreset would reset the board which would then crash.

ESP32 core and variants have several s/w issues that creates problems.

The ESPDUINO-32 board cannot use the same Arduino pin numbers as an UNO to reference a specific header pin.
Other platforms such as the esp8266 platform include variants that created Dn symbols to provide pin mappings.
While not fully compatible with Arduino Uno, it does make picking the correct gpio pin number easy as you can use a Dn symbol that matches the uno Arduino pin number.
While very ugly this can be worked around by picking the appropriate GPIO pins that map to the pins used by the LCD keypad shield.

The next version of the hd44780 library will include the appropriate GPIO pin numbers for the ESPDUINO-32 board in all the hd44780_pinIO examples.
While I would prefer to add a new board type to the ESP32 platform, from looking at the issues and pull requests it looks like they have not been too receptive to this in the past.
So for now, the code will default to ESPDUINO-32 GPIO pin numbers for the most common lcd keypad whenever the hd44780_pinIO examples are built for a ESP32 processor.

The ESP32 platform/core has chosen not to implement the analogWrite() function.
This has been an issue for a LONG time (many years) and they do not seem to want to fix this.
This can create problems depending on the LCD library being used. This will cause the hd44780 library using the hd44780_pinIO class to fail to compile.
I'll put in a work around in the next release of the hd44780 library. What this means that the backlight dimming will not work for the ESP32 platform based boards. Backlight control will be limited to on/off.
You can read more about the issue here:

The ESP32 platform/core does not include an actual board type for the ESPDUINO-32
Since there isn't a specific board type for this board, you must pick one.
While you can pick "ESP32 Dev Module" and most code will work, the variant for that board type does include LED_BUILTIN, so any code that uses or depends on the on board led may have issues.
The hd44780 can work with or without a built in LED, but since the ESPDUINO-32 board actually has a built in led,
I would recommend using the "node32s" board instead of the generic development module as this will provide the LED_BUILTIN definition for the built in LED.

--- bill

To resolved the GPIO12 issue, I soldered a resistor to the back of the PCB.
--- bill

ESPDUINO-32-GPIO12hack.jpg

In short, that board is a complete bodge! :cold_sweat:

Not to mention the standard warning at the head of this forum about the "LCD Keypad shield"

Paul__B:
In short, that board is a complete bodge! :cold_sweat:

I wouln't be that harsh. But it does suck that it doesn't work out of the box with an lcd keypad.
The issue is that GPIO12 is special and must be held low during bootup.
If you use GPIO12 to control RS or EN it has issues since the hd44780 control signals are pulled up and will override the weak internal pulldown on GPIO12.

This would be an issue on any ESP32 module/board not just this board.

On this board, GPIO12 is wired up to Uno header pin D8 which connects to RS of the LCD on the keypad shield.
Because of this, it needs a pulldown.

The fix is relatively easy, but is likely a bit above some users skills.

--- bill

bperrybap:
The issue is that GPIO12 is special and must be held low during bootup.

Noted. As are GPIO0, GPIO2 and GPIO15 on the ESP8266 "special".

bperrybap:
If you use GPIO12 to control RS or EN it has issues since the hd44780 control signals are pulled up and will override the weak internal pulldown on GPIO12.

Ah! I hadn't noted that before. This is presumably part of facilitating a 4-bit control mode. :grinning: Nominal 125 μA at 5 V, essentially a 40k pull-up - kinda like the INPUT_PULLUP on the ATmega.

bperrybap:
This would be an issue on any ESP32 module/board not just this board.

Clearly. :sunglasses:

Paul__B:
This is presumably part of facilitating a 4-bit control mode.

Its been a while since I looked but I think the data lines are pulled low vs high.
What allows 4 bit mode control to work without having to strap the unused lower 4 bits is that the data lines are pulled down.
This ensures that function set commands can get the LCD back into 8 bit mode and then into 4 bit mode to always get the host and the LCD back into nibble sync.
In order for that to work, the unconnected D0-D3 pins must read consistently when in 8 bit mode.
There is a very long description of how this works in the hd44780 library in the begin() function.

--- bill

Paul__B:
In short, that board is a complete bodge! :cold_sweat:

Ok, so I've changed my mind on this board.
I'm now down on this board design as well as many of the esp32 boards which use this same design for autoreset.
The reason being is that they have a funky DTR/RTS circuit from the USB to serial chip that is used for autoreset downloading.
Both signals from the USB chip go through a transistor. DTR controls EN, and RTS controls GPIO0/BOOT.
The transistors create an active low output and can only be used to sink the ESP signal pins low.
i.e. DTR and RTS don't directly control EN or GPIO0.
The odd part is that the two transistors are interconnected to ensure that both outputs can't be low at the same time.
i.e. DTR must be high and RTS low to get EN low
and RTS must be high and DTR low to get GPIO0 low.
If RTS and DTR both are high or both low, then neither EN nor GPIO0 will be sunk low so they float back high.

However.....
In order to enter serial bootloader mode, you need both low at the same time so that EN can rise when GPIO0/BOOT is still low.
On paper the circuit doesn't work. However in practice it works on some systems.
The board depends on some built in capacitance to alter the slew rate of the rising EN signal to get it to work.
i.e. EN rises slow enough so when you sink GPIO0 low by setting DTR high and RTS low that EN remains low long enough so that the esp32 sees GPIO0 low when coming out of reset to enter serial bootloader mode.

However... It doesn't always work.
It seems to work all the time on one of my machines but not at all on another machine.
Both have identical OS and Arduino s/w.
But they are different motherboards with different processors (Intel vs AMD) and also different USB chipsets
The USB voltages on the two machines is also bit different.
I don't have a scope but this might be why it isn't working on the one machine.
I can see the timing difference on the logic analyzer to see the issue on the non working machine but it would be nice to see the real raw analog signal to see what is really going on.

Apparently, this auto boot failure issue is a well known issue in the esp32 world.
Many people simply press the "boot" button to get USB serial downloading to work.
The ESP32duino board doesn't have a boot button.
The other popular solution is to add a 10uf cap between EN and GND to slow down the signal rise time to allow USB serial autoreset to work for serial downloading.

What mess.

--- bill

So this is the same circuit as the WeMOS D1 Mini?

Doesn't matter to the 8266?

(Sorry, can't look into it in detail just now! :roll_eyes: )

Paul__B:
So this is the same circuit as the WeMOS D1 Mini?

It is similar but different.
Another thing I noticed is that ESP8266 has both RST and EN whereas the ESP32 only has EN.
The ESp8266 boards use RST to reset the board.
The espduino-32 board I have is feeding in 4.1 volts into the EN and GPIO0/BOOT pins. :astonished:
The two transistors are J3Y and the signals that feed it are from a CH430C USB to serial chip running at 5V with 5V logic signals.
So that is likely causing the collector to float up to 4.1 volts as the logic signals connected to the base and emitter are at 5V.

But the esp32 "mini" style board uses a different design and has 3.3v on the EN and BOOT pins.

There are so many versions of these boards and some if not all of them have issues.

--- bill