Skip to content
LCD

16x2 Character LCD with I2C Backpack

The classic 16x2 text display made simple with I2C — just 4 wires and you're up and running.

The LCD1602 is a 16-column, 2-row character LCD built around the ubiquitous HD44780 controller. On its own it needs a dozen wires and a contrast potentiometer, which is why almost every one sold today comes glued to a small PCF8574 I2C backpack — that backpack absorbs all of it into 4 pins (power, ground, and two I2C lines) and gives you an onboard trimmer for contrast.

It only displays fixed-width text characters (plus up to 8 custom 5x8 glyphs you can define yourself), not arbitrary graphics — for anything pixel-addressable, look at a graphic display like the SSD1306 OLED instead. But for status readouts, menus, sensor value displays, and simple UIs, it's the cheapest and most reliable text display in the hobbyist ecosystem, and the exact same library and code scale straight up to the larger LCD2004 (20x4) — see the variants table below.

Specifications

Display16 characters × 2 lines, fixed-width text (HD44780 controller)
BackpackPCF8574 I2C I/O expander (converts the LCD's 6-wire parallel interface to I2C)
Operating voltage5V DC (most common); some 3.3V-tolerant backpacks exist but are less common
I2C address0x27 default on most PCF8574 backpacks, 0x3F on some clones — scan to confirm
InterfaceI2C, up to 100 kHz typical
BacklightLED backlight, on/off controllable over I2C
Custom charactersUp to 8 user-defined 5×8 pixel glyphs

Pinout

PinNameDescription
1GNDGround
2VCCPower, 5V DC
3SDAI2C data line
4SCLI2C clock line

The PCF8574 backpack already includes its own I2C pull-up resistors, tied to whatever you feed VCC — same consideration as any other I2C breakout with onboard pull-ups. Most backpacks are 5V parts and the display itself needs 5V to hit full contrast/brightness, so on 3.3V-only boards (ESP32, Raspberry Pi, STM32) you'll typically power VCC from a 5V rail while still wiring SDA/SCL through a level shifter or accepting that the I2C lines will sit at 5V — check your specific board's I2C pin tolerance before skipping a level shifter. If characters look like solid black blocks or are invisible, adjust the small blue potentiometer on the back of the backpack — that's a contrast issue, not a wiring or code fault. If nothing shows up on the bus at all, run an I2C scanner sketch first to confirm the actual address, since 0x27 vs 0x3F varies by manufacturer.

Variants

The I2C backpack version is the one to buy for almost every project — it trades a few cents and a tiny bit of address-lookup hassle for going from 6+ wires down to 4. If a project needs more visible text at once (multi-field status screens, small menus, logs), the LCD2004 uses the exact same library and code, just with 20x4 instead of 16x2 passed to the constructor.

VariantTemp rangeHum rangeAccuracyProtocolPrice
LCD1602 I2C~$2–4
LCD2004 I2C~$4–7
LCD1602 (parallel, no backpack)~$1–3

Board Integration

Library

LiquidCrystal I2Cby Frank de Brabander

Arduino IDE → Tools → Manage Libraries → search "LiquidCrystal I2C" by Frank de Brabander → Install

Wiring

Component pinBoard pinNote
VCC5V
GNDGND
SDAA4Uno's hardware I2C data pin.
SCLA5Uno's hardware I2C clock pin.

Code

C++

Notes

  • If the backlight is on but no text appears, adjust the contrast potentiometer on the back of the backpack before assuming it's a code problem.
  • lcd.print() does not auto-wrap or clear the line first — always pad with trailing spaces (as in the example) if a new value might be shorter than the old one, or you'll see leftover characters.
  • Run an I2C scanner sketch once if lcd.init() doesn't seem to do anything - confirm the address is actually 0x27 before debugging further.