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.

Intro: 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

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.

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

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.

4 People Made This Project!

Recommendations

  • Tiny Home Contest

    Tiny Home Contest
  • Audio Contest 2018

    Audio Contest 2018
  • Furniture Contest 2018

    Furniture Contest 2018

29 Discussions

0
None
clemenlg

2 months 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
1 reply
0
None
farmerkeithclemenlg

Reply 2 months 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
None
Sara_6

5 months ago

Hello Keith,
Thanks alot for helping me.

The code I had it from internet to achieve my project it has some error as I said first but I can’t figure it out. Anyhow the project I made is about pill reminder the code should achieve on lcd keypad shows the name of medicine and can set time using keypad for when to take each does when the time come such as 3 o’clock a led and buzeer should work to notify and a photoresistor will be down at each bottle.
I will post from where I found the project to see what I mean.
https://armartin891.wordpress.com/2014/05/08/final-project-report-the-friendly-pill-reminder/
Could you help be connect buzzer and I2c add to the code if you find what’s written? Because I have struggle on it

9 replies
0
None
Sara_6Sara_6

Reply 5 months ago

Also I had change the LCD to LCD keypad and add I2c and buzzer.

Thanks.

0
None
farmerkeithSara_6

Reply 5 months ago

Hi Sara_6, I think we are making progress.

I can now get your software to compile. To achieve this, you need to add a couple of lines to the Version 1.4 MenuBackend.h library. It is quite simple.

Find the MenuBackend.h file and open it in a text editor such as Mousepad. It should be version 1.4 (the version number is in line 4).

Go to line 195, and just before the line that says private: add the following:

void toRoot(){
setCurrent(&getRoot());
}

Then save the file.

Once you have done that, your software should compile without errors. After that, you can start working on making it do what you want it to do.

0
None
farmerkeithfarmerkeith

Reply 5 months ago

Hi Sara_6, With your software which I have changed a little bit, I now have the LCD displaying "Take 1 pill(s)" on line 1 and "every 1 hours" on line 2. Progress. The changes I made to your software are:

in the "includes" section, add

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

and delete

#include <LiquidCrystal.h>

This is because you need the library for the LCd that accesses it via I2C.

Not far below that, replace

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

with

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

This is to tell the I2C library the address and what pins to use.

Also (this is not essential but it helps) just after the line

Serial.begin(9600);

add a new line

Serial.println("\n Starting pillReminder ");

Can you please tell me the exact modules that you are using?

In particular, are using the DFRobot keypad LCD or the Sainsmart one?

Are you using the Sparkfun real time clock module, or the TinyRTC module?

Which Arduino board are you using (I am using a Nano)?

Please let me know how you go with these suggestions.

Keith

0
None
farmerkeithfarmerkeith

Reply 5 months ago

Hi Sara_6, I realised soon after I sent this that you don't need any of these last changes. I think you are using direct connection between your Arduino and the LCD keypad unit. So you don't need the serial library after all. I had assumed that you were using serial, because that is what this Instructable is mainly about.

I am looking forward to your answers to my questions still.

Keith

0
None
farmerkeithfarmerkeith

Reply 5 months ago

Hi Sara_6, I am not sure about whether you want to change the LCD to serial, or leave it directly connected. Either way is possible and I think I have given you the information you need to do either.

The only other thing I found was that on my version of the LCD keypad (which the DFRobot type) I had to change the threshold values for key recognition. The adjusted code, with relevant comments, is copied below here.

if (adc_key_in > 1000) return btnNONE;
if (adc_key_in < 50) return btnRIGHT; // was 50; R button returns 0
if (adc_key_in < 180) return btnUP; // was 250; U button returns 100
if (adc_key_in < 333) return btnDOWN; // was 450; D button returns 257
if (adc_key_in < 524) return btnLEFT; // was 650; L button returns 410
if (adc_key_in < 820) return btnSELECT; // was 850; S button returns 639
return btnNONE;

The other change that you said you wanted to do was to add a buzzer. I think you should get the basic unit working on the existing code first, and then add the buzzer afterwards. Adding the buzzer will be quite simple if you know what you want it to do.

Please let me know how you get on.

Keith

0
None
Sara_6farmerkeith

Reply 5 months ago

hello Keith,

I will update you what I have done until now and I'll answer your questions. first I'm using LCD keypad not directly on Arduino sine I need Arduino board to connect the other parts like LED and other so I made the connection LCD with i2c and change on the code based on what you said. I change LCD to LCD with i2c and solve the error for

MenuBackend.h by upload library for both. so this problem sloved.

Can you please tell me the exact modules that you are using?

In particular, are using the DFRobot keypad LCD or the Sainsmart one? I don't know exactly but for LCD check it here SKU: CAN67

http://www.etqan.sa/product-page/lcd-keypad-shield

Are you using the Sparkfun real time clock module, or the TinyRTC module? I will post a picture. and as I just realized today the RTC I'm using is different than the one in the code!

Which Arduino board are you using (I am using a Nano)? I'm using Arduino uno

and then another problem shown in the code after the first one is solved here is it

no match for 'operator==' (operand types are 'const char*' and 'MenuItem')

if(newMenuItem.getName()== menu.getRoot()){

^

exit status 1
no match for 'operator==' (operand types are 'const char*' and 'MenuItem')

also about what you mention I don't I don't know where to add them and what to delete.

"

Go to line 195, and just before the line that says private: add the following:

void toRoot(){
setCurrent(&getRoot());
}

Then save the file.

"

if (adc_key_in > 1000) return btnNONE;
if (adc_key_in < 50) return btnRIGHT; // was 50; R button returns 0
if (adc_key_in < 180) return btnUP; // was 250; U button returns 100
if (adc_key_in < 333) return btnDOWN; // was 450; D button returns 257
if (adc_key_in < 524) return btnLEFT; // was 650; L button returns 410
if (adc_key_in < 820) return btnSELECT; // was 850; S button returns 639
return btnNONE;

"

so could you please if you made the change and the code run well with you attach a file on Note or any other program that will help me and you to see what's going on easier.

I will upload you the code and the 2 new library a download as a zip files.

thank you, your comment help me and I'm looking forward for your answer as soon as posiple.

RTC.jpg
0
None
Sara_6Sara_6

Reply 5 months ago

Parts list:
red LED (3x)
510 ohm resistors (3x)
2.2 kohm resistors (3x)
photoresistors (3x)
Sparkfun Real Time Module (1x)
Arduino uno(1x)
LCD Keypad Shield (1x)
buzzer (1)
i2c

and buzzer code it's ode later add it just if all the problems sloved

0
None
farmerkeithSara_6

Reply 5 months ago

Sara_6, this is not your parts list.

Instead of Sparkfun Real Time Module (1x) it should say DS1302 real time module

Instead of LCD Keypad Shield (1x) it should say DFRobot LCD Keypad shield.

I suspect that the item that says i2c actually means I2C serial backpack for LCD module. By itself, i2c is meaningless.

Being specific about the parts you are using helps a lot in working out how to help you.

Keith

0
None
farmerkeithSara_6

Reply 5 months ago

Hi Sara_6, We are progressing but slowly.

The link to your lcd keypad module has a photo that clearly shows it is the DFRobot module. Hence I think the button values will be the same as mine.

The photo of your real time clock module shows that it is NOT a DS1307, but is a DS1302. This runs a different protocol than the DS1307, and is not I2C. We will have to use different pins for this module, and different software. I found a link to a site that probably will provide a solution, here:

https://playground.arduino.cc/Main/DS1302

I have not tried it, because i don't have a DS1302 module. I think you should connect your module to some spare pins on your Uno, download his software and try it as is.

The compilation error you have been getting - I get it also when I use MenuBackend.h version 1.6 (which is the one you sent me). It does not occur with MenuBackend.h version 1.5. I am attaching that so you can use it. This is not a very satisfactory situation, because usually a later version of a library should not make earlier code fail. However we can proceed with Version 1.5 at least for the moment.

I am also attaching an updated version of your software. It includes changes that I think will work for you. There are some lines with comments that say "//works for KH" and the next line says "//works for Sara". I have commented out the KH lines and left in the Sara lines. You may need to swap some of them around. If you open it up and load it to your Uno with the serial monitor running you should be able to see the results of button presses on the serial monitor, and at least some of them will show up on the LCD screen. Maybe you can figure out if it is doing what you want.

If it is OK as it is, the main job remaining will be to get the DS1302 going (as per suggestions above).

Good luck,

Keith

0
None
Sara_6

Question 5 months ago

hello farmerkeith,

please I need help I tried may best and since this is my first time working on project.

it's hard to see the connection wire clearly that you mention, but can you check what I am done is it true ??

I have a problem while I connect the Ardunio to upload the code nothing would be shown in the LCD screen I tried different code but what is the problem do you think?

i notice that there is one wire if I disconnected it from the circuit the LCD will be always ON but nothing show on it. when I didn't connect this wire it will be ON just when I upload the code then OFF directly "ON/OFF just the light"

image3.jpgimage1.jpgimage2.jpg
5 more answers
0
None
farmerkeithSara_6

Answer 5 months ago

Hi Sara_6, I had another look at this.

I found a solution on the internet that allowed me to compile the example.

The errors I get with your code is just one, which appears twice. It is on line 103 and line 431 of your code, where the code says "menu.toRoot();" which the compiler rejects since there is no "toRoot" in the class definition, or anywhere else in the MenuBackend.h file. Did you copy this from somewhere? Do you know what it is supposed to achieve?

Keith

0
None
farmerkeithSara_6

Answer 5 months ago

I found another version of MenuBackend.h at

http://www.arduino.cc/playground/uploads/Profiles/...

At least it compiles as a valid library, but neither the example nor your sketch will compile with it. They both fail with errors. So I think help is still needed from the experts on this menu management system.

0
None
farmerkeithSara_6

Answer 5 months ago

Hi Sara_6, I am glad to hear that your LCD problem is solved and it now works.

I put your software into an Arduino sketch and pressed the button for verify. It returns "Error compiling for board Arduino Nano" and (among other things, and after copying in MenuBackend.h from github) "Invalid library found in ... /Arduino/libraries/Wiring:" So I think your problem is with using that library. It is new to me, I have not used Wiring.

I think your options are to use some other pathway to achieve your programming goals; or seek help from the Wiring community who may be able to give you guidance on getting this library installed and working.

If you want to go forward without using the Wiring framework, I expect I can help you with any problems you may encounter.

I am sorry I can't be more help.

Keith

0
None
Sara_6Sara_6

Answer 5 months ago

Hi Keith,

Great yes finally LCD works with me, Thank you.

my project is about a pill reminder, But when i try to upload the code for the project it doesn’t work not verify on Arduino software and always a wrong message showed up.
"I copy and paste it on Arduino software"

also I want to add another code for i2c because as I think when i add i2c to the circuit I need other code for it but I don't know how to connect two codes together or no need for it?

could you check the code please ?

1
None
farmerkeithSara_6

Answer 5 months ago

Hi Sara_6,

Have you tried adjusting the contrast pot on the DFRobot LCD shield? It is a multi-turn pot at the top left corner of the shield. Try winding it clockwise for several turns (up to 10) and see if you start to see the pixels on the LCD display.

Please let me know if that solves your problem.

Keith

0
None
Col68

9 months ago

Hello to very kind Keith, after seeing your magnificent instructable needing to make a thermostat I am disturbing you with my adventure, you have brought me big help unforgettable, with patient worthy of a father, thank you very much.

I am amateur in electronics but thanks to you I finally managed to finish the project "Keith Control". You are a great man, I can not find words,

Thank you with all my heart, I wish you very beautiful Christmas and end of year, I wish you good santer, good mood, happiness and peace,

with my big respect for you Keith. I love you.

20171210_231830.jpg20171213_000850.jpg20171213_000544.jpg
1 reply
0
None
farmerkeith

Reply 11 months ago

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 is attached here. 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.