Find out how to wire an LCD to an Arduino, and how to use the LiquidCrystal library through a set of useful examples.
LAST REVISION:
12/05/2023, 02:33 PM
This article was revised on 2021/11/18 by Karl Söderby.
The LiquidCrystal library allows you to control LCD displays that are compatible with the Hitachi HD44780 driver. There are many of them out there, and you can usually tell them by the 16-pin interface.
Output of the sketch on a 16x2 LCD
The LCDs have a parallel interface, meaning that the microcontroller has to manipulate several interface pins at once to control the display. The interface consists of the following pins:
There's also a display contrast pin (Vo), power supply pins (+5V and GND) and LED Backlight (Bklt+ and BKlt-) pins that you can use to power the LCD, control the display contrast, and turn on and off the LED backlight, respectively.
The process of controlling the display involves putting the data that form the image of what you want to display into the data registers, then putting instructions in the instruction register. The LiquidCrystal Library simplifies this for you so you don't need to know the low-level instructions.
The Hitachi-compatible LCDs can be controlled in two modes: 4-bit or 8-bit. The 4-bit mode requires seven I/O pins from the Arduino, while the 8-bit mode requires 11 pins. For displaying text on the screen, you can do most everything in 4-bit mode, so example shows how to control a 16x2 LCD in 4-bit mode.
Note that this circuit was originally designed for the Arduino UNO. As the Arduino is communicating with the display using SPI, pin 11 & 12 will change depending on what board you are using. For example, on a MKR WiFi 1010, the SPI bus is attached to pin 8 & 11.
Before wiring the LCD screen to your Arduino board we suggest to solder a pin header strip to the 14 (or 16) pin count connector of the LCD screen, as you can see in the image further up.
To wire your LCD screen to your board, connect the following pins:
Additionally, wire a 10k potentiometer to +5V and GND, with it's wiper (output) to LCD screens VO pin (pin3).
The circuit (made using Fritzing).
The schematic (made using Fritzing).
This example sketch prints
Hello World
!
to the LCD and shows the time in seconds since the Arduino was reset.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#
include
<LiquidCrystal.h>
45
46
47
48
const
int
rs
=
12
,
en
=
11
,
d4
=
5
,
d5
=
4
,
d6
=
3
,
d7
=
2
;
49
LiquidCrystal
lcd
(
rs
,
en
,
d4
,
d5
,
d6
,
d7
)
;
50
51
void
setup
(
)
{
52
53
lcd
.
begin
(
16
,
2
)
;
54
55
lcd
.
print
(
"hello, world!"
)
;
56
}
57
58
void
loop
(
)
{
59
60
61
lcd
.
setCursor
(
0
,
1
)
;
62
63
lcd
.
print
(
millis
(
)
/
1000
)
;
64
}
to the LCD and shows the time in seconds since the Arduino was reset.
This example sketch shows how to use the
autoscroll
(
)
and noAutoscroll
(
)
methods to move all the text on the display left or right. autoscroll
(
)
moves all the text one space to the left each time a letter is addednoAutoscroll
(
)
turns scrolling offandmethods to move all the text on the display left or right.
This sketch prints the characters
0
to 9
with autoscroll off, then moves the cursor to the bottom right, turns autoscroll on, and prints them again.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#
include
<LiquidCrystal.h>
67
68
69
70
71
const
int
rs
=
12
,
en
=
11
,
d4
=
5
,
d5
=
4
,
d6
=
3
,
d7
=
2
;
72
73
LiquidCrystal
lcd
(
rs
,
en
,
d4
,
d5
,
d6
,
d7
)
;
74
75
void
setup
(
)
{
76
77
78
79
lcd
.
begin
(
16
,
2
)
;
80
}
81
82
void
loop
(
)
{
83
84
85
86
lcd
.
setCursor
(
0
,
0
)
;
87
88
89
90
for
(
int
thisChar
=
0
;
thisChar
<
10
;
thisChar
++
)
{
91
92
lcd
.
print
(
thisChar
)
;
93
94
delay
(
500
)
;
95
96
}
97
98
99
100
lcd
.
setCursor
(
16
,
1
)
;
101
102
103
104
lcd
.
autoscroll
(
)
;
105
106
107
108
for
(
int
thisChar
=
0
;
thisChar
<
10
;
thisChar
++
)
{
109
110
lcd
.
print
(
thisChar
)
;
111
112
delay
(
500
)
;
113
114
}
115
116
117
118
lcd
.
noAutoscroll
(
)
;
119
120
121
122
lcd
.
clear
(
)
;
123
}
towith autoscroll off, then moves the cursor to the bottom right, turns autoscroll on, and prints them again.
This example sketch shows how to use the
blink
(
)
and noBlink
(
)
methods to blink a block-style cursor.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#
include
<LiquidCrystal.h>
67
68
69
70
71
const
int
rs
=
12
,
en
=
11
,
d4
=
5
,
d5
=
4
,
d6
=
3
,
d7
=
2
;
72
73
LiquidCrystal
lcd
(
rs
,
en
,
d4
,
d5
,
d6
,
d7
)
;
74
75
void
setup
(
)
{
76
77
78
79
lcd
.
begin
(
16
,
2
)
;
80
81
82
83
lcd
.
print
(
"hello, world!"
)
;
84
}
85
86
void
loop
(
)
{
87
88
89
90
lcd
.
noBlink
(
)
;
91
92
delay
(
3000
)
;
93
94
95
96
lcd
.
blink
(
)
;
97
98
delay
(
3000
)
;
99
}
andmethods to blink a block-style cursor.
This example sketch shows how to use the
cursor
(
)
and noCursor
(
)
methods to control an underscore-style cursor.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#
include
<LiquidCrystal.h>
69
70
71
72
73
const
int
rs
=
12
,
en
=
11
,
d4
=
5
,
d5
=
4
,
d6
=
3
,
d7
=
2
;
74
75
LiquidCrystal
lcd
(
rs
,
en
,
d4
,
d5
,
d6
,
d7
)
;
76
77
void
setup
(
)
{
78
79
80
81
lcd
.
begin
(
16
,
2
)
;
82
83
84
85
lcd
.
print
(
"hello, world!"
)
;
86
}
87
88
void
loop
(
)
{
89
90
91
92
lcd
.
noCursor
(
)
;
93
94
delay
(
500
)
;
95
96
97
98
lcd
.
cursor
(
)
;
99
100
delay
(
500
)
;
101
}
andmethods to control an underscore-style cursor.
This example sketch shows how to use the
display
(
)
and noDisplay
(
)
methods to turn on and off the display. The text to be displayed will still be preserved when you use noDisplay() so it's a quick way to blank the display without losing everything on it.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#
include
<LiquidCrystal.h>
44
45
46
47
const
int
rs
=
12
,
en
=
11
,
d4
=
5
,
d5
=
4
,
d6
=
3
,
d7
=
2
;
48
LiquidCrystal
lcd
(
rs
,
en
,
d4
,
d5
,
d6
,
d7
)
;
49
50
void
setup
(
)
{
51
52
lcd
.
begin
(
16
,
2
)
;
53
54
lcd
.
print
(
"hello, world!"
)
;
55
}
56
57
void
loop
(
)
{
58
59
lcd
.
noDisplay
(
)
;
60
delay
(
500
)
;
61
62
lcd
.
display
(
)
;
63
delay
(
500
)
;
64
}
andmethods to turn on and off the display. The text to be displayed will still be preserved when you use noDisplay() so it's a quick way to blank the display without losing everything on it.
This example sketch shows how to use the
scrollDisplayLeft
(
)
and scrollDisplayRight
(
)
methods to reverse the direction the text is flowing. It prints "Hello World!", scrolls it offscreen to the left, then offscreen to the right, then back to home.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#
include
<LiquidCrystal.h>
44
45
46
47
const
int
rs
=
12
,
en
=
11
,
d4
=
5
,
d5
=
4
,
d6
=
3
,
d7
=
2
;
48
LiquidCrystal
lcd
(
rs
,
en
,
d4
,
d5
,
d6
,
d7
)
;
49
50
void
setup
(
)
{
51
52
lcd
.
begin
(
16
,
2
)
;
53
54
lcd
.
print
(
"hello, world!"
)
;
55
delay
(
1000
)
;
56
}
57
58
void
loop
(
)
{
59
60
61
for
(
int
positionCounter
=
0
;
positionCounter
<
13
;
positionCounter
++
)
{
62
63
lcd
.
scrollDisplayLeft
(
)
;
64
65
delay
(
150
)
;
66
}
67
68
69
70
for
(
int
positionCounter
=
0
;
positionCounter
<
29
;
positionCounter
++
)
{
71
72
lcd
.
scrollDisplayRight
(
)
;
73
74
delay
(
150
)
;
75
}
76
77
78
79
for
(
int
positionCounter
=
0
;
positionCounter
<
16
;
positionCounter
++
)
{
80
81
lcd
.
scrollDisplayLeft
(
)
;
82
83
delay
(
150
)
;
84
}
85
86
87
delay
(
1000
)
;
88
89
}
andmethods to reverse the direction the text is flowing. It prints "Hello World!", scrolls it offscreen to the left, then offscreen to the right, then back to home.
This example sketch accepts serial input from a host computer and displays it on the LCD. To use it, upload the sketch, then open the Serial Monitor and type some characters and click Send. The text will appear on your LCD.
1
/*
2
LiquidCrystal Library - Serial Input
3
4
Demonstrates the use a 16x2 LCD display. The LiquidCrystal
5
library works with all LCD displays that are compatible with the
6
Hitachi HD44780 driver. There are many of them out there, and you
7
can usually tell them by the 16-pin interface.
8
9
This sketch displays text sent over the serial port
10
(e.g. from the Serial Monitor) on an attached LCD.
11
12
The circuit:
13
* LCD RS pin to digital pin 12
14
* LCD Enable pin to digital pin 11
15
* LCD D4 pin to digital pin 5
16
* LCD D5 pin to digital pin 4
17
* LCD D6 pin to digital pin 3
18
* LCD D7 pin to digital pin 2
19
* LCD R/W pin to ground
20
* 10K resistor:
21
* ends to +5V and ground
22
* wiper to LCD VO pin (pin 3)
23
24
Library originally added 18 Apr 2008
25
by David A. Mellis
26
library modified 5 Jul 2009
27
by Limor Fried (http://www.ladyada.net)
28
example added 9 Jul 2009
29
by Tom Igoe
30
modified 22 Nov 2010
31
by Tom Igoe
32
modified 7 Nov 2016
33
by Arturo Guadalupi
34
35
This example code is in the public domain.
36
37
http://www.arduino.cc/en/Tutorial/LiquidCrystalSerialDisplay
38
39
*/
40
41
// include the library code:
42
#include <LiquidCrystal.h>
43
44
// initialize the library by associating any needed LCD interface pin
45
// with the arduino pin number it is connected to
46
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
47
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
48
49
void setup() {
50
// set up the LCD's number of columns and rows:
51
lcd.begin(16, 2);
52
// initialize the serial communications:
53
Serial.begin(9600);
54
}
55
56
void loop() {
57
// when characters arrive over the serial port...
58
if (Serial.available()) {
59
// wait a bit for the entire message to arrive
60
delay(100);
61
// clear the screen
62
lcd.clear();
63
// read all the available characters
64
while (Serial.available() > 0) {
65
// display each character to the LCD
66
lcd.write(Serial.read());
67
}
68
}
69
}
This example sketch shows how to use the
setCursor
(
)
method to reposition the cursor. To move the cursor, just call setCursor
(
)
with a row and column position. For example, for a 2x16 display:1
lcd
.
setCursor
(
0
,
0
)
;
2
lcd
.
setCursor
(
15
,
0
)
;
3
lcd
.
setCursor
(
0
,
1
)
;
4
lcd
.
setCursor
(
15
,
1
)
;
method to reposition the cursor. To move the cursor, just callwith a row and column position. For example, for a 2x16 display:
Here is the full example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#
include
<LiquidCrystal.h>
67
68
69
70
71
const
int
rs
=
12
,
en
=
11
,
d4
=
5
,
d5
=
4
,
d6
=
3
,
d7
=
2
;
72
73
LiquidCrystal
lcd
(
rs
,
en
,
d4
,
d5
,
d6
,
d7
)
;
74
75
76
77
78
const
int
numRows
=
2
;
79
80
const
int
numCols
=
16
;
81
82
void
setup
(
)
{
83
84
85
86
lcd
.
begin
(
numCols
,
numRows
)
;
87
}
88
89
void
loop
(
)
{
90
91
92
93
for
(
int
thisLetter
=
'a'
;
thisLetter
<=
'z'
;
thisLetter
++
)
{
94
95
96
97
for
(
int
thisRow
=
0
;
thisRow
<
numRows
;
thisRow
++
)
{
98
99
100
101
for
(
int
thisCol
=
0
;
thisCol
<
numCols
;
thisCol
++
)
{
102
103
104
105
lcd
.
setCursor
(
thisCol
,
thisRow
)
;
106
107
108
109
lcd
.
write
(
thisLetter
)
;
110
111
delay
(
200
)
;
112
113
}
114
115
}
116
117
}
118
}
This example sketch shows how to use the
leftToRight
(
)
and rightToLeft
(
)
methods. These methods control which way text flows from the cursor.rightToLeft
(
)
causes text to flow to the left from the cursor, as if the display is right-justified.leftToRight
(
)
causes text to flow to the right from the cursor, as if the display is left-justified.andmethods. These methods control which way text flows from the cursor.
This sketch prints
a
through l
right to left, then m
through r
left to right, then s
through z
right to left again.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#
include
<LiquidCrystal.h>
67
68
69
70
71
const
int
rs
=
12
,
en
=
11
,
d4
=
5
,
d5
=
4
,
d6
=
3
,
d7
=
2
;
72
73
LiquidCrystal
lcd
(
rs
,
en
,
d4
,
d5
,
d6
,
d7
)
;
74
75
int
thisChar
=
'a'
;
76
77
void
setup
(
)
{
78
79
80
81
lcd
.
begin
(
16
,
2
)
;
82
83
84
85
lcd
.
cursor
(
)
;
86
}
87
88
void
loop
(
)
{
89
90
91
92
if
(
thisChar
==
'm'
)
{
93
94
95
96
lcd
.
rightToLeft
(
)
;
97
98
}
99
100
101
102
if
(
thisChar
==
's'
)
{
103
104
105
106
lcd
.
leftToRight
(
)
;
107
108
}
109
110
111
112
if
(
thisChar
>
'z'
)
{
113
114
115
116
lcd
.
home
(
)
;
117
118
119
120
thisChar
=
'a'
;
121
122
}
123
124
125
126
lcd
.
write
(
thisChar
)
;
127
128
129
130
delay
(
1000
)
;
131
132
133
134
thisChar
++
;
135
}
throughright to left, thenthroughleft to right, thenthroughright to left again.
This example demonstrates how to add custom characters on an LCD display.
Note that this example requires an additional potentiometer:
This potentiometer controls the
delayTime
variable.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#
include
<LiquidCrystal.h>
45
46
47
48
const
int
rs
=
12
,
en
=
11
,
d4
=
5
,
d5
=
4
,
d6
=
3
,
d7
=
2
;
49
LiquidCrystal
lcd
(
rs
,
en
,
d4
,
d5
,
d6
,
d7
)
;
50
51
52
byte
heart
[
8
]
=
{
53
0b00000
,
54
0b01010
,
55
0b11111
,
56
0b11111
,
57
0b11111
,
58
0b01110
,
59
0b00100
,
60
0b00000
61
}
;
62
63
byte
smiley
[
8
]
=
{
64
0b00000
,
65
0b00000
,
66
0b01010
,
67
0b00000
,
68
0b00000
,
69
0b10001
,
70
0b01110
,
71
0b00000
72
}
;
73
74
byte
frownie
[
8
]
=
{
75
0b00000
,
76
0b00000
,
77
0b01010
,
78
0b00000
,
79
0b00000
,
80
0b00000
,
81
0b01110
,
82
0b10001
83
}
;
84
85
byte
armsDown
[
8
]
=
{
86
0b00100
,
87
0b01010
,
88
0b00100
,
89
0b00100
,
90
0b01110
,
91
0b10101
,
92
0b00100
,
93
0b01010
94
}
;
95
96
byte
armsUp
[
8
]
=
{
97
0b00100
,
98
0b01010
,
99
0b00100
,
100
0b10101
,
101
0b01110
,
102
0b00100
,
103
0b00100
,
104
0b01010
105
}
;
106
107
void
setup
(
)
{
108
109
lcd
.
begin
(
16
,
2
)
;
110
111
112
lcd
.
createChar
(
0
,
heart
)
;
113
114
lcd
.
createChar
(
1
,
smiley
)
;
115
116
lcd
.
createChar
(
2
,
frownie
)
;
117
118
lcd
.
createChar
(
3
,
armsDown
)
;
119
120
lcd
.
createChar
(
4
,
armsUp
)
;
121
122
123
lcd
.
setCursor
(
0
,
0
)
;
124
125
126
lcd
.
print
(
"I "
)
;
127
lcd
.
write
(
byte
(
0
)
)
;
128
lcd
.
print
(
" Arduino! "
)
;
129
lcd
.
write
(
(
byte
)
1
)
;
130
131
}
132
133
void
loop
(
)
{
134
135
int
sensorReading
=
analogRead
(
A0
)
;
136
137
int
delayTime
=
map
(
sensorReading
,
0
,
1023
,
200
,
1000
)
;
138
139
lcd
.
setCursor
(
4
,
1
)
;
140
141
lcd
.
write
(
3
)
;
142
delay
(
delayTime
)
;
143
lcd
.
setCursor
(
4
,
1
)
;
144
145
lcd
.
write
(
4
)
;
146
delay
(
delayTime
)
;
147
}
variable.
If you have any questions on LCD Working Principle. We will give the professional answers to your questions.