Introduction: LCD Display I2C Adapter for Arduino With PCF8574A

Picture of LCD Display I2C Adapter for Arduino With PCF8574A

Using LCD display with arduino needs many I/O lines of your microcontroller. Never again with the I2C adapter !!!

In this tutorial I've used a PCF8574A shift register I2C interfaced. The advantages are: it's cheap and on the web is available a library written for our purposes.

Step 1: What Will You Need

Skills necessary for this tutorial are:

- basic knoweldege in electronic prototyping, including soldering

- basic programming knoweldege

The materials for this instructable are:

- 1x PCF8574A (or PCF8574)

- 1x LCD display HD44780

- straight female headers

- 1x 16 pin IC socket

- 1x BC548B npn transistor

- 1x 4.7K potentiometer

- 1x stripboard 5x7cm

Step 2: Schematic

Picture of Schematic


using I2C communication protocol implies giving an address to your device. The components suitables for our project are:

PCF8574 -> address 0x20

PCF8574A - > address 0x38

I'm using the second, so you'll retrive 0x38 in the software.

These address work if PCF's address pins are shorted to ground. If you need to use another address please refer to datasheet.

Step 3: Build It !

Picture of Build It !

So let's do it ! I've built it on a stripboard, but a perfoboard works fine too.

The result shud apear like the photo. Messy. Very messy.

Test it using a tester in short circuit mode (same as diode test, the tester beeps when current can flow) and the cover the back with dutch tape.

Step 4: Connections

Connect vcc to +5V, GND to ground, SDA and SCL to arduino pins (I'm using arduino uno, so A4 and A5).

If you are using other arduinos, such as Mega, find out I2C pins on this page

Step 5: Software

Picture of Software

Download and add in your IDE the library LiquidCrystal_I2C.h from

restart the IDE and upload this test code



//create an object called lcd, with address 0x38, wich is a display with 4 lines and 20 chars per line

LiquidCrystal_I2C lcd(0x38,20,4);

void setup()




lcd.print("20x4 LCD I2C adapter");


void loop()





SMALL ISSUE: I've used a npn transistor for backlight, the library is written for a pnp transistor. This means that the command lcd.setBaclight(LOW) turns the backlight on and lcd.setBacklight(HIGH) switchs the backlight off.

It's not a big issue, and it's easy to change in header file of library. Do it if you can.

Step 6: Done !

Congratulations, you're done !

Now you can interface your display via I2C with 127 other devices using only 2 wires

Hope you liked it



ZainulD (author)2017-06-29

Hi there,

does this lib work for 16x2 lcd? I have a pcf 8574 AT with a hex address 0x38. But when i print on lcd it doesnt budge beyond first letter.

taratata2015 (author)2017-06-08

in your simulation Proteus, you use PCF8574T. i have NXP PCF8574A and not find it on libraries Proteus. have you idea please

uge02 (author)taratata20152017-06-09

The only thing that matters is the address. For PCF8574A should still be 0x38, but check the datasheet

taratata2015 (author)uge022017-06-10

i find the solution - thks - my prob is solved with the same file version 7 on vers. 8 of proteus.

GurukarthikK (author)2017-02-05

I am getting error, that is using PCF 8574 with LCD ,
Error 1:wire.h is not in library
Error 2:serial connection is detected

Dagui (author)2017-02-03

Nice job, thank you so much man !

SaadNukeEng. (author)2016-06-08
Fix to single character problem (doesn't print more than one character as it happens with newer arduino IDE's):

Open up the LiquidCrystal_I2C.cpp in a text editor

Go to the line 229

You should find a block of code like this:

inline size_t LiquidCrystal_I2C::write(uint8_t value) {
send(value, Rs);
return 0;

Edit the line "return 0;" by replacing 0 with 1

The new code may look this this:

inline size_t LiquidCrystal_I2C::write(uint8_t value) {
send(value, Rs);
return 1;

Compile and voila!

merta1 made it! (author)2016-05-19

I have different problem. this is when I write lcd.print("hello"); then it writes only h.


#include <Wire.h>

#include <LiquidCrystal_I2C_PCF8574.h>

// Adapted from :

LiquidCrystal_I2C_PCF8574 lcd(0x27,20,4); // set the LCD address to 0x27 for a 20 chars and 4 line display

void setup()


lcd.init(); // initialize the lcd

// Print a message to the LCD.


lcd.print("Hello, world!");


void loop()



buffle made it! (author)2016-05-13

So i made it, but with some changes:

1)I used another modification of the chip PCF8574AN(Texas Instruments) and

transistor BC548B.

2) used pull-up resistors on next legs: SCL, SDA 10 kOhm to +5v. Without it was no connection between the i2C extender and my Arduino micro.

3) 330Ohm pull-up resistor between +5V and transistor Base. without it the backlight doesnt work. The transistor doesnt allow enough current, to get it on. When proofing with a LED, it was ok.

on the perfoard are some extra components(LED's and temp sensor) mounted.

My Sketch, may be it help's somebody:

#include <Wire.h>
#include <LiquidCrystal_I2C.h> //to get this working i use fmalpartida's NewLiquidCrystal library.

#define LCD_I2C_ADDR 0x38

#define LCD_EN 4

#define LCD_RW 5

#define LCD_RS 6

#define LCD_D4 0

#define LCD_D5 1

#define LCD_D6 2

#define LCD_D7 3

LiquidCrystal_I2C lcd(LCD_I2C_ADDR,LCD_EN,LCD_RW,LCD_RS,LCD_D4,LCD_D5,LCD_D6,LCD_D7,7,POSITIVE);// here are the pins defined.

void setup()


lcd.begin (16,2);
lcd.clear(); //
for(int i = 0; i< 3; i++) // too proof the backlight it blinks three times. when not neeed just add some //







lcd.backlight(); // finish with backlight on

void loop()

vandenbrande (author)2016-01-26

Yes i had not visual text... i thought about the driver/address right away

See the image i added. Im sure more people will have this problem.

vandenbrande (author)2016-01-26

If you have a PCF8574AT IC2, Adress is 0x3F, for those who have a problem with not seeing anything. To find your number look at the black CHIP of the IC2.

PCF8574 -> address 0x20

PCF8574A - > address 0x38

PCF8574AT -> address 0x3F

Just change this code if you have the PCF8574AT

#define I2C_ADDR 0x3F

uge02 (author)vandenbrande2016-01-26

Well, since I had another model I don't know, but what you're saying makes sense. Anyway, these infos can be retrived on the datasheet

vandenbrande (author)uge022016-01-26

Yes i had no screen.. but i had this before... it was a small Hygrometer project for a friend i did. But i had no visual text. So i thought about the Driver right away.. and i was right. I got this image with all addresses

vandenbrande (author)uge022016-01-26

Yes i had no screen.. but i had this before... it was a small Hygrometer project for a friend i did. But i had no visual text. So i thought about the Driver right away.. and i was right. I got this image with all addresses

AlexandreI3 (author)2015-12-12


Thanks for the explanations, although I've done everything as you said, my lcd doesn't print anything, I managed to get a '0' in a corner after a while though. Also, if I leave the 'lcd.print' line in the voidloop, I get a blinking screen.

Any ideas ?

uge02 (author)AlexandreI32015-12-12

Can you please post the sketch you downloaded into the arduino?

Anyway, since you managed to obtain a zero written on the display means that the address of the chip is correct.
lcd.print in loop cause blinking because is in loop, which means that in every loop cycle Arduino cancel the row and rewrite it (causing blinking)

AlexandreI3 (author)uge022015-12-19

Hi, Thanks for your answer, I managed to solve the problem in the end, but I don't really know how.

Rob van Staalduinen (author)2015-09-03

Now i know how to use it. Thanks

uge02 (author)2015-04-15

Hello Gene,

sincerly I have no idea of how the library works. You can do three things:

1) contact the author of the library asking for help
2) try to modify the library on your own (is the pro's way, do you know what are you doing ?)
3) change the physical connections to match mine

if I were you, i would try the second, but depends from your programming skills. TIP: I've not seen inside the library, but PCF8574 is a shift register, if you swap MSB (most significant bit) and LSB (less significant bit) probably you're done.
Try looking for MSBFIRST or LSBFIRST in the code

If your pinout is different because you bought a commecial module as adafruit's, try to contact the producer

gene.jackson.712 (author)2015-03-26

I have an LCD with a PCF8574. But the 8 bit port is reversed: p0=RS, p1=RW, p2=E; p4=d4, p5=d5, p6=d6, p7=d7.

How do I make the change in software to make it work?

uge02 (author)2014-03-24

sure I know ! U can buy for some dollars in China via ebay ... But I prefer build mine !


wfoster6 (author)2014-03-23

nice tutorial, but just in case you did not know adafruit sells them for $10 each .

About This Instructable



More by uge02:LCD display I2C adapter for Arduino with PCF8574A
Add instructable to: