Arduino LCD Complete Tutorial for Beginners

Using an LCD display can give you an advantage in your Arduino project. This LCD can show some information about your project. For example, you can create a distance measurement system that displays the distance on LCD, or you can create a simple project that only shows some message on LCD.

In this tutorial, I will show you how to use a 16×2 Character LCD display with Arduino. I will show you how you can print text, blink text, scroll text, display custom characters.

Component need for Arduino LCD Tutorial

16×2 Character LCD x1Amazon / AliExpress / Baggood
Arduino UNO Rev3 x1Amazon / AliExpress / Baggood
Breadboard x1Amazon / AliExpress / Baggood
Jumper wires ~ 10Amazon / AliExpress / Baggood
10 kΩ potentiometer x1Amazon / AliExpress / Baggood

Hardware Overview

Character LCDs are available in many different sizes (16×2 or 1602, 20×4 or 2004, etc.) but most of them use the same HD44780 parallel interface LCD controller from Hitachi. So you can easily modify the code a little bit and it would work for 20×4 LCD.

16×2 LCD Pin out :

16×2 LCD has 16 pins and can be operated in 4-bit (using 4 data lines) or 8-bit mode (using 8 data lines).
Pin Count Starts from left to right. The very first pin from the left is the VSS pin. Then VCC, V0, RS, R/W, EN, D0 to D7, and at the last Anode and Cathode.

16x2 lcd pinout

VDD/VCC & VSS : These two pins are for the power supply. You have to provide a 5v power supply through these two pins. Connect VDD/VCC to +ve end of the power supply and -ve end to VSS.

V0/VEE : This pin is for controlling the contrast of the LCD. Connect a variable 10 kΩ resistor to this pin.

RS : Register select pin. Basic 16×2 character LCD has two types of register, command register, and data register. Logic 0 at pin RS selects command register and Logic 1 at pin RS selects data register. If we select the data register, input through the data line (D0-D7) will be treated as data to show in the display and when we select command register input will be treated as a command.

R/W : Read/Write pin. This pin gives us an option whether we want to read the data from LCD or write to LCD.

E : Enable pin. A HIGH to LOW pulse is required at this pin to enable the LCD for any operation.

D0 – D7 : Pin D0 to D7 are 8-bit data pins. The command and data are sent to the LCD through these pins. Pin D7 to D4 are used for 4-bit mode.

LED+/A & LED-/K : These two pins are for controlling the backlight of the LCD. Connect a 5v power supply to this pin. Or if you want to control the brightness you can connect a variable resistor to this pin.

Connect the LCD to the Arduino Uno

arduino lcd circuit diagram

A typical 16×2 LCD needs 5v to operate. So connect LCDs VCC to the +5ve pin of Arduino and VSS pin to the ground.
Vo pin is for controlling the contrast of the LCD. Connect a 10 kΩ variable potentiometer to it so that you can control the contrast.
The last two pins from the left are anode and cathode. You can control the backlight through those pins. Connect the anode pin with the +5ve through a series 220Ω resistor and connect the cathode to the ground.
Connect the RS pin to Arduino pin no 2, R/W pin to ground, and EN pin to Arduino pin no 3.
Then you have four data pins D4 to D7. I connect those pins to Arduino digital pin no 4, 5, 6, 7 respectively. We are using the 4-bit mode so you don’t need to connect anything to pins D0 to D3.

Note :- If you want to use the 8-bit mode simply connect the remaining four data pins i.e D0 to D3with four Arduino digital pins and change the code accordingly.
Technically 8 bit mode is faster because 8 data pins are used. So 8-bit data can be sent at once. But in practical you can’t see much difference.

Arduino Code for 16×2 LCD

We are using Arduino LiquidCrystal Library to control our LCD. It is a great library to control LCD with an Arduino. And it comes pre-installed with Arduino IDE.

In order to use a library, you need to include it in the program. In line 1 we can include LiquidCrystal Library through this line #include <LiquidCrystal.h>
Now we are ready to get into programming. Before we get into detailed programming first run a simple program given below. It will print “Hello,Welcome to Circuit Geeks” on the screen.
Enter this code to the Arduino IDE and upload it to your Arduino board.

#include <LiquidCrystal.h>
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
void setup() {
   lcd.begin(16, 2);
}
void loop() {
   lcd.setCursor(0, 0);
   lcd.print("Hello,Welcome to");
   lcd.setCursor(0, 1);
   lcd.print("Circuit Geeks");
}

Your LCD should look like this.

arduino lcd basic program

Explaining the Code

So you can see various functions used here.

First, we include the LiquidCrystal library by #include <LiquidCrystal.h> this line of code.
Then we use LiquidCrystal() function to create a variable for our LCD named “lcd”. You can name it anything like lcd1, lcd2, mylcd, etc.
This function helps us to define the pin numbers Arduino uses to control the LCD. We will discuss more on this function in detail later.

Then in the void loop() section, we set the cursor at 0th column 0th row position by lcd.setCursor(0, 0); this line and print Hello,Welcome to to the first line by lcd.print("Hello,Welcome to"); this line of code.
Then set the cursor at the second line i.e 0th column 1st row by lcd.setCursor(0, 1); this line and print Circuit Geeks by lcd.print("Circuit Geeks"); this line of code.

So you got the basic idea of how the code works with Arduino and LCD display. Now we will discuss about various functions available in LiquidCrystal Library. There are 20 different functions available in the Arduino LiquidCrystal library. We will discuss one by one with an example.

LiquidCrystal()

This function is used to create a variable of type LiquidCrystal for an LCD. You can name it anything like lcd1, lcd2, mylcd, etc.
This function helps us to define the pin numbers that Arduino uses to control the LCD.

Basics syntax for this function would look like this
LiquidCrystal(rs, rw, enable, d4, d5, d6, d7); for 4-bit mode and
LiquidCrystal(rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7); for 8-bit mode.

Where rs is the no of Arduino pin which is connected to the LCD’s RS pin.
rw is the no of Arduino pin which is connected to the LCD’s R/W pin.
R/W pins can be connected to the ground. If so omit it from the function.
enable is the no of Arduino pin which is connected to the LCD’s Enable pin.

Then there is d4, d5, d6, d7 which are the no. of pins that are connected to the LCD pin no D4, D5, D6, and D7 respectively.
If you are using 8-bit mode then put the no of 8 pins of the Arduino in place of d0, d1, d2, d3, d4, d5, d6, d7 sequentially.

Here we use Arduino pin 2 to connect with LCD’s RS pin, pin 3 to connect with Enable pin, and pin 4, 5, 6, 7 to connect with pin D4, D5, D6, and D7 respectively.
And we connect R/W to the ground.

So we use LiquidCrystal lcd(2, 3, 4, 5, 6, 7); in our program.

Here we use LiquidCrystal() function to create a variable for our LCD named “lcd”.
So we have to use it like that : lcd.begin();, lcd.setCursor();, lcd.print(); etc.

If you create a variable with a different name then use it throughout the program. Let’s say you create a variable named “mylcd”, then you have to use it like this mylcd.begin();, mylcd.setCursor();, mylcd.print();

begin()

This function is used to set the dimension of the LCD.

The basic syntax for this function is lcd.begin(columns, rows);. For the 16×2 LCD we would use lcd.begin(16, 2);, and for the 20×4 LCD we would use lcd.begin(20, 4);.
This function needs to be placed before any other LiquidCrystal function in the void setup() section.

clear()

This function is used to clear the LCD screen and set the cursor at the upper left corner. The Basic syntax for this function is lcd.clear(); where ‘lcd’ is a variable of type LiquidCrystal.

This function is very useful for displaying long sentences. For example, if I want to display “Hello, welcome to CircuitGeeks. Follow us on Facebook, Twitter and Instagram. Thanks”, I can’t show it at once on a 16×2 display. But we can display it in three instances using this function.

First, we print “Hello,welcome to CircuitGeeks.” for one second then clear the display and print “Follow us on Facebook,Twitter” for one second and “and Instagram. Thanks” for one second.

Study the below code carefully and you get a clear idea how clear() function works.

#include <LiquidCrystal.h>
LiquidCrystal mylcd(2, 3, 4, 5, 6, 7);
void setup() {
  mylcd.begin(16, 2);
}
void loop() {
  mylcd.setCursor(0, 0);
  mylcd.print("Hello,welcome to");
  mylcd.setCursor(0, 1);
  mylcd.print("CircuitGeeks.");
  delay(1000);
  mylcd.clear();
  mylcd.setCursor(0, 0);
  mylcd.print("Follow us on");
  mylcd.setCursor(0, 1);
  mylcd.print("Facebook,Twitter");
  delay(1000);
  mylcd.clear();
  mylcd.setCursor(0, 0);
  mylcd.print("and Instagram.");
  mylcd.setCursor(9, 1);
  mylcd.print("Thanks");
  delay(1000);
  mylcd.clear();
}

home()

This function is used to set the cursor at the home location i.e upper left corner of the LCD and use that location to output subsequent text to the display.

setCursor()

setCourser() is used to position the cursor at any place of the display. And subsequent text can be displayed from that location.

The Basics syntax for this function is lcd.setCursor(columns, rows);.

For example, if you want to display any text at the bottom right half of the display, simply place the cursor at the (7,1) position (columns, rows) by using this line lcd.setCursor(7,1);
And print anything from there.

Complete code for this example would look something like this:-

#include <LiquidCrystal.h>
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
void setup() {
  lcd.begin(16, 2);
}
void loop() {
  lcd.setCursor(7, 1);
  lcd.print("Hello");
}

Note that the columns and row count start from 0. So (0,0) would be the first place of the display and (15,1) would be the last place for a 16×2 display.

write()

This function is used to display a character to the LCD. The basic syntax for this function is lcd.write(data);.

We will discuss more on this function in the Arduino LCD custom character section.

print()

This function is used to print text to the display.
You can use this function within the setup() section or within the loop() section of the program.

The basic syntax for this program is 
lcd.print(data); or
lcd.print(data, BASE);

data could be any char, byte, int, long, or string.
If you print letters and words put them inside quotation marks (“ ”).

For example, if you want to print Hello world ! use lcd.print("Hello world !");.
For numbers quotation marks (“ ”) are not necessary. So if you want to print 12345, you can use lcd.print(12345) as well as lcd.print("12345")

BASE is used to print numbers in binary, decimal, hexadecimal, and octal decimal bases.
For example,
lcd.print(31, BIN) prints “11111”
lcd.print(31, HEX) prints “1F”
lcd.print(31, OCT) prints “37”

cursor() and noCursor()

This function creates a visible cursor (an underscore line) below the next character to be printed on the display.

lcd.cursor() turns the cursor on and lcd.noCursor() turns the cursor off. Using these two functions we can create a blinking cursor.

#include <LiquidCrystal.h>
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
void setup() {
  lcd.begin(16, 2);
  lcd.print("cursor ");
}
void loop() {
  lcd.cursor();
  delay(500);
  lcd.noCursor();
  delay(500);
}

blink()

Creates a blinking block style LCD cursor at the position of the next character to be printed to the display.

lcd.blink() turns the cursor on and lcd.noBlink() turns the cursor off.

display()

This function turns the LCD display on after it’s been turned off with noDisplay(). This will restore the text that was on the display.

noDisplay()

This function turns the display off without clearing it from the LCD’s Memory.

Using these two functions together we can create a blinking text on the LCD.
This code below will display Hello World! For 1 second and clear the display for 1 second and repeat this process.

This code below will create a blinking text of Hello World!

#include <LiquidCrystal.h>
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
void setup() {
   lcd.begin(16, 2);
}
void loop() {
  lcd.setCursor(0, 0);
  lcd.print("Hello, world!");
  lcd.noDisplay();
  delay(500);
  lcd.display();
  delay(500);
}

scrollDisplayLeft()

This function scrolls the contents of the LCD one step to the left. If we use this function within the loop() section followed by a delay(), we can achieve a moving text animation.

#include <LiquidCrystal.h>
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
void setup() {
  lcd.begin(16, 2);
}
void loop() {
  lcd.setCursor(0, 0);
  lcd.print("Hello World!");
  lcd.scrollDisplayLeft();
  delay(200);
}

scrollDisplayRight()

This is similar to the above function. The only difference here is that it scrolls the texts to the right.

leftToRight()

This function prints the text or number from left to right. By default LCD prints texts from left to right. So you don’t need to use it normally. When you change the orientation by rightToleft() function, you can get back to the previous state (default state) by leftToRight() function.

#include <LiquidCrystal.h>
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
void setup() {
  lcd.begin(16, 2);
  lcd.setCursor(15, 0);
  lcd.rightToLeft();
  lcd.print("ABCDEF");
  lcd.setCursor(0, 1);
  lcd.leftToRight();
  lcd.print("ABCDEF");
}
void loop() {
}
arduino lcd right to left function

rightToLeft()

This function prints the text or number from right to left.

Arduino LCD Custom Character

createChar()

This function is used to create custom characters for the LCD. Up To eight characters of 5×8 pixels are supported for a 16×2 display.

16×2 LCD with HD44780 chipset (or a compatible) has a 64 bytes internal ​CG-RAM(character generated ram) where we can place our custom character. We can place 8 characters of size 5×8 at a time in CG-RAM.

To create a custom character first we need to create a byte array for that character. Then place it into LCD’s CG-RAM memory using createChar(); function and print it using write(); function.

LCD Custom Character Example code for Arduino

#include <LiquidCrystal.h>
// Creates an LCD object. Parameters: (RS, E, D4, D5, D6, D7)
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
// Make custom characters:
byte smiley[] = {
  B00000,
  B10001,
  B00000,
  B00000,
  B10001,
  B01110,
  B00000,
  B00000,
};
void setup() {
  // Specify the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Create a new characters:
  lcd.createChar(0, smiley);
  // Clears the LCD screen:
  lcd.clear();
}
void loop() {
  // Print all the custom characters:
  lcd.setCursor(0, 0);
  lcd.write(byte(0));
}

Run this code and you will get an output like this –

arduino lcd custom character

Explaining the code

So here you can see, I create a byte array for a smiley character
byte smiley[8] = {
B00000,
B10001,
B00000,
B00000,
B10001,
B01110,
B00000,
B00000
};

Or we can simply rewrite it like this:-
byte smiley[8] = { B00000, B10001, B00000, B00000, B10001, B01110, B00000, B00000};
Here B indicates that the data is in binary format. A “0” means that the corresponding pixel is off and a “1” means that the pixel is on.

Also, we can write this array in hex format like this
byte smiley[8] = { 0x00, 0x11, 0x00, 0x00, 0x11, 0x0E, 0x00, 0x00, 0x00};
Here 0x means that the data is in hex format.

So, we create a smiley character on our program. Now we put that data into LCD’s CG-RAM memory using createChar();
Basic syntax for createChar() is lcd.createChar(num, data); where num denotes the number of the custom character. And data means the character’s pixel data.

In the setup() section, we use lcd.createChar(0, smiley); to put the byte array data to the LCD’s CG-RAM. In the loop() section, we use the write() function to write that custom character to the display. Simply put the character number inside the write() function like lcd.write(byte(0)); to print that custom character.

Now I will give another example to understand the code better. I will print a simple text along with eight custom characters. The code is given below.

#include <LiquidCrystal.h>

// Creates an LCD object. Parameters: (RS, E, D4, D5, D6, D7)
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);

// Make custom characters:
byte smiley[8] = {B00000,B10001,B00000,B00000,B10001,B01110,B00000,B00000};
byte man[8] = {B00000,B01110,B10001,B01110,B00100,B11111,B00100,B11011};
byte music[8] = {B00001,B00011,B00101,B01001,B01001,B01011,B11011,B11000};
byte heart[8] = {B00000,B01010,B11111,B11111,B01110,B00100,B00000,B00000};
byte speaker[8] = {B00001,B00011,B01111,B01111,B01111,B00011,B00001,B00000};
// Using Hex data
byte bell[8] = {0x00,0x04,0x0E,0x0E,0x0E,0x1F,0x04,0x00};
byte pie[8] = {0x00,0x1F,0x0A,0x0A,0x0A,0x13,0x00,0x00};
byte ohm[8] = {0x00,0x0E,0x11,0x11,0x0A,0x1B,0x00,0x00};

void setup() {
  // Specify the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Create a new characters:
  lcd.createChar(0, smiley);
  lcd.createChar(1, man);
  lcd.createChar(2, music);
  lcd.createChar(3, heart);
  lcd.createChar(4, speaker);
  lcd.createChar(5, bell);
  lcd.createChar(6, pie);
  lcd.createChar(7, ohm);
  // Clears the LCD screen:
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Custom Caracter");
}
void loop() {
  // Print all the custom characters:
  lcd.setCursor(0, 1);
  lcd.write(byte(0));
  lcd.setCursor(2, 1);
  lcd.write(byte(1));
  lcd.setCursor(4, 1);
  lcd.write(byte(2));
  lcd.setCursor(6, 1);
  lcd.write(byte(3));
  lcd.setCursor(8, 1);
  lcd.write(byte(4));
  lcd.setCursor(10, 1);
  lcd.write(byte(5));
  lcd.setCursor(12, 1);
  lcd.write(byte(6));
  lcd.setCursor(14, 1);
  lcd.write(byte(7));
}

Summary

In this tutorial, you have learned how to display different types of text, number, characters as well as custom characters on the display. but one thing you have noticed is that the LCD consumes a lot of I/O pins on the Arduino. To reduce the pin consumption you can use an Arduino I2C LCD display in your project. In my Arduino I2C LCD tutorial, I have covered how to connect an I2C LCD display with Arduino.

I hope you like the tutorial, if so please subscribe to our weekly newsletter to get more such content in your inbox.

Help me to Build more Projects for You!

At CircuitGeeks, we're passionate about creating exciting electronics projects and sharing our knowledge with the world. Our projects are free and open to everyone, but we would need your support to keep the creativity flowing!

If you enjoy our work and find our projects valuable, please consider supporting us on Buymeacoffee. By buying us a coffee, you help us buy more components and keep our projects going strong.

We truly appreciate your contribution!

Leave a Comment