16×2 LCD Display with I2C | PCF8574 Library

Back to Blog
16x2 LCD Display with I2C | PCF8574 Library - 16x2 LCD Display with I2C | PCF8574 Library - 16x2 LCD Display with I2C | PCF8574 Library - 16x2 LCD Display with I2C | PCF8574 Library

16×2 LCD Display with I2C | PCF8574 Library

16×2 LCD is an alphanumeric display that can show up to 32 characters on a single screen. You can display more characters by scrolling the texts one by one. We have already seen how to connect LCD Display directly with the Arduino using 4bit and 8bit modes in our previous tutorial. But those two modes will utilize many numbers of GPIO Pins of our Arduino and we would have to end up with less number of pins for other sensors and actuators.

To overcome this problem we use LCD I2C backpack with our LCD. This I2C Backpack uses PCF8574 Remote 8 bit I/O Expander. It translates the data received from the I2C Bus into Parallel data that is needed for the LCD Display.

I2C – Inter-Integrated Circuit:

Inter-integrated Circuit (in short I2C) is a two-wire short distance communication protocol. You can use multiple slave devices in the same two wires with one or more master controllers. You may wonder how does the master identifies which slave does the data to be sent. In I2C the external devices have an I2C address for different external devices like LCD Backpack, OLED Display, etc. By using the address the data is sent to the specific device connected on the same I2C Bus.

The message is broken into two frames and sent serially via the I2C Bus. The first frame contains the address, once the address matches with any device on I2C bus, that device will send an acknowledge signal to the master. After receiving the acknowledgment from the slave the data bits are sent. By this method an I2C bus works.

16×2 LCD Display:

16×2 LCD means it can display 16 characters per line and there are 2 such lines. In this LCD each character is displayed in the 5×7 pixel matrix.

LCD Pinout:

There are totally 16 pins in an LCD Display. You can use directly all the pins in 8-bit mode with Arduino or 12 pins using 4-bit mode. In this tutorial, we use the I2C module for LCD and multiplex it into just 4 pins. This pin details might not be useful while using I2C Method but this is the actual pin details of all the pins in LCD Display.

Vcc – Power Supply (5v)

Vdd/GND – Ground

V0 – Brightness Control using Potentiometer

RS – Register select. Specify what we are sending Command or Data. Sets to 0 for Command mode like setCursor, LCD Clear, TurnOFF LCD. Set 1 for data mode like sending Data/Characters.

R/W – Read/Write. Mostly we are writing data/characters to the registers.

E – Enable writing to Registers.

D0 to D7 – Data pins. Send 4bit/8bit data to display characters. The Arduino library provides 4bit and 8bit mode. The data will be in ASCII format.

A/LED+ – Anode (Backlight LED)

K/LED- – Cathode (Backlight LED)

I2C Pinout:

I2C-Serial-Interface-Module-for-LCD-1602-2004-factoryforward

The LCD I2C Backpack only has 4 Pins. They are

GND – Ground

VCC – 5V Power Supply

SDA – Data Line

SCK – Clock Line

Circuit diagram:

LCD-I2C-16x2-factoryforward

The connection is simple just attach the LCD Backpack as shown in the image (Pins coming outwards). Connect

GND – Ground of Arduino

VCC – 5V Arduino Pin

SDA – SDA Pin of Arduino (mentioned in the backside of Arduino)

SCL – SCL Pin of Arduino (mentioned in the backside of Arduino)

 

Finding I2C Address of our backpack:

First, we need to find the address of our I2C LCD Backpack. For that, we will be using I2C Scanner code to display the address in the serial monitor. Upload the following code, then note down the I2C address from the serial monitor.

#include <Wire.h>
void setup()
{
  Wire.begin();

  Serial.begin(9600);
  while (!Serial);             // Leonardo: wait for serial monitor
  Serial.println("\nI2C Scanner");
}

void loop()
{
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for(address = 1; address < 127; address++ ) 
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the 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("  !");

      nDevices++;
    }
    else if (error==4) 
    {
      Serial.print("Unknown error at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");

  delay(5000);           // wait 5 seconds for next scan
}

 

In my case, it is 0x27. Node down the address displayed for you. Mostly it will be 0x27 only. In case you have another I2C device connected on the same bus it will show that address too.

Now we will be using this address on our code.

Download and Install LiquidCrystal_I2C Library:

Download .zip LiquidCrystal_I2C library by Frank de Brabander from here and Install it in IDE by navigating Sketch>Include Library>Add .zip library and choose the downloaded LiquidCrystal_I2C.zip library file.

Now the LCD I2C library is installed. We need to define and initialize the library using its associated functions. The steps is as follows. Or you can copy the code given below to print Hello World example.

 

Declare the LiquidCrystal_I2C.h library by using the following line

#include <LiquidCrystal_I2C.h>

Set the address that we copied from I2C Scanner code. The address I got is 0x27 so I replaced it to 0x27 in the following line

LiquidCrystal_I2C lcd(0x27, 16, 2);

Inside the setup function, initialize the LCD by using the following function

lcd.begin();

 

Example Code to print ‘Hello World’:

#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.begin();

 // Turn on the blacklight and print a message.
 lcd.backlight();
 lcd.print("Hello, world!");
}

void loop()
{
 // Do nothing here...
}

In the above code, we have created an LCD object for ‘LiquidCrystal_I2C’. So you can use directly use the regular LCD functions to work with I2C like lcd.begin(), lcd.print(“”), etc.

Frequently used LCD Functions:

To print a string we use lcd.print() function with string in its parameters. This prints ‘Factory’ string in the 1st row and ‘Forward’ in the 2nd row.

Important Note: The columns and rows position starts with 0th location.

Example:  7th column and 2nd row are mentioned as (6, 1).

lcd.print():

This function is used to print a message on LCD.

lcd.print("Factory"); // Prints "Factory" on first row

delay(2000); // 2 seconds delay

lcd.setCursor(column,row):

This function sets the cursor on 7th column and 2nd row. Printing the string will gets displayed from this location on LCD.

 lcd.setCursor(6,1); // Sets cursor column and row position

 lcd.print("Forward"); //Prints ‘Forward’ on 7th column of 2nd row.

lcd.clear():

The LCD will hold the previous data on its registers. You need to manually clear it using the lcd.clear() function.

lcd.clear();

Blinking Full Cursor:

By Using lcd.blink() function we can make the cursor blinking on LCD. To turn off the blinking cursor we use lcd.noBlink() function.

lcd.blink(); //Blinking cursor

lcd.noBlink();  //Turns OFF blinking cursor

Underscore Cursor:

Use lcd.cursor() function for printing an underscore symbol. It is also used for notifying users to enter some values.

lcd.cursor(); // Prints an underscore symbol

lcd.noCursor(); Clears the underscore only.

 

Share this post

Comment (1)

  • sravya

    I used this module to interface 2 displays using 1 Arduino Uno board to displaying LCD 16×2 , and graphical display interface the display but only one LCD was working is it possible using Arduino Uno board

    November 29, 2019 at 10:30 AM

Leave a Reply

Back to Blog