Overview
The LCD1602 is a 16-character by 2-line character LCD module based on the industry-standard HD44780 controller. It is the de facto standard for adding a low-cost, low-power text display to Arduino, Raspberry Pi, ESP32, ESP8266, and PIC projects. From bench multimeters to clocks, sensor readouts, and CNC controllers, this module has been the workhorse of hobbyist electronics for decades.
This module uses a 16-pin parallel interface and runs on a single 5V rail. It can be driven in 4-bit or 8-bit mode — most projects use 4-bit mode to save on GPIO. With the right backlight current and contrast trim, characters are crisp and readable in any indoor light.
If you're tight on GPIO, pair this module with a PCF8574 I2C backpack to drop the wiring down from 16 pins to 4 (VCC, GND, SDA, SCL). Without the backpack, the module is purely parallel — the wiring guides below cover the standard 4-bit hookup.
At a Glance
Specifications
| Parameter | Value |
| Display Format | 16 characters × 2 lines |
| Character Size | 5 × 8 dots per character |
| Controller IC | HD44780 (or compatible) |
| Operating Voltage | 5V DC (typical) |
| Logic Voltage | 5V |
| Operating Current | ~1.5 mA (display) + 15-20 mA (backlight) |
| Interface | 4-bit or 8-bit parallel |
| Backlight | Yellow-green or blue with white text |
| Built-in Character Set | ASCII + Japanese kana + 8 user-defined |
| Operating Temperature | 0°C to 50°C |
| Module Dimensions | ~80 × 36 × 13 mm |
Pinout Diagram
Wiring Guide
Arduino Wiring (4-bit Mode)
The standard 4-bit hookup uses 6 GPIO lines: RS, E, and D4-D7. RW is tied to ground (write-only mode). A 10k potentiometer sets the contrast. The backlight gets a 220Ω current-limit resistor on the anode.
| LCD Pin | Arduino Pin | Details |
|---|---|---|
| 1 - VSS | GND | |
| 2 - VDD | 5V | |
| 3 - VE (V0) | Wiper of 10k pot | Pot ends to 5V and GND |
| 4 - RS | Digital 12 | |
| 5 - RW | GND | Tie low for write-only |
| 6 - E | Digital 11 | |
| 7 - D0 | Not connected | Unused in 4-bit mode |
| 8 - D1 | Not connected | Unused in 4-bit mode |
| 9 - D2 | Not connected | Unused in 4-bit mode |
| 10 - D3 | Not connected | Unused in 4-bit mode |
| 11 - D4 | Digital 5 | |
| 12 - D5 | Digital 4 | |
| 13 - D6 | Digital 3 | |
| 14 - D7 | Digital 2 | |
| 15 - A (LED+) | 5V via 220Ω resistor | Backlight anode |
| 16 - K (LED-) | GND | Backlight cathode |
ESP32 Wiring (4-bit Mode with 3.3V Logic)
ESP32 outputs 3.3V on its GPIO pins, but the LCD's HD44780 logic is 5V-tolerant on inputs. Most boards work fine with the LCD powered at 5V and driven by 3.3V GPIO directly. Power the backlight from 5V and use a 220Ω resistor.
| LCD Pin | ESP32 Pin | Details |
|---|---|---|
| 1 - VSS | GND | |
| 2 - VDD | 5V (VIN) | |
| 3 - VE | Wiper of 10k pot | Pot ends to 5V and GND |
| 4 - RS | GPIO 19 | |
| 5 - RW | GND | |
| 6 - E | GPIO 23 | |
| 11 - D4 | GPIO 18 | |
| 12 - D5 | GPIO 17 | |
| 13 - D6 | GPIO 16 | |
| 14 - D7 | GPIO 15 | |
| 15 - A | 5V via 220Ω | |
| 16 - K | GND |
Raspberry Pi Wiring (4-bit Mode)
The Raspberry Pi runs on 3.3V GPIO. The HD44780 is generally 5V-tolerant on inputs, so a direct 3.3V GPIO drive works. Power the LCD logic from 5V and the backlight from 5V via a current-limit resistor.
| LCD Pin | Raspberry Pi GPIO | Details |
|---|---|---|
| 1 - VSS | Pin 6 (GND) | |
| 2 - VDD | Pin 2 (5V) | |
| 3 - VE | Wiper of 10k pot | |
| 4 - RS | BCM 25 (Pin 22) | |
| 5 - RW | GND | |
| 6 - E | BCM 24 (Pin 18) | |
| 11 - D4 | BCM 23 (Pin 16) | |
| 12 - D5 | BCM 17 (Pin 11) | |
| 13 - D6 | BCM 27 (Pin 13) | |
| 14 - D7 | BCM 22 (Pin 15) | |
| 15 - A | 5V via 220Ω | |
| 16 - K | GND |
Raspberry Pi Pico Wiring (4-bit Mode)
The Pico is 3.3V logic but the HD44780 will accept 3.3V drive when its logic supply is 5V. Use VBUS (pin 40) as your 5V source if the Pico is powered over USB.
| LCD Pin | Pico Pin | Details |
|---|---|---|
| 1 - VSS | GND | |
| 2 - VDD | VBUS (5V) | Pin 40, 5V from USB |
| 3 - VE | Wiper of 10k pot | |
| 4 - RS | GP15 | |
| 5 - RW | GND | |
| 6 - E | GP14 | |
| 11 - D4 | GP13 | |
| 12 - D5 | GP12 | |
| 13 - D6 | GP11 | |
| 14 - D7 | GP10 | |
| 15 - A | VBUS via 220Ω | |
| 16 - K | GND |
Code Examples
Arduino
// LCD1602 16x2 LCD Display - Arduino Example
// 4-bit mode using LiquidCrystal library
// RS = 12, E = 11, D4 = 5, D5 = 4, D6 = 3, D7 = 2
#include <LiquidCrystal.h>
// (rs, enable, d4, d5, d6, d7)
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() {
// Tell the LCD it has 16 columns and 2 rows
lcd.begin(16, 2);
lcd.print("Hello, World!");
lcd.setCursor(0, 1);
lcd.print("ShillehTek LCD");
}
void loop() {
// Move the cursor and print the seconds counter on row 2
lcd.setCursor(0, 1);
lcd.print("Uptime: ");
lcd.print(millis() / 1000);
lcd.print("s ");
delay(1000);
}
Raspberry Pi (Python)
#!/usr/bin/env python3
# LCD1602 16x2 LCD Display - Raspberry Pi Example
# Uses RPLCD library: pip install RPLCD
from RPLCD.gpio import CharLCD
from RPi import GPIO
import time
lcd = CharLCD(
pin_rs=25,
pin_e=24,
pins_data=[23, 17, 27, 22],
numbering_mode=GPIO.BCM,
cols=16,
rows=2,
dotsize=8
)
try:
lcd.write_string("Hello, World!")
lcd.cursor_pos = (1, 0)
lcd.write_string("ShillehTek LCD")
while True:
lcd.cursor_pos = (1, 0)
lcd.write_string("Time: {:>4}s ".format(int(time.time()) % 10000))
time.sleep(1)
except KeyboardInterrupt:
pass
finally:
lcd.close(clear=True)
GPIO.cleanup()
Raspberry Pi Pico (MicroPython)
# LCD1602 16x2 LCD Display - Pico MicroPython Example
# Direct GPIO bit-banged 4-bit mode (no library needed).
from machine import Pin
import time
RS = Pin(15, Pin.OUT)
E = Pin(14, Pin.OUT)
D4 = Pin(13, Pin.OUT)
D5 = Pin(12, Pin.OUT)
D6 = Pin(11, Pin.OUT)
D7 = Pin(10, Pin.OUT)
def pulse_e():
E.value(1); time.sleep_us(1); E.value(0); time.sleep_us(50)
def write_nibble(value):
D4.value((value >> 0) & 1)
D5.value((value >> 1) & 1)
D6.value((value >> 2) & 1)
D7.value((value >> 3) & 1)
pulse_e()
def write_byte(value, mode_data):
RS.value(1 if mode_data else 0)
write_nibble(value >> 4)
write_nibble(value & 0x0F)
def cmd(c): write_byte(c, False); time.sleep_ms(2)
def data(c): write_byte(c, True); time.sleep_us(50)
def init_lcd():
time.sleep_ms(50)
write_nibble(0x03); time.sleep_ms(5)
write_nibble(0x03); time.sleep_us(150)
write_nibble(0x03); time.sleep_us(150)
write_nibble(0x02)
cmd(0x28) # 4-bit, 2 line, 5x8
cmd(0x0C) # display on, no cursor
cmd(0x06) # entry mode
cmd(0x01) # clear
init_lcd()
for ch in "Hello, World!":
data(ord(ch))
cmd(0xC0) # row 2
for ch in "ShillehTek LCD":
data(ord(ch))