Inquire: Call 0086-755-23203480, or reach out via the form below/your sales contact to discuss our design, manufacturing, and assembly capabilities.
Quote: Email your PCB files to Sales@pcbsync.com (Preferred for large files) or submit online. We will contact you promptly. Please ensure your email is correct.
Notes: For PCB fabrication, we require PCB design file in Gerber RS-274X format (most preferred), *.PCB/DDB (Protel, inform your program version) format or *.BRD (Eagle) format. For PCB assembly, we require PCB design file in above mentioned format, drilling file and BOM. Click to download BOM template To avoid file missing, please include all files into one folder and compress it into .zip or .rar format.
I2C LCD Arduino: Reduce Wiring with PCF8574 Adapter
Anyone who has connected a standard 16×2 LCD to an Arduino knows the frustration of dealing with a mess of wires. You need at least six digital pins just for the display, and your breadboard starts looking like a bird’s nest. The I2C LCD Arduino combination solves this problem elegantly by reducing those connections down to just two data lines plus power.
In this comprehensive guide, I’ll walk you through everything you need to know about using an I2C LCD with Arduino, from understanding how the PCF8574 adapter works to writing advanced code with custom characters and scrolling text. As someone who has designed numerous PCBs with character LCDs, I can tell you that the I2C interface is the way to go for almost every project.
What is an I2C LCD and Why Should You Use It?
An I2C LCD is simply a standard HD44780-compatible character LCD (like the common 16×2 or 20×4 displays) with an I2C adapter module attached to its back. This adapter, typically based on the PCF8574 chip, converts the parallel data interface of the LCD into a serial I2C protocol.
The traditional way of connecting an LCD to Arduino requires 4 data pins, plus RS, Enable, and optionally RW pins for a total of 6-7 connections. Add in VCC, GND, and contrast adjustment, and you’re looking at a lot of wiring. The I2C LCD Arduino setup replaces all those data and control lines with just two wires: SDA (Serial Data) and SCL (Serial Clock).
Benefits of Using I2C LCD with Arduino
Feature
Standard LCD
I2C LCD
Data Pins Required
4-8
0
Control Pins Required
2-3
0
I2C Pins Required
0
2 (shared)
Total Arduino Pins Used
6-12
2
Wiring Complexity
High
Low
Multiple Displays
Difficult
Easy (different addresses)
The real beauty of I2C is that those two data lines can be shared with other I2C devices like sensors, EEPROMs, or real-time clock modules. You could theoretically have dozens of I2C devices on the same bus, each with a unique address.
Understanding the PCF8574 I2C Adapter Module
The heart of any I2C LCD adapter is the PCF8574 chip, manufactured by both NXP (formerly Philips) and Texas Instruments. This clever IC is an 8-bit I/O expander that converts I2C serial commands into parallel signals.
How the PCF8574 Works
When your Arduino sends data over the I2C bus, the PCF8574 receives it and sets its 8 output pins accordingly. The adapter board routes these outputs to the LCD’s data pins (D4-D7 in 4-bit mode), as well as the RS, RW, Enable, and backlight control lines.
The communication happens in nibbles (4 bits at a time) because the LCD operates in 4-bit mode when used with this adapter. For each character or command you want to send, the Arduino actually transmits multiple I2C bytes to toggle the Enable line and clock the data into the LCD controller.
PCF8574 Module Features
Component
Function
PCF8574/PCF8574T IC
I2C to parallel conversion
Blue Potentiometer
LCD contrast adjustment
Backlight Jumper
Enable/disable LED backlight
A0, A1, A2 Solder Pads
I2C address configuration
16-Pin Header
Connects directly to LCD
Most modules you’ll encounter use either the PCF8574 or PCF8574T chip with a default I2C address of 0x27. Some modules use the PCF8574A variant, which has a different address range starting at 0x38. This distinction becomes important when troubleshooting communication issues.
I2C LCD Arduino Wiring Diagram
Connecting an I2C LCD to Arduino is remarkably simple. You only need four wires total.
I2C LCD Pinout
I2C LCD Pin
Arduino UNO Pin
Description
GND
GND
Ground connection
VCC
5V
Power supply (5V)
SDA
A4
I2C Data line
SCL
A5
I2C Clock line
I2C Pin Locations on Different Arduino Boards
Different Arduino boards have their I2C pins in different locations. Here’s a quick reference:
Arduino Board
SDA Pin
SCL Pin
Arduino UNO
A4
A5
Arduino Nano
A4
A5
Arduino Mega 2560
20
21
Arduino Leonardo
2
3
Arduino Due
20
21
ESP32
GPIO 21
GPIO 22
ESP8266
GPIO 4 (D2)
GPIO 5 (D1)
On newer Arduino UNO boards with the R3 pinout, you’ll also find dedicated SDA and SCL pins near the AREF pin, which are internally connected to A4 and A5.
Finding Your I2C LCD Address
Before writing any display code, you need to know your LCD’s I2C address. Most modules ship with either 0x27 or 0x3F as the default address, but this can vary by manufacturer. The safest approach is to scan for it.
I2C Scanner Code
Upload this sketch to find all I2C devices connected to your Arduino:
#include <Wire.h>
void setup() {
Wire.begin();
Serial.begin(9600);
while (!Serial);
Serial.println(“\nI2C Scanner”);
}
void loop() {
byte error, address;
int deviceCount = 0;
Serial.println(“Scanning…”);
for (address = 1; address < 127; address++) {
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0) {
Serial.print(“I2C device found at address 0x”);
if (address < 16) Serial.print(“0”);
Serial.print(address, HEX);
Serial.println(” !”);
deviceCount++;
}
}
if (deviceCount == 0)
Serial.println(“No I2C devices found\n”);
else
Serial.println(“Scan complete\n”);
delay(5000);
}
Open the Serial Monitor at 9600 baud after uploading. You should see output like “I2C device found at address 0x27 !” which tells you the address to use in your LCD code.
Installing the LiquidCrystal_I2C Library
The standard Arduino LiquidCrystal library doesn’t support I2C communication. You’ll need to install a dedicated library for I2C LCD displays.
Installation Steps
Open the Arduino IDE
Go to Sketch → Include Library → Manage Libraries
Search for “LiquidCrystal I2C”
Find the library by Frank de Brabander
Click Install
This library provides functions nearly identical to the standard LiquidCrystal library, making it easy to adapt existing code for I2C displays.
Basic I2C LCD Arduino Code Example
Once you have the library installed and know your I2C address, displaying text is straightforward.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 16, 2);
void setup() {
// Initialize the LCD
lcd.init();
// Turn on the backlight
lcd.backlight();
// Print a message to the LCD
lcd.setCursor(0, 0);
lcd.print(“Hello, World!”);
lcd.setCursor(0, 1);
lcd.print(“I2C LCD Works!”);
}
void loop() {
// Nothing needed here for static display
}
The LiquidCrystal_I2C lcd(0x27, 16, 2) line creates an LCD object with the I2C address (0x27), number of columns (16), and number of rows (2). Adjust these parameters to match your display.
LiquidCrystal_I2C Library Functions Reference
The library provides numerous functions for controlling the display. Here’s a comprehensive reference:
Function
Description
lcd.init()
Initialize the LCD display
lcd.backlight()
Turn on the backlight
lcd.noBacklight()
Turn off the backlight
lcd.clear()
Clear the display and move cursor to home
lcd.home()
Move cursor to top-left corner
lcd.setCursor(col, row)
Position the cursor
lcd.print(data)
Print text or numbers
lcd.write(byte)
Write a single character
lcd.cursor()
Show the cursor
lcd.noCursor()
Hide the cursor
lcd.blink()
Enable blinking cursor
lcd.noBlink()
Disable blinking cursor
lcd.display()
Turn on the display
lcd.noDisplay()
Turn off the display (data preserved)
lcd.scrollDisplayLeft()
Scroll content left
lcd.scrollDisplayRight()
Scroll content right
lcd.createChar(num, data)
Create custom character
Displaying Sensor Data on I2C LCD
One of the most common uses for an I2C LCD Arduino project is displaying sensor readings. Here’s an example that shows temperature from an analog sensor:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
const int tempPin = A0;
void setup() {
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print(“Temperature:”);
}
void loop() {
int sensorValue = analogRead(tempPin);
float voltage = sensorValue * (5.0 / 1023.0);
float temperature = (voltage – 0.5) * 100; // For TMP36
lcd.setCursor(0, 1);
lcd.print(” “); // Clear the line
lcd.setCursor(0, 1);
lcd.print(temperature, 1);
lcd.print(” C”);
delay(1000);
}
Creating Custom Characters for I2C LCD
Character LCDs support up to 8 custom characters stored in CGRAM (Character Generator RAM). Each character is defined as an 8-byte array representing a 5×8 pixel grid.
Custom Character Example
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Define custom characters
byte heart[8] = {
0b00000,
0b01010,
0b11111,
0b11111,
0b11111,
0b01110,
0b00100,
0b00000
};
byte smiley[8] = {
0b00000,
0b00000,
0b01010,
0b00000,
0b10001,
0b01110,
0b00000,
0b00000
};
void setup() {
lcd.init();
lcd.backlight();
// Create custom characters
lcd.createChar(0, heart);
lcd.createChar(1, smiley);
// Display custom characters
lcd.setCursor(0, 0);
lcd.write(0); // Heart
lcd.print(” Custom Chars “);
lcd.write(1); // Smiley
}
void loop() {
}
You can use online custom character generators to create the byte arrays visually rather than calculating them manually.
Scrolling Text on I2C LCD Arduino
For messages longer than the display width, scrolling text provides an elegant solution.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
String scrollText = “This is a long scrolling message for the I2C LCD display! “;
void setup() {
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print(“Scrolling Demo:”);
}
void loop() {
for (int position = 0; position < scrollText.length(); position++) {
lcd.setCursor(0, 1);
// Display 16 characters starting from current position
for (int i = 0; i < 16; i++) {
int charPos = (position + i) % scrollText.length();
lcd.print(scrollText.charAt(charPos));
}
delay(300);
}
}
PCF8574 I2C Address Configuration
The PCF8574 has three address pins (A0, A1, A2) that allow you to configure up to 8 different I2C addresses. This is essential when using multiple LCD displays on the same I2C bus.
PCF8574 Address Table
A2
A1
A0
I2C Address
Open
Open
Open
0x27
Open
Open
Bridged
0x26
Open
Bridged
Open
0x25
Open
Bridged
Bridged
0x24
Bridged
Open
Open
0x23
Bridged
Open
Bridged
0x22
Bridged
Bridged
Open
0x21
Bridged
Bridged
Bridged
0x20
PCF8574A Address Table
The PCF8574A variant has a different address range:
A2
A1
A0
I2C Address
Open
Open
Open
0x3F
Open
Open
Bridged
0x3E
Open
Bridged
Open
0x3D
Open
Bridged
Bridged
0x3C
Bridged
Open
Open
0x3B
Bridged
Open
Bridged
0x3A
Bridged
Bridged
Open
0x39
Bridged
Bridged
Bridged
0x38
To change the address, locate the solder pads on your adapter module and bridge them with a small blob of solder. Open pads are pulled HIGH by internal pull-up resistors, while bridged pads are pulled to ground.
Using Multiple I2C LCDs with Arduino
With different I2C addresses, you can easily control multiple displays from a single Arduino.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Create two LCD objects with different addresses
LiquidCrystal_I2C lcd1(0x27, 16, 2);
LiquidCrystal_I2C lcd2(0x26, 16, 2);
void setup() {
lcd1.init();
lcd1.backlight();
lcd2.init();
lcd2.backlight();
lcd1.setCursor(0, 0);
lcd1.print(“Display 1”);
lcd2.setCursor(0, 0);
lcd2.print(“Display 2”);
}
void loop() {
}
Note that powering multiple LCD displays may exceed the Arduino’s 5V regulator capacity. For projects with multiple displays, consider using an external 5V power supply.
I2C LCD Arduino Troubleshooting Guide
When your I2C LCD doesn’t work as expected, work through these common issues systematically.
Problem: Blank Screen (Backlight On)
Cause 1: Wrong I2C address Run the I2C scanner sketch to find the correct address. Update your code accordingly.
Cause 2: Contrast not adjusted Turn the blue potentiometer on the I2C adapter slowly while watching the display. You should see character blocks appear when the contrast is correct.
Cause 3: Wrong library Make sure you’re using the LiquidCrystal_I2C library by Frank de Brabander. Multiple libraries with similar names exist, and they may have different function names.
Problem: Display Shows Blocks/Garbage
Cause 1: Initialization timing Add a small delay at the start of setup() before calling lcd.init() to ensure the LCD has powered up completely.
Cause 2: Loose connections Check that all four wires (VCC, GND, SDA, SCL) are securely connected.
Problem: I2C Scanner Finds No Devices
Cause 1: Wiring error Double-check that SDA connects to A4 and SCL connects to A5 on Arduino UNO. Verify your board’s I2C pin locations if using a different model.
Cause 2: Missing pull-up resistors Most I2C LCD modules have built-in pull-up resistors, but some don’t. If your module lacks them, add 4.7kΩ pull-ups between SDA/VCC and SCL/VCC.
Cause 3: Defective module Try a different I2C device on the same pins to verify your Arduino’s I2C hardware is working.
Problem: Intermittent Display Corruption
Cause 1: Power supply issues The LCD backlight draws significant current. Use a dedicated 5V supply rather than the Arduino’s onboard regulator for more stable operation.
Cause 2: Long wires acting as antennas Keep I2C wires as short as possible. For longer runs, reduce the I2C clock speed or add additional pull-up resistors.
Useful Resources for I2C LCD Arduino Projects
Resource
Description
LiquidCrystal_I2C Library (GitHub)
Frank de Brabander’s library source code
HD44780 Datasheet
LCD controller documentation
PCF8574 Datasheet
I2C I/O expander documentation
Custom Character Generator
Online tool for creating character byte arrays
Arduino Wire Library Reference
Official I2C library documentation
Arduino Forum – Displays Section
Community troubleshooting and project ideas
Frequently Asked Questions About I2C LCD Arduino
What is the default I2C address for LCD displays?
Most I2C LCD modules using the PCF8574 chip have a default address of 0x27, while those using the PCF8574A variant default to 0x3F. However, this can vary by manufacturer, so always run an I2C scanner sketch to confirm the address before writing display code. The address depends on the state of the A0, A1, and A2 pins on the chip.
Why is my I2C LCD showing a blank screen even though the backlight is on?
A blank screen with backlight typically indicates one of three issues: incorrect I2C address in your code, improper contrast adjustment, or wrong library. First, run the I2C scanner to verify the address. Then, slowly rotate the blue potentiometer on the adapter until you see character blocks appear. Finally, ensure you’re using the LiquidCrystal_I2C library by Frank de Brabander, as other libraries may use different function names.
Can I connect multiple I2C LCD displays to one Arduino?
Yes, you can connect up to 8 I2C LCDs to a single Arduino by giving each display a unique address. Modify the address by soldering the A0, A1, and A2 pads on the adapter module. You could theoretically connect up to 16 displays by mixing PCF8574 (0x20-0x27) and PCF8574A (0x38-0x3F) based modules. Keep in mind that powering multiple displays may require an external 5V power supply.
Do I need pull-up resistors for the I2C LCD?
Most I2C LCD adapter modules include built-in pull-up resistors on the SDA and SCL lines, so you typically don’t need to add external ones. However, if your module lacks these resistors or if you experience communication issues, adding 4.7kΩ pull-up resistors between SDA and 5V, and between SCL and 5V, can improve signal integrity, especially with longer wires.
How do I adjust the contrast on an I2C LCD?
The I2C adapter module has a small blue potentiometer (trimmer) on the back. Use a small screwdriver to rotate it while the display is powered. Turn it slowly until you see the character blocks or text become clearly visible. If you turn it too far in either direction, the display may appear either too dark or completely washed out. The correct setting is usually somewhere in the middle of the potentiometer’s range.
Conclusion
The I2C LCD Arduino combination is one of the most practical upgrades you can make to any project that requires a character display. By reducing the pin count from 6-12 down to just 2 shared I2C lines, you free up valuable GPIO pins for sensors, actuators, and other peripherals.
The PCF8574 adapter module handles all the complexity of converting serial I2C data into the parallel signals the LCD controller expects. Combined with the LiquidCrystal_I2C library, you get nearly the same programming interface as standard LCDs but with dramatically simplified wiring.
Whether you’re building a temperature monitor, a menu-driven interface, or just want to display status messages, the I2C LCD delivers reliable performance with minimal complexity. Start with the basic examples in this guide, then explore custom characters and scrolling text to make your displays more engaging.
For any project where board space and pin availability matter, the I2C LCD is simply the smarter choice compared to parallel-connected displays.
Inquire: Call 0086-755-23203480, or reach out via the form below/your sales contact to discuss our design, manufacturing, and assembly capabilities.
Quote: Email your PCB files to Sales@pcbsync.com (Preferred for large files) or submit online. We will contact you promptly. Please ensure your email is correct.
Notes: For PCB fabrication, we require PCB design file in Gerber RS-274X format (most preferred), *.PCB/DDB (Protel, inform your program version) format or *.BRD (Eagle) format. For PCB assembly, we require PCB design file in above mentioned format, drilling file and BOM. Click to download BOM template To avoid file missing, please include all files into one folder and compress it into .zip or .rar format.