Part

Character LCD with I2C backpack

The same two rows on four wires, through the PCF8574 backpack at 0x27. Mind the backlight bit.

or see every part
  • 4 pins
  • 2 properties
Drawn live by the editor's own code, at the size you see it.
Reference

Every one of its 4 pins

Pin
What it does
GND
VCC
SDA
SCL
This part

What it does

This is the 16x2 character LCD with a PCF8574 backpack on the back, which turns sixteen pins into four: SDA, SCL, power and ground. The display itself is the same HD44780 controller as the plain module, with its character shapes in ROM, so a sketch sends characters rather than pixels. The backpack is an eight-bit port expander wired to the controller’s control lines, four data lines and the backlight, and every byte the board sends appears on those pins. That has one famous consequence, modeled here: the backlight is a single bit in that byte, and a driver that forgets it gets a display that works and cannot be read. The address is 0x27 by default and is a property, since some backpacks answer at 0x3F. The LiquidCrystal_I2C calls tutorials use compile on every board, and on an Uno they use A4 and A5.

How to use it

How to use an I2C LCD with an Arduino

SDA to A4, SCL to A5, VCC to 5 V, GND to GND. Create a LiquidCrystal_I2C with the address and the size, call init() and backlight() in setup(), and print. If the screen stays empty, the address is the first suspect: most backpacks answer at 0x27 and some at 0x3F.

To update a number without flicker, overwrite the line and pad it with spaces rather than calling clear() every time.

Part pin
Board pin
SDA
A4
SCL
A5
VCC
5 V
GND
GND

LiquidCrystal_I2C compiles on every board here, on whichever pins Wire.begin() uses on that board.

Arduino Uno: I2C LCD thermometerlive0.000 s 0.00x
Click to open it in the editor
This is the simulator itself, running here. Click anything to open it in the editor.
A first I2C LCD sketch
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);

void setup() {
  lcd.init();
  lcd.backlight();
  lcd.print("Hello, world!");
}

void loop() {}
Reference

The 2 properties you can set

Property
Default
What it means
address
39
contrast
0.75
How it is modeled

What is true about the Character LCD with I2C backpack, here

Not modeled

Reads of any kind. The busy flag, the address counter and DDRAM read back nothing, so a driver that polls the busy flag instead of waiting will hang. Wait instead; that is what every real library does anyway. Also not modeled: the 5x10 font a one-line module can select, and the viewing angle.

The busy timings are the datasheet's two typical numbers (37 microseconds for a write and 1.52 milliseconds for clear and home), used as exact values. A real HD44780's timing scales with whatever its internal oscillator happens to be running at, so those figures move by tens of percent between parts and with temperature, and the 4-bit nibble timing (the minimum E pulse width and the hold after it) is not checked here at all: a driver can clock E as fast as it likes.

A byte arriving while the controller is busy is dropped. That is a choice the model makes so the fault is visible and repeatable; on a real part the outcome is undefined and more often a corrupted character than a lost one.

On the backpack, the PCF8574 never stretches the clock and acknowledges every byte sent to it. There is no read of the expander's port, no NACK and no bus error of any kind, and the backlight transistor is bit 3 and nothing else: no current, no brightness. Contrast on the backpack is a property rather than the trimmer's actual divider.

See it: Thermometer on an I2C LCD for the backpack, and Thermometer in the templates for the six-wire hookup.

If an I2C LCD stays blank, shows blocks or prints leftovers, Arduino I2C LCD not working goes through the causes by symptom.

From The 16x2 character LCD, in full.

Projects

See the Character LCD with I2C backpack in a project

Shown here on: Arduino Uno R3, ESP32-C3-DevKitM-1

Wire up the Character LCD with I2C backpack

Open the editor and push it into the breadboard. It is free, and it runs on your own machine.