1602 LCD Keypad Shield Module With I2C Backpack

26,496

19

62

Introduction: 1602 LCD Keypad Shield Module With I2C Backpack

About: I am a retired professional engineer, now farmer. Taking an interest in all things technological and in building devices useful on the farm.

As part of a larger project, I wanted to have an LCD display and a keypad for navigation of some simple menus. I will be using a lot of the I/O ports on the Arduino for other jobs, so I wanted an I2C interface for the LCD. So I bought some hardware, consisting of a 1602 LCD Keypad shield module from DFRobot and an anonymous I2C serial module for LCDs. I want to use these with an Arduino Nano.
Then I found there are some challenges to make these components work together - but it is possible. So I want to share my experience and maybe help some others.

This photo is of the working breadboard, which can display messages on the LCD and identify key presses. The LCD is controlled through the I2C interface, including the LCD backlight. The key presses are received by the Arduino on pin A0 (it can be any of the analogue pins, except for A4 and A5 which are tied up for the I2C interface).

Step 1: Parts Description - LCD Keypad Shield Module

The LCD Keypad shield module consists of a commonly used 1602 LCD mounted on top of a circuit board that holds the keys, and which takes a subset of the LCD connections and makes them available to the header pins on the underside of the circuit board. I understand this board is intended to be mounted on top of an Arduino Uno or similar and provides the right pin layout for it to work in that environment. I bought this module on Ebay from a vendor in China. The header pins on the lower (keypad) side of the board are mostly labelled but the pins on the upper side, which is the LCD interface, are not labelled. However the pins on the LCD itself are labelled.

Step 2: Parts Description - I2C Serial Module

The serial module has the usual 4-pin header for I2C, and a set of unlabelled header pins which I understand are intended to plug directly into the underside of the LCD module. By studying the labels on the LCD, I was able to identify the functions of the pins on the serial module.

This module is based on the IC PCF8574T which terminates the I2C protocol, has 3 pins for address control (20 to 27) and has 8 digital input/output pins P0 to P7. According to the data sheet of the PCF8574T, each I/O pin has a FET to pull it to ground for the LOW state, and can sink at least 20ma. In the High state, it has a transient active pull-up and then a continuing pull-up current of about 0.1 mA.

On this module, all of the digital I/O pins, except for P3, are simply brought out to header pins (on the right in the photo). In the case of P3, it is connected to the base of a transistor (visible in the photo at the top right area just under the label "LED"). The emitter of that transistor is connected to Vss (ground) and the collector is connected to header pin 16, where it can be used to control the LCD backlight. Because of the transistor, the logic state is reversed relative to that assumed in the software library. That is, the LCD backlight is turned ON when the P3 pin is Low, and OFF when the P3 pin is High.

The label on the transistor says L6 which according to my research probably makes it a MMBC1623L6 which has a minimum current gain of 200. With 0.1 mA of base current, it should be able to maintain a LOW condition at its collector (module Pin 16) with at least 20mA collector current.

In addition this module has a 10K potentiometer connected between +5 and Ground, whose variable lead is brought out to pin 3 (third from the bottom in the photo). When connected directly to the LCD, this pot will control the contrast of the LCD. However, that function is provided by a separate similar pot on the LCD shield, so this pot on the serial module has no function.

I was unable to find any connection to the INT pin of the PCF8574T.

UPDATE 22 August 2019

As mentioned above, the PCF8574 has 3 address control pins. These appear to be brought out to pads on the backpack board where they are labelled A0, A1 and A2. They can be seen in the photo. I have not tested this, but it seems almost certain that by bridging one or more of these pins to the adjacent pads, the I2C address can be controlled over the range from 20 to 27. Furthermore, there is a second almost identical device, the PCF8574A which has identical functionality to the PCF8574 but covers the address range from 0x38 to 0x3F.

The address your device actually uses can be checked with an I2CScanner. There are several simple I2C scanners available from various sources. This one at https://github.com/farmerkeith/I2CScanner also identifies some of the devices found.

Step 3: Connections

Thanks to ChaitanyaM17 who provided the Fritzing diagram which depicts the connections, described below.

Power:

The LCD module has a pin on the lower side labelled "5.0V". To the right, adjacent to that are two unlabelled pins which are both ground.

Holding the serial module with the I2C interface at the left hand end, there are 16 pins at the lower edge. The first of these is ground, and the second of these is +5v. Another option is to use the lower two pins on the I2C interface for power, but I found it more convenient to use the pins as described above.

I2C interface. On the serial module, the top pin is SCL (clock) and it goes to the Arduino A5. The second pin down is SDA (data) and it goes to the Arduino A4.

LCD print interface. There are 6 connections between the serial module and the LCD Keypad shield, all of them between pins with no labels. I will identify them on the LCD module by counting from Right to Left, with the first pin as 1. There are 2 blocks of 8, so they go from 1 to 16. I identify them on the I2C serial module by counting from Left to Right, there are also 16 of these. In addition I give each wire a label, which is the equivalent pin on the Arduino that is normally associated with that function, in the case of a direct connection without the serial module.

So the 6 data connections are:

Arduino equivalent // Serial module pin // LCD Keypad module pin

D4 // 11 // 5
D5 // 12 // 6
D6 // 13 // 7
D7 // 14 // 8
D8 // 4 // 9
D9 // 6 // 10

LCD backlight control: This uses one more connection:

Arduino equivalent // Serial module pin // LCD Keypad module pin

D10 //16 // 11

Keypad interface: This uses a single wire from the LCD module pin on the lower side labelled "A0", to pin A0 on the Arduino. At least that was pretty easy!

Step 4: Making the RST Key Usable Similar to the Other 5 Keys

The RST can be connected directly to the RESTART input of the Arduino Nano.

However if you want the RST key to be usable in the software for other things, this can be done by connecting a 15K resistor between the RST pin and the A0 pin on the lower side of the LCD keypad shield.

This works as follows: There is a 2K resistor between +5V and the Right key. Then a chain of progressively larger resistors for each of the other keys (330R to the UP key, 620R to the DOWN key, 1K to the LEFT key, and 3K3 to the SELECT key. All the keys (including the RST key) connect to ground. When connected to a 10 bit A/D converter (as for Arduino Nano A0) they deliver approximately the following values:

Right = 0; Up = 100; Down = 260; Left = 410; Select = 640.

With the 15 k resistor to RST, it delivers about 850.

The software will use values around the mid points between these values to decide which key has been pressed.

Step 5: Software

Useful software is of course an exercise for the reader. However to get you started, you can have a look at my test software. I used the NewLiquidCrystal library, which contains support for the I2C interface. It all just worked, once I have the libraries correctly installed.

The main point was to reverse the polarity of the Backlight OFF and ON commands (due to the transistor on the I2C module as explained in the Parts Description section).

UPDATE 22 August 2019

If you have problems with the LCD display not working, please check the I2C address of your serial backpack using an I2C scanner. A suitable scanner is attached. Then if necessary adjust the first parameter in the statement

LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7);

Step 6: Review and Discussion

As you can see I got the main functions working.

My next intention is to put this into a project box as part of another project. However after setting out on this path I learned that there is another difficulty that I had not anticipated.

The difficulty is that this LCD Keypad module is not set up to be installed in a box. Any sort of box. The buttons of the 6 keys are well below the level of the LCD screen, so that if the module is mounted in a box (eg in the lid) with the top of the LCD circuit board flush with the underside of the lid, the tops of the keys are about 7mm below the top of the lid.

Possible solutions are:

a) Put up with it. Drill access holes in the lid and use a tool (eg a cut down knitting needle of suitable diameter) to press the buttons.

b) Remove the LCD from the module circuit board and perform surgery on the keypad so that the two components can be fixed to the lid of the project box independently (I think there still may be a problem with the buttons being too short)

c) remove the existing buttons and replace them with taller buttons. The new buttons have to be about 13 mm high so that they can be operated through the lid of the project box). Replacement button switches are readily available in a range of heights, including 13mm.

d) discard the LCD keypad shield module and use separate LCD and keypad units (ie start over). There is a wide range of keypad units available, however I have not seen one with the same 6-key layout as on this module (ie Select, Left, Up, Down, Right, Restart). It may not be a big issue, but one of the reasons I started off with this module was that I thought this key layout was what I wanted.

I am planning to go with solution c) above, and see how I go.

Another snippet of information that may be of interest:

With the backlight ON, the current consumption of this project is:
Arduino Nano 21.5 ma; Serial module 3.6 ma; LCD module 27.5 mA; Total 52 mA.

With the backlight OFF, the current consumption of this project is:
Arduino Nano 21.5 ma; Serial module 4.6 ma; LCD module 9.8 mA; Total 36 mA.

5 People Made This Project!

Recommendations

  • Laser Challenge

    Laser Challenge
  • Unusual Uses Contest

    Unusual Uses Contest
  • Edible Art Challenge

    Edible Art Challenge

62 Comments

0
WillJN
WillJN

Question 2 months ago

Hello and thanks farmerkeith,

Thanks for taking the time to figure this out and posting it. I found it easy to follow and easy to build, although I added a 4 channel I2C logic level converter, in order to use it with an ESP32.

I too am using this LCD Keypad shield as part of a larger project. This will display setup instructions and calibration settings on a group of remote sensing devices.

I do have a problem/question that I hope you can help me with.

Since the Arduino Nano you are using has a 10 bit A/D converter, the range is 0 to 1023. It delivers "approximately the following values: Right = 0; Up = 100; Down = 260; Left = 410; Select = 640."

I haven't tried my LCD w/ Keypad shield on an Arduino, maybe mine is different from yours, but I am confused with the results I'm getting when compared with yours. The "Select = 640", which is well below the maximum of 1023, is so far below, that you have added a 15k resistor to the RST and inserted it at "about 850", still well below the 1023.

The ESP32 has a 12 bit A/D converter so my range is 0 to 4095. I loaded the LCD_I2C.ino file and made a few changes to adapt it to the ESP. The buttons for the ESP software ended up being Right < 50; Up < 850; Down < 1970; Left < 3180; Select < 4100. That last button, "Select", is the source of my confusion and my problem. It outputs a constant 4095, the maximum. The software interpets this as a constant pressing of the "Select" button and displays accordingly. There is no room for the RST button. It's as if the manufacturer left out the resistor to the "Select" key.

I need the space, the extra room, to add the RST and be able to add to the software an instruction to print a "" if the valve > 4000 so that the screen will be clear until a button is pressed.

Based on your knowledge of this module, can you make any recommendations?

Thanks again for your effort.

0
farmerkeith
farmerkeith

Answer 2 months ago

Hi WillJN,
I think your problem is due to the mixing of 5V for the LCD and 3V3 for the ESP32 - although I am a bit confused about your description of the SEL key.
When no key is pressed, you should get 4095.
When the SEL key is pressed it will also give 4095, because the division of 5 volts across the resistor chain delivers a voltage to A0 in excess of 3V3.
To fix this, the best solution would be to increase the 2K from 5V to Right to a higher value. However this requires de-soldering the provided resistor and replacing it with a higher value.
An easier solution (physically) is to install a voltage divider from A0 of the LCD keypad module to A0 of your ESP32. I have not done the resistor design for this. I suggest you make a little spreadsheet to calculate the results, taking into account the values in the resistor chain on the module, the input impedance of the ESP32 ADC, and the voltage divider values.
Please let me know how you get on.
Keith

0
WillJN
WillJN

Reply 7 weeks ago

Hello again and thanks for the quick reply Keith,

I feel really dumb and am ashamed to admit it here, but in my haste, I made a of big mistake and sent the analog signal through the logic level converter.

What fooled me was that it was mostly working. It turns out the bi-directional logic level converter was not a strictly a 5 to 3.3Vdc converter, it would work in the range of 1.65 - 5.5Vdc on the high side, to 1.2 - 3.6Vdc on the low side. This explained why I was getting the readings that I reported.

Per your suggestion, I started out with a couple resistors, 2k and 3.9K ohm, and put the analog signal through a voltage divider. Now I got numbers that made more sense, Right < 50; Up < 350; Down < 900; Left < 1450; Select < 2000. The maximum was 2587. I checked the input voltage from the usb line, and it was low. I put together a 5Vdc power supply, changed one of the resistors...

I have "played" with this awhile now and learned a lot from my mistake and your instruction. Lessons I'm sure I won't soon forget.

Thanks again,
WillJN


0
AkmalF7
AkmalF7

Question 10 months ago

Hello sir,
I really appreciate your work

but i got some problem

the lcd just a blink and not show anything

0
farmerkeith
farmerkeith

Answer 10 months ago

Hello AkmalF7,
My first guess is that it might be backlight or contrast problems.
Is the backlight coming on? You will not see anything with it off.
And then, have you tried adjusting the contrast setting? This is the main cause of not seeing the characters.
Carefully check all the connections.
If still no success, install in I2C scanner and make sure you have the right address.
Please ask again if you still have problems.
Keith

0
dhanson64
dhanson64

1 year ago on Step 3

Great write up, helped me in my project. Thanks

0
moserroger
moserroger

2 years ago

Hello

This is a very nice input. Thank you

Unfortunately I get the "Error compiling for board Arduino Nano" error. Same for Uno.

I cannot make sense out of the error message:

Thank you

moses

Arduino: 1.8.10 (Windows 10), Board: "Arduino Nano, ATmega328P (Old Bootloader)"

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x0 pc=0x7855fb]

goroutine 1 [running]:
github.com/arduino/arduino-cli/legacy/builder.ResolveLibrary(0x11cba5a0, 0x11ef206a, 0x5, 0x11ef206a)
/home/jenkins/workspace/arduino-builder-all-cross-cli-inception/src/github.com/arduino/arduino-cli/legacy/builder/resolve_library.go:64 +0x14b
github.com/arduino/arduino-cli/legacy/builder.findIncludesUntilDone(0x11cba5a0, 0x11f0b580, 0x88ed00, 0x11da26f0, 0x11f4bd58, 0x11f58400, 0x0)
/home/jenkins/workspace/arduino-builder-all-cross-cli-inception/src/github.com/arduino/arduino-cli/legacy/builder/container_find_includes.go:358 +0x3b6
github.com/arduino/arduino-cli/legacy/builder.(*ContainerFindIncludes).Run(0xdebc68, 0x11cba5a0, 0xdebc68, 0x0)
/home/jenkins/workspace/arduino-builder-all-cross-cli-inception/src/github.com/arduino/arduino-cli/legacy/builder/container_find_includes.go:152 +0x3e5
github.com/arduino/arduino-cli/legacy/builder.runCommands(0x11cba5a0, 0x11c5be1c, 0x20, 0x20, 0x409a01, 0x7fff, 0x0)
/home/jenkins/workspace/arduino-builder-all-cross-cli-inception/src/github.com/arduino/arduino-cli/legacy/builder/builder.go:210 +0xbd
github.com/arduino/arduino-cli/legacy/builder.(*Builder).Run(0x11c63f40, 0x11cba5a0, 0xdebbb4, 0x11c06c98)
/home/jenkins/workspace/arduino-builder-all-cross-cli-inception/src/github.com/arduino/arduino-cli/legacy/builder/builder.go:117 +0xb9c
github.com/arduino/arduino-cli/legacy/builder.RunBuilder(...)
/home/jenkins/workspace/arduino-builder-all-cross-cli-inception/src/github.com/arduino/arduino-cli/legacy/builder/builder.go:226
main.main()
/home/jenkins/workspace/arduino-builder-all-cross-cli-inception/src/github.com/arduino/arduino-builder/main.go:398 +0x6d2
C:\Program Files (x86)\Arduino\arduino-builder returned 2
Error compiling for board Arduino Nano.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

0
farmerkeith
farmerkeith

Reply 2 years ago

Good morning moserroger,
The reason for the problem is not immediately obvious, but we can find it with a methodical approach.
The first thing is to make sure you can compile some of the standard Arduino sketches, such as the "blink" sketch. Can you do that?
Regards,
Keith

0
moserroger
moserroger

Reply 2 years ago

Hi farmerkeith
Thank you for the reply.
Yes, normally there isn't any problem. I have already compiled many sketches and it works.
Cheers,
Roger

0
farmerkeith
farmerkeith

Reply 1 year ago

Hi roger, Sorry about my slow reply. I have been overloaded.
I think the next steps are a) download the software again to make sure there is no transmission error and you are using the original software from the project. If it will still not compile, then
b) comment out the entire loop() procedure (but not the loop() itself). That is, out a new line with just /* following the loop() line (line 34) and another one with just */ before the closing brace of the loop() block (line 96).
If that compiles, then you can progressively restore function calls or blocks of code until you find the one that is the problem.
If that will not compile, then you need to remove more pieces of code until you find the one that is the problem.
I hope this helps. Please let me know how you get on.
Keith

0
clemenlg
clemenlg

3 years ago

Hi,

I've the same issue than other people, I can't power on the backlight, and I can't see nothing in the display. Keypad works perfectly, because I can see it in the serial.

I simplified the code for testing.

I use arduino nano and use the ChaitanyaM17 connection diagram.

Can you help me?

Regards

#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7); // 0x27 is the I2C bus address for an unmodified backpack

int readkey;

void setup() {
Serial.begin(9600);
lcd.begin(16, 2);
lcd.setBacklightPin(3,POSITIVE);
lcd.setBacklight(LOW);
lcd.clear();
lcd.home() ;
lcd.print("LCD & serial backpack");
}

void loop() {
lcd.setBacklight(LOW);
readkey=analogRead(0);
lcd.setCursor(0, 1);
lcd.print(readkey);
Serial.println(readkey);
}

IMG_20180711_193630.jpg
0
farmerkeith
farmerkeith

Reply 3 years ago

Hi clemenlg,

Your wiring in the photo looks correct to me, so it is not obvious what might be wrong.

Do you have the exact same modules that are specified in the Instructable? There are several different ones on the market.

If the backlight does not come on, you will not be able to see the characters in the display. So that is the first thing you need to get working.

I have the following suggestion. In the setup() section, after

lcd.setBacklight(LOW);

I suggest you add:

delay(1000);

lcd.setBacklight(HIGH);

delay(1000);

lcd.setBacklight(LOW);

And see if the backligh comes on briefly. That will indicate that the polarity is back to front.

Good luck. Please let us know if that is the problem.

Keith

0
clemenlg
clemenlg

Reply 2 years ago

Hi farmerkeith,
I try your code, but the result is the same.
I bought another keypad shield, because I didn't know if the problem was the lcd (that's why I took so long to try it), and the same result.
Buttons work perfect, the problem is the LCD (I can't see nothing).
In my LCD Keypad Shield I can read "D1 ROBOT" (not "DF ROBOT")
Regards

0
farmerkeith
farmerkeith

Reply 2 years ago

Hi clemenig, I take it that when you say "the same result", you mean that the backlight does not flash briefly at startup, when you have put the extra lines into setup?
It is not possible at the moment for me to check on my own hardware at the moment, because I am away from it, but I will look when I can in a few days.
In order to see characters on the LCD screen, it is necessary to have the backlight working. The wire is the yellow one in your photo. You could try putting your multimeter on it to see if there is a 1-second pulse when the Nano starts up. If there is, the problem must be in the LCD end. If there is not, the problem is in the serial backpack or the software.
Good luck, I will get back to you when I can look at my own hardware.
Keith

0
clemenlg
clemenlg

Reply 2 years ago

I recently broke my multimeter...
I can not see any of the characters (I should see these characters with an external light).
I tried with another LCD (and keypad) with the same result, then, I think the problem isn't the hardware.
Regards

0
farmerkeith
farmerkeith

Reply 2 years ago

Hello clemenlg, I think you will need a multimeter to make much progress.
Please have a look at the reply I just sent to JohnSmith-Workshop in the adjacent message. I hope it will help you as well.
Good luck,
Keith

0
clemenlg
clemenlg

Reply 2 years ago

Hello @farmerkeith,
Sorry for the delay, I was out of home.
If I try to work without I2C, connecting directly to Arduino Uno (or Mega), it works (a sample code), then, LCD & keypad works.
Connections are the same that can see in the post picture.
Measured with multimeter:

VSS->0v
VDD->4.6v
V0->0.84v
My code:
#include
#include
#include
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7); // 0x27 is the I2C bus address for an unmodified backpack

int readkey;

void setup() {
Serial.begin(9600);
Serial.println("Primera");
lcd.begin(16, 2);
lcd.setBacklightPin(3,POSITIVE);
lcd.setBacklight(LOW);
delay(1000);
lcd.setBacklight(HIGH);
delay(1000);
lcd.setBacklight(LOW);
lcd.clear();
lcd.home() ;
lcd.print("LCD & serial backpack");
}

void loop() {
lcd.setBacklight(LOW);
readkey=analogRead(0);
lcd.setCursor(0, 1); // go to 1st char of line 2
delay(1000);
lcd.print(readkey);
Serial.println(readkey);
}
Example code to work without I2C: here.

IMG_20190821_120952.jpg
0
farmerkeith
farmerkeith

Reply 2 years ago

Hi clemenig,
Thank you for posting your code. The answer may be there.
The first 3 lines of your code (under the heading My code) say:
#include
#include
#include

They should be:
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
Without these 3 lines as shown, the I2C will not work. Please try putting them in.
Regards,
Keith

0
clemenlg
clemenlg

Reply 2 years ago

Hello farmerkeith,
I tried some things, but I can't show characters, neither power on the display.
If I try to disconnect same wire that Sara_6, backlight powers on, but nothing appears in the display.
I noticed that my I2C wiring is different that Col68, but my wiring is the same that you put in the instructable.
You can see in the photos my wiring, but i checked it several times, and it's the same.
Regards

Edit: I used i2c_scanner to check my I2C bus address, and it was 0X3F, not 0x27 (as your tutorial). With this address, all works perfectly.
If someone have the same problem as my, please check your module address.
farmerkeith, maybe it would be interesant post it into the instructable.
Thanks for all.

IMG_20190822_090242.jpgIMG_20190822_090927.jpg
0
farmerkeith
farmerkeith

Reply 2 years ago

Hi clemenig, Well done for finding the reason for this problem.
I have updated the Instructable with information about the various addresses and an I2C scanner. Please let me know if you think it should be made clearer.
Thank you for the feedback.
Keith