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


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 !

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

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()



lcd.print(" @instructables.com");


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


in your simulation Proteus, you use PCF8574T. i have NXP PCF8574A and not find it on libraries Proteus. have you idea please
<p>The only thing that matters is the address. For PCF8574A should still be 0x38, but check the datasheet</p>
<p>i find the solution - thks - my prob is solved with the same file version 7 on vers. 8 of proteus.</p>
I am getting error, that is using PCF 8574 with LCD ,<br>Error 1:wire.h is not in library<br>Error 2:serial connection is detected
<p>Nice job, thank you so much man !</p>
Fix to single character problem (doesn't print more than one character as it happens with newer arduino IDE's):<p>Open up the <strong>LiquidCrystal_I2C.cpp </strong>in a text editor</p><p>Go to the line 229</p><p>You should find a block of code like this:</p><blockquote><strong>inline</strong> size_t <strong>LiquidCrystal_I2C::write</strong>(uint8_t value) {<br><strong>send</strong>(value, Rs);<br><strong>return</strong> 0;<br>}<br></blockquote><p>Edit the line &quot;return 0;&quot; by replacing 0 with 1</p><p>The new code may look this this:</p><blockquote><strong>inline</strong> size_t <strong>LiquidCrystal_I2C::write</strong>(uint8_t value) {<br><strong>send</strong>(value, Rs);<br><strong>return</strong> 1;<br>}</blockquote><p>Compile and voila!</p>
<p>I have different problem. this is when I write lcd.print(&quot;hello&quot;); then it writes only h.</p><p>code:</p><p>#include &lt;Wire.h&gt; </p><p>#include &lt;LiquidCrystal_I2C_PCF8574.h&gt;</p><p>// Adapted from : <a href="http://hmario.home.xs4all.nl/arduino/LiquidCrystal_I2C/" rel="nofollow"> http://hmario.home.xs4all.nl/arduino/LiquidCrysta...</a></p><p>LiquidCrystal_I2C_PCF8574 lcd(0x27,20,4); // set the LCD address to 0x27 for a 20 chars and 4 line display</p><p>void setup()</p><p>{</p><p> lcd.init(); // initialize the lcd </p><p> // Print a message to the LCD.</p><p> lcd.backlight();</p><p> lcd.print(&quot;Hello, world!&quot;);</p><p>}</p><p>void loop()</p><p>{</p><p>}</p>
<p>So i made it, but with some changes:</p><p>1)I used another modification of the chip PCF8574AN(Texas Instruments) and</p><p>transistor BC548B.</p><p>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.</p><p>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.</p><p>on the perfoard are some extra components(LED's and temp sensor) mounted.</p><p>My Sketch, may be it help's somebody:</p><p>#include &lt;Wire.h&gt;<br> #include &lt;LiquidCrystal_I2C.h&gt; //to get this working i use fmalpartida's NewLiquidCrystal library.<br><br> #define LCD_I2C_ADDR 0x38 <br><br> #define LCD_EN 4 <br><br> #define LCD_RW 5 <br><br> #define LCD_RS 6 <br><br> #define LCD_D4 0 <br><br> #define LCD_D5 1 <br><br> #define LCD_D6 2 <br><br> #define LCD_D7 3 <br><br>#define BACKLIGHT_PIN 7<br> 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.<br><br> <br><br> void setup()<br> <br> {<br><br> lcd.begin (16,2);<br> lcd.clear(); //<br> for(int i = 0; i&lt; 3; i++) // too proof the backlight it blinks three times. when not neeed just add some //<br><br>{<br><br>lcd.backlight();<br><br>delay(250);<br><br>lcd.noBacklight();<br><br>delay(1000);<br><br>}<br><br>lcd.backlight(); // finish with backlight on <br> }<br><br> void loop()</p>
<p>Yes i had not visual text... i thought about the driver/address right away</p><p>See the image i added. Im sure more people will have this problem.</p>
<p>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.</p><p>PCF8574 -&gt; address 0x20</p><p>PCF8574A - &gt; address 0x38</p><p>PCF8574AT -&gt; address 0x3F</p><p>Just change this code if you have the PCF8574AT</p><p>#define I2C_ADDR 0x3F</p>
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
<p>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</p>
<p>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</p>
<p>Hi, </p><p>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.</p><p>Any ideas ?</p>
<p>Can you please post the sketch you downloaded into the arduino?</p><p>Anyway, since you managed to obtain a zero written on the display means that the address of the chip is correct. <br>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)</p>
<p>Hi, Thanks for your answer, I managed to solve the problem in the end, but I don't really know how.</p>
<p>Now i know how to use it. Thanks</p>
<p>Hello Gene,</p><p>sincerly I have no idea of how the library works. You can do three things:</p><p>1) contact the author of the library asking for help<br>2) try to modify the library on your own (is the pro's way, do you know what are you doing ?)<br>3) change the physical connections to match mine</p><p>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.<br>Try looking for MSBFIRST or LSBFIRST in the code </p><p>If your pinout is different because you bought a commecial module as adafruit's, try to contact the producer</p>
<p>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.</p><p>How do I make the change in software to make it work?</p>
<p>sure I know ! U can buy for some dollars in China via ebay ... But I prefer build mine !</p><p>Bye</p>
<p>nice tutorial, but just in case you did not know adafruit sells them for $10 each .</p><p>http://www.adafruit.com/products/292 </p>

About This Instructable



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