16×2 LCD Interface – Arduino LCD Display

There are various kind of displays available for Arduino boards. Some of them use I2C communication, some use SPI protocol and some uses port interface. Liquid Crystal or LCD displays are available in two sizes, 16×2 LCD( 16 Column, 2 Row) and 20×4 LCD( 20 Column, 4 Row). Both of them can be used using the same Arduino library called “LiquidCrystal.h“.

Connect 16×2 LCD Display With Arduino

16x2 LCD Arduino Interface

LCD Displays have a drawback and that is, it used too much of the pins to be operated. It need at least 6 pins of the Arduino for 4-bit communication and 10 pins for 8-bit communication. But they are used on most of the projects because coding them is easier.


Arduino code for a LCD Display

First of all, define the pins and create an lcd object. Inside the void setup, “lcd.begin(16, 2) stands for 16×2 LCD display that has 16 columns and 2 rows. In case of 20×4 LCD display, lcd.begin(20,4) it will be. Any string of 16 characters can be printed using lcd.print() function. Other data types can also be used by simply passing them into the function.

#include <LiquidCrystal.h>

// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("hello, world!");

void loop() {
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  // print the number of seconds since reset:
  lcd.print(millis() / 1000);

lcd.setCursor() is used to print data in a particular location into the display. If you want to display a message into 2nd row, column 5 then the code will be lcd.setCursor(4,1). The prototype of the function is lcd.setCursor(column, row). The numbering starts from 0. So, for 2nd row, it will be 1 and 5th column, it will be 4.

Burn Arduino Bootloader into ATmega328 (0x1e9514)

Programming an Arduino is easy and a lot of resources are available online. The Arduino boards contains ATMEL AVR 8 bit microcontrollers. Arduino Uno, Nano and Mini Uses the ATmega328p chip as the main processor. These boards are custom bootloaded that makes the programming easier. However, we can burn that bootloader into ATMEL Chips manually that would allow us to run Arduino code into AVRs directly which is very cost efficient compared to an Arduino. The process for burning bootloader into ATmega328 (0x1e9514) is slightly different.

What is the difference between ATmega328 and ATmega328p?

The “P” in ATmega328p stands for Pico-Power Technology. It means this chip can run with minimal power. It turns of peripheral modules that hasn’t been utilized by the code and thus saves power. The pin configuration and other features are identical. we can run the same code these two devices but the problem occurs when  the device is called by it’s signature because the two devices have two different identities. ATmega328 has device signature 0x1e9514 and ATmega328p has device signature 0x1e95of. So we need to know which chip we are using when programming it through the Arduino IDE. The Arduino IDE is configured for ATmega328p so when we use ATmega328 we need to edit the “avrdude.conf” file. The procedure for burning bootloader and uploading program into the chip for the two variants has been described below.

What is Bootloader and How to Upload it?

Bootloader is a small program that runs in Arduino which receives data from pc and writes it to Arduino memory. By using this method we can easily program an Arduino without using any special hardware. Programming AVR boards require using UBSAsp programmer. But the bootloader utilizes the In System Programmer(ISP) to program the chip.

Bootloader Burning into ATMega328p

The bootloader Uploading process is simple. First You have to Upload a sketch to the Arduino called “ArduinoISP” which you can find into the Arduino IDE Examples. This sketch tells the main processor to act as a programmer. The codes coming into the processor are not for itself. Now, go to Arduino IDE > Tools > Programmer > Arduino as ISP. Hit “Arduino as ISP” this is the hardware setup for Arduino to behave as a programmer.

After that prepare the chip on which you are going to burn the bootloader. You will need the following components.

  1. ATmega328p Chip
  2. BreadBoard
  3. Crystal Oscillator (16 MHz)
  4. 2x 22pF Ceramic Capacitor

The Arduino bootloader requires a 16 MHz Crystal Oscillator. If you don’t use this you will get the following error.


avrdude: Device signature = 0x000000
avrdude: Yikes!  Invalid device signature.

The crystal oscillator is the heart of the Arduino and without it the Arduino is dead. So, it return the following error. Using the ceramic capacitors are recommended but I found the system working without using them. It time to build the circuit. Build it as follows:

Now, Arduino IDE > Tools > Burn Bootloader and hit the “Burn Bootloader” Buttton. If the process is is successful then you will see the message “Done Burning Bootloader”.

avrdude: Expected signature for ATMEGA328P is 1E 95 0F

You will get this error if you are using ATmega328. Because, Arduino UNO/NANO bootloader is written for ATmega328p that device signature 0x1e950f. So, we have to change the device signature to 0x1e9614. Firstly, navigate to the Arduino Installation folder. In my case, it is “C:\Program Files (x86)\Arduino\hardware\tools\avr\etc“. Copy the file “avrdude.conf” to somewhere for safety. If there is any problem, you can restore it anytime. After that, open that file using “notepad ++” or any text editor. Press “CTRL+F” to open the find window and type “0x1e 0x95 0x0f” . You will find two occurrences. Replace them with “0x1e 0x95 0x14“. Save the file. Now, do the same thing you used to burn bootloader to atmega328p.

Note: You need to change the signature back to “0x1e 0x95 0x0f” when you will you use your Arduino. Because your Arduino still has the atmega328p chip. We used  “0x1e 0x95 0x14” to make Arduino believe that the device we are going to bootload is the required device. Additionally, you have to change the programmer to “AVRISP mkll”. This programmer programmers the main programmer in the Arduino board.

Upload Programs to Custom Bootloaded ATmega328 chip

This process is same for both of the chips. Plug an LED to Digital Pin 13. You can find it from the figure below. Open the blink sketch. Go to, Arduino IDE > File > Examples > Basics > Blink.  Check the programmer. It should be “Arduino as ISP”. After that, Sketch > Upload Using Programmer.

You can find the physical pin number of ATmega328 for Arduino digital pin 13 from the picture above. It is pin 19.

Note: Don’t get confused between selecting the programmer. When you are burning or uploading code to the external atmega328/atmega328p chip use “Programmer > Arduino as ISP”. But choose “Programmer > AVRISP mkll” when you are uploading the code to the Arduino itself.

Watch the video to get help: 

Open Smart Rich Shield – Arduino Vault

Open Smart Rich Shield is a beginner-friendly shield for Arduino Uno. It can also be used with Arduino Mega. This shield gives you easy access to a 4 digit 7 segment display, 4 LEDs, 2 buttons, LDR,  Temperature Sensor, Voltage sensor, IR sensor, and a buzzer. Controlling a 4 digit 7 segment display can be difficult. Open Smart Rich Shield library makes it easy for its users. The shield contains a TM1637 driver IC to make the display control facile.

There are 2/3 Open Smart Rich Shield libraries. The one I have used could be downloaded from here.

Download Arduino and LDR Proteus Libray also. The Arduino code that has been used to operate the system can be found here. If you have downloaded all the files mentioned above you are ready to go.

Features of this project:

  • The vault door is locked or not is sensed by the LDR sensor. If the door is open then it won’t take code input. First, you have to lock the door.
  • The shield has two keys. The first key is used to change the number and the second key is used to confirm it and store it.
  • The red led indicates the wrong password. Green led indicates the right password.

If you look at the shield you can see that the LDR is front faced so we can not place the LDR inside the vault. To solve this problem, we place the finger on the sensor to make the system understand that the vault door is open. If we uncover it then the system reads as the door is closed and locked.

Open Smart Rich Shield – Arduino Vault Code Explanation:

I have divided the code into sections to explain easily. Each function is a section. So we have four sections here:

  • void Setup(): Used to declare the setup parameters.
  • void Loop(): The main function where the Arduino by default runs in an infinite loop.
  •          bool matchpassword(): This is a function that has been used to compare user input with the stored password.
  • char numberToCharConversion(int j): This function does two things at a time. First checks if the system is in “Normal” or “setPassword” mode. If it’s in the “normal” mode then convert integer variable “ j ” to character type and stores in the “dataStr” character array. In the case of “setPassword” mode stores in the “password” character array.

So how it works then?

1. The first condition for the project is, when you put your finger on the LDR, it indicates that the door is opened and it should not receive code input unless the door is closed and locked. The “threshold” variable at line 11 sets the LDR reference point. If it is greater than 300 that means there is enough light ( no finger on the LDR)  and when it is less than 300, it means the LDR is covered by a finger ( it’s dark).

So, the code starts from this condition at line 39. Then it turns the “GREEN_LED” as an indicator that the safe door is close and locked. The display shows “___”. You can set it as you like or keep it blank. 


2. Then you get to decide if you want to input the password or change it. I have defined two modes, “Normal” and “setPassword”. You can choose between the two using the “input_button”. If you press the “input_button” once then it goes into the “Normal” mode. If you press and hold the “input_button” for more than 3 seconds it goes into the “setPassword” mode. Line 42 has been used to stop Arduino from doing anything until you press the “input_button”. After that, the timer starts. It has been used to count how long you are pressing the button. Line 42, stops Arduino until you release “input_button”. The rest you can understand. Let’s say, you have chosen “setPassword” mode. Line 49 clears the previously stored password. Line 47 turns the “Yellow_LED” on, which indicates you are in the “setPassword” mode. The rest you can understand.

3. “digitNumber” refers to how many digit you want to enter as input. The “ while “ loop runs 4 times as the working digit is 4. Line 60 to 85 generates “ cyclic number “ ex. 1 > 2 > 3 > 4 > 1 and goes on and also displays it on the display.  Line 64 to 72 for user input or “Normal” mode. Line 74 to Line 82 is for the “setPassword” mode.

Here you can see, we are using “password []” character array. Because when we are changing password, we are making changes into the array that contain “Main Pasword”.

4. Then Line 87 freezes Arduino until you press “input_button” to change the digit or “confirm_button” to confirm it. If somehow, the LDR value is changed which denotes a force entry without entering password, “goto” statement sends the code  to the forcedOpen section in Line 157. It will be discussed letter. If you press confirm, the program sends the integer “j” to the numberToCharConversion() function mentioned at the start.

5. Line 108 to 154 does the password matching operation. If it is in the “Normal” mode, and the password is correct, then clears the used input array to make it ready for the next input.

6. If the password is wrong, then also clears the used input array and blink “RED_LED” for 5 sec. It also counts login attempt. If you enter the wrong password for more than 3 three times it sends you to the “forcedOpen” label.

7. From line 140 to 154, If you are in the “setPasword” mode, then it blinks the “Yellow_LED” 3 times to indicate that the password has successfully changed.

8. Line 156 to 180 is the condition when the safe door is open or “forcedOpen” condition. It plays the buzzer, blinks the “red_LED” 5 times. In the case of 3 failed logins, send a message to the reception through the serial monitor. Line 179 freezes the processor until there is enough light or you remove the finger from the LDR.

If you have any questions regarding this project please ask in the comment section.

Watch How to Build Arduino Vault in Proteus on Youtube:


The proteus library for the open smart rich shield is not available but you can build it easily into proteus from the circuit diagram.