Introduction: 1602 LCD Keypad Shield Module With I2C Backpack

Picture of 1602 LCD Keypad Shield Module With I2C Backpack

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

Picture of 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

Picture of 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.

Step 3: Connections

Picture of Connections

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


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).

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.


Col68 made it! (author)2017-10-12

Hello from France very dear Farmerkeith, thank you very much for your superb site very instructive to use microcontrollers,

I am a beginner and thanks to you I succeeded. As I make cheese at home I need to make a thermostat for temperature and humidity with possibilities to set the temperature or humidity values,

the road is long I hope to succeed someday, desolate for the errors I use a translator, I respect you and I wish you happiness, cordially.

farmerkeith (author)Col682017-10-12

Hello Col68, I am very pleased that my instructable has helped you, and I will be happy to help you with your next steps if you want. Can you share with me what temperature and humidity sensor or sensors you intend to use?

Col68 (author)farmerkeith2017-10-18

Hello Farmerkeith, I wanted to ask you a question, as your code works very well, is it possible to use for my project? adding a dht22, 2 channel relay and controlling the humidity and temperature of a fridge to refine the cheese? Thanks in advance and forgive me for translation errors.

farmerkeith (author)Col682017-10-18

Yes of course you can base your code on mine in the instructable if you want to. That is one of the main reasons for publlishing it, so you can use it to hep you get going. If yo need any help with adding the DHT22 and relays, please do not hesitate to ask. Good luck and enjoy the project. Keith

Col68 (author)farmerkeith2017-10-18

thank you very much for your kindness Keith, my adventure is difficult, but I will do step by step, step 1 was to find a skit compatible with shield 1602 and I2c, thanks to you it is ok,

step 2 is to introduce a sensor Dht22 and relay for humidity and temperature,

step 3 would be successful to use the buttons to have a management menu with setting of the temp. and humydite wish, is my dream amateur.

I will try to add the dht and relay to share if all is ok, thank you again dear Keith, luckily you are present, I wish you happiness.

Col68 (author)Col682017-10-20

Hello Keith, I tried to start writing my sketch thanks to your sharing using your own sketch, thank you again for sharing, I send you the beginning, to see if I start, thank you for correcting me:

#include <Wire.h>

#include <LCD.h> #include <LiquidCrystal_I2C.h>

#include <DHT.h> LiquidCrystal_I2C lcd (0x27,2,1,0,4,5,6,7);

const int relay1Pin = 8; // PIN 8 pour le relais

const int relay2Pin = 9; // PIN 9

const int DHTPIN = A0; // PIN A0 pour le capteur

#define DHTPIN A0

#define DHTTYPE DHT22

#define RELAY1PIN 8

#define RELAY2PIN 9

int readkey;long int lastmillis;long int hours;long int minutes;long int seconds;char l2c1; char l2c2;char l2c3;


farmerkeith (author)Col682017-10-20

Hello Col68,

I assume you are using one of the Arduino family - nano or uno, etc.

You do not need any of the #define statements. It is much better to use const as you have done, so the #define statements just duplicate what they are doing, and may cause confusion later on.

I think it is possible to use pin A0 for DHT data pin, but all the examples I have seen use a digital pin, and I would recommend you use a digital pin also. For example pin 2 or 4, but any unused digital pin will be OK.

The other #define statement that is not a duplicate of a const declaration is your #define DHTTYPE DHT22. I recommend you delete this also, and when you create your DHT object you just write it as


Another thing, you have named your relay pins relay1Pin and relay2Pin, which is OK, but you also have the option of giving them names that relate to their functions, which I think might be heaterRelay and humidityRelay, or some name (maybe in French) that helps you get the correct relay when you are writing the control code.

Good work so far, keep going!


Col68 (author)farmerkeith2017-10-21

Thank you very much Keith, I do not want to disturb you with my adventure, I will try to get by, thank you for your kindness, very good continuations, Sincerely.

farmerkeith (author)Col682017-10-21

Hi col68, I wrote a reply to your latest questions, but I think I made a mistake with pressing the wrong button and it was deleted. However I saved it and am now trying to send it again.

Hi col68, I have had a look at this code. I have some suggestions for you to consider for software writing; and for the development process; and for the code itself. These are not strict rules or requirements, just things that I have found make the process easier and more efficient.

Software writing:

Include plenty of comments (thry will help when you come back in the future, and possibly other people who may look at and/or use your code).

Use descriptive variable names. For example "humidity" rather than "h" and "humidityThreshold" rather than "hum". For compound names (like "humidityThrushold" mark each new word in the name with an upper case letter, as in this example.

Write functions and use function calls, that than long sequences of statements (I see you have done this to some extent in your code already).

Development process

Check that your code will compile. Check it often, so that as you add or change functionality you have what you are trying to achieve still in your mind in case there is a problem.

Use Serial.print() .to find out what s going on, if you come across a problem where the software is doing something different from what you are looking for.

About your code.

I have made a new version which I will attach in a separate reply. I had to find and install the library DFR_Key.h in order to allow it to compile. I am not sure you are actually using that library, since you have your own function in the code

int read_LCD_buttons()

I am also not sure if I found the same DFR_Key.h that you are using. The one I found would not compile due to a couple of simple errors in it, which I have fixed in my version. I also had to add a parameter in the constructor call in your sketch (that one that instantiates the DFR_Key object.) If you give me a link to the library you are using we can get in sync on that front.

I had to change quite a few things, they are all noted with a "KH" comment. If you can't understand any of them, please let me know.

I saw some confusion about relay names, and I adopted one of the 3 possible ways of naming that I found in your original. Please donwload the attached code and see if it compiles for you, and try running it iwth your hardware and see if it does what you want.

Good luck and do not worry.

farmerkeith made it! (author)farmerkeith2017-10-21

Updated code for col68

Col68 (author)farmerkeith2017-10-22

Hello Keith, you have done me an unforgettable service, I am very happy thanks to you, I hope all the beautiful things for you, I hope that everything you touch become "Gold, you are a genie , I'll never forget this service, this help, you're too strong, Big thanks,

I also have problems with libraries DFR_Key, in the old sketch also I had a problem with DFR_Key I'm going to work on that , very dear Keith I copy the code provided by you, I will go to writing to try to compile, I do not know how to thank you,

I love you KEITH, thank you with all my heart.

farmerkeith made it! (author)farmerkeith2017-10-21

Hi col68, I am having trouble attaching the file. Trying it as an archive.

MuratHürmüzA (author)2017-09-21

can you share to using libraries?

You can get the LCD I2C library from here:

This is an Instructable about installing a library:

If you have problems following these, please let me know.

ChaitanyaM17 made it! (author)2017-04-18

Hey farmerkeith,

Thanks a lot for this detailed instructable.

I was able to reduce pin usage even further using this instructable and it was a great help!

Really nicely made tutorial and easy to understand.


P.S Sorry if the image is not clear, the fritzing in comments is better for connections.

farmerkeith (author)ChaitanyaM172017-04-18

Hi ChaitanyaM17, Thank you for doing the Fritzing diagram (in reply to ALEiCARGG). I htink it might help others too.

Do you mind if I add it to the Instructable, so it can easily be found by anyone?

ALEICARGG (author)2017-03-22

hey man! Can you place the diagram of the connections? I cant understand the communication between the i2c and lcd. That would help me a lot. Thanks in advance

ChaitanyaM17 (author)ALEICARGG2017-04-18

I know your problem is solved, but here is the connection diagram for future issues.

It was so great to find this and make it work that I made it for myself and sharing it so others like me can do it easily too!


farmerkeith (author)ALEICARGG2017-03-23

Hi Aleicargg, I am happy to help you work out these connections. I agree it is a bit hard with no labels on the pins on the boards. When I wrote this instructable, I thought that the explanation I gave in Step 3 was clear. It is a matter of placing the two modules as they are shown in the main photo, and counting pins. Have you tried that? If necessary I will do a diagram but I cannot do it right now, and maybe we can answer your questions without a diagram.

ALEICARGG (author)farmerkeith2017-03-23

hi! yes, I made the connections as is. But the detail is that it does not turn on the lcd.

farmerkeith (author)ALEICARGG2017-03-23

Hi Aleicargg, I guess the backlight of the LCD is not being turned on, and the most likely reason is that the software logic has to be reversed from the standard setup, due to the transisor in the serial backpack.

The connection for the backlight is from serial module pin 16 (the one on far right) to LCD module pin 11 (just above the capital "S" in the word "Shield" printed on the module).

In the software, the LCD backlight control commands are:

lcd.setBacklight(LOW); // Backlight ON


lcd.setBacklight(HIGH); // Backlight OFF

These are the reverse of the commands you use for direct connection.

if the backlight is not on, you will not be able to see the characters on the LCD scree, even if they are being displayed.

Please let me know how you get on. Keith

DIY Hacks and How Tos (author)2016-05-15

Cool circuit project.

Thank you.

About This Instructable




Bio: I am a retired professional engineer, now farmer. Taking an interest in all things technological and in building devices useful on the farm.
More by farmerkeith:DIY Linear ActuatorTemperature LoggersDIY Logging Thermometer with 2 sensors
Add instructable to: