You are on page 1of 1

tilt

Basic Electronics Arduino ESP32 ESP8266

ARDUINO Table Of Contents


Introduction

Interface an I2C LCD with Arduino Hardware Overview


Character LCD Display
I2C LCD Adapter

I2C Address of LCD


If your LCD has TI’s PCF8574
chip:

If your LCD has NXP’s PCF8574


chip:

I2C LCD Display Pinout

Wiring an I2C LCD Display to an


Arduino

Adjusting The LCD Contrast


Library Installation

Determining the I2C Address


Basic Arduino Sketch – Hello World
Code Explanation:

Other useful functions of the


LiquidCrystal_I2C Library
Create and Display Custom Characters
Custom Character Generator

Arduino Example Code


Code Explanation:
If you’ve ever attempted to connect an LCD display to an Arduino, you’ve probably noticed
that it uses a lot of Arduino pins. Even in 4-bit mode, the Arduino requires seven connections
– half of the Arduino’s available digital I/O pins.

The solution is to use an I2C LCD display. It only uses two I/O pins that are not even part of
the digital I/O pin set and can be shared with other I2C devices.

Hardware Overview
A typical I2C LCD display consists of an HD44780-based character LCD display and an I2C
LCD adapter. Let’s learn more about them.

Character LCD Display


As the name suggests, these LCDs are ideal for displaying only characters. A 16×2 character
LCD, for example, can display 32 ASCII characters across two rows.

If you look closely, you can see tiny rectangles for each character on the screen as well as the
pixels that make up a character. Each of these rectangles is a grid of 5×8 pixels.

Please refer to our in-depth guide for more information about character LCD displays.

I2C LCD Adapter


At the heart of the adapter is an 8-bit I/O expander chip – PCF8574. This chip converts the
I2C data from an Arduino into the parallel data required for an LCD display.

The board also includes a tiny trimpot for making precise adjustments to the display’s
contrast.

There is a jumper on the board that provides power to the backlight. To control the intensity
of the backlight, you can remove the jumper and apply external voltage to the header pin
labeled ‘LED’.

I2C Address of LCD


If you have multiple devices on the same I2C bus, you may need to set a different I2C
address for the LCD adapter to avoid conflicting with another I2C device.

For this purpose, the adapter comes with three solder jumpers/pads (A0, A1, and A2). The
address is set when a jumper is shorted with a blob of solder.

An important point to note here is that several companies, including Texas Instruments and
NXP Semiconductors, manufacture the same PCF8574 chip. And the I2C address of your LCD
depends on the chip manufacturer.

If your LCD has Texas Instruments’ PCF8574 chip:


According to the Texas Instruments’ datasheet, the three address selection bits (A0, A1, and
A2) are located at the end of the 7-bit I2C address register.

Because there are three address inputs that can take on two states, either HIGH or LOW,
eight (2^3) different combinations (addresses) are possible.

All three address inputs are pulled HIGH using onboard pullups. This gives the PCF8574 a
default I2C address of 0x27.

When you short a solder jumper, you pull that address input LOW. If you were to short all
three jumpers, the address would be 0x20. So the range of all possible addresses spans from
0x20 to 0x27.

You can set a different I2C address, according to the table below.

If your LCD has NXP’s PCF8574 chip:


According to the NXP Semiconductors’ datasheet, the three address selection bits (A0, A1,
and A2) are located at the end of the 7-bit I2C address register. However, the remaining bits
in the address register are different.

Because there are three address inputs that can take on two states, either HIGH or LOW,
eight (2^3) different combinations (addresses) are possible.

All three address inputs are pulled HIGH using onboard pullups. This gives the PCF8574 a
default I2C address of 0x3F.

When you short a solder jumper, you pull that address input LOW. If you were to short all
three jumpers, the address would be 0x38. So the range of all possible addresses spans from
0x38 to 0x3F.

You can set a different I2C address, according to the table below.

So the I2C address of your LCD is most likely 0x27 or 0x3F. If you’re not sure what
your LCD’s I2C address is, there’s an easy way to figure it out. You’ll learn about
that later in this tutorial.

I2C LCD Display Pinout


The I2C LCD Display has only four pins. The following is the pinout:

GND is a ground pin.

VCC is the power supply pin. Connect it to the 5V output of the Arduino or an external 5V
power supply.

SDA is the I2C data pin.

SCL is the I2C clock pin.

Wiring an I2C LCD Display to an Arduino


Connecting an I2C LCD is much simpler than connecting a standard LCD. You only need to
connect four pins.

Begin by connecting the VCC pin to the Arduino’s 5V output and the GND pin to ground.

Now we are left with the pins that are used for I2C communication. Note that each Arduino
board has different I2C pins that must be connected correctly. On Arduino boards with the
R3 layout, the SDA (data line) and SCL (clock line) are on the pin headers close to the AREF
pin. They are also referred to as A5 (SCL) and A4 (SDA).

Check out the table below for quick reference.

SCL SDA

Arduino Uno A5 A4

Arduino Nano A5 A4

Arduino Mega 21 20

Leonardo/Micro 3 2

The diagram below shows how to connect everything.

Adjusting The LCD Contrast


After wiring the LCD, you will need to adjust the contrast of the LCD. On the I2C module,
there is a potentiometer that can be rotated with a small screwdriver.

Now, turn on the Arduino. You will see the backlight light up. As you turn the potentiometer
knob, the first row of rectangles will appear. If you have made it this far, Congratulations!
Your LCD is functioning properly.

Library Installation
Before you can proceed, you must install the LiquidCrystal_I2C library. This library allows you
to control I2C displays using functions that are very similar to the LiquidCrystal library.

To install the library, navigate to Sketch > Include Library > Manage Libraries… Wait for the
Library Manager to download the library index and update the list of installed libraries.

Filter your search by entering ‘liquidcrystal‘. Look for the LiquidCrystal I2C library by Frank
de Brabander. Click on that entry and then choose Install.

Determining the I2C Address


As previously stated, the I2C address of your LCD depends on the manufacturer. If your LCD
has a PCF8574 chip from Texas Instruments, its I2C address is 0x27; if it has a PCF8574 chip
from NXP Semiconductors, its I2C address is 0x3F.

If you’re not sure what your LCD’s I2C address is, you can run a simple I2C scanner sketch
that scans your I2C bus and returns the address of each I2C device it finds.

You can find this sketch under File > Examples > Wire > i2c_scanner.

Load the i2c_scanner sketch into your Arduino IDE.

#include <Wire.h>

void setup() {
Wire.begin();

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

void loop() {
int nDevices = 0;

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

for (byte 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);
byte error = Wire.endTransmission();

if (error == 0) {
Serial.print("I2C device found at address 0x");
if (address < 16) {
Serial print("0");

After you’ve uploaded the sketch, launch the serial monitor at 9600 baud. You should see the
I2C address of your I2C LCD display.

Please make a note of this address. You’ll need it in later examples.

Basic Arduino Sketch – Hello World


The test sketch below will print ‘Hello World!’ on the first line of the LCD and ‘LCD Tutorial’
on the second.

However, before you upload the sketch, you must make a minor change to make it work for
you. You must pass the I2C address of your LCD as well as the display dimensions to the
LiquidCrystal_I2C constructor. If you’re using a 16×2 character LCD, pass 16 and 2; if you’re
using a 20×4 character LCD, pass 20 and 4.

// enter the I2C address and the dimensions of your LCD here
LiquidCrystal_I2C lcd(0x3F, 16, 2);

Once you are done, go ahead and try the sketch.

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F,16,2); // set the LCD address to 0x3F for a 16 chars a

void setup() {
lcd.init();
lcd.clear();
lcd.backlight(); // Make sure backlight is on

// Print a message on both lines of the LCD.


lcd.setCursor(2,0); //Set cursor to character 2 on line 0
lcd.print("Hello world!");

lcd.setCursor(2,1); //Move cursor to character 2 on line 1


lcd.print("LCD Tutorial");
}

void loop() {
}

This is what you should see on the screen.

Code Explanation:
The sketch begins by including the LiquidCrystal_I2C library.

#include <LiquidCrystal_I2C.h>

The next step is to create an object of LiquidCrystal_I2C class. The LiquidCrystal_I2C


constructor accepts three inputs: I2C address, number of columns, and number of rows of the
display.

LiquidCrystal_I2C lcd(0x3F,16,2);

In the setup, three functions are called. The first function is init() . It initializes the interface
to the LCD. The second function is clear() . This function clears the LCD screen and
positions the cursor in the upper-left corner. The third function, backlight() , turns on the
LCD backlight.

lcd.init();
lcd.clear();
lcd.backlight();

The function setCursor(2, 0) is then called to move the cursor to the third column of the
first row. The cursor position specifies where you want the new text to appear on the LCD. It
is assumed that the upper left corner is col=0 and row=0 .

lcd.setCursor(2,0);

Next, the print() function is used to print “Hello world!” to the LCD.

lcd.print("Hello world!");

Similarly, the next two lines of code move the cursor to the third column of the second row
and print ‘LCD Tutorial’ to the LCD.

lcd.setCursor(2,1);
lcd.print("LCD Tutorial");

Other useful functions of the LiquidCrystal_I2C


Library
There are many useful functions you can use with LiquidCrystal_I2C Object. Some of them are
listed below:

lcd.home() function positions the cursor in the upper-left of the LCD without clearing
the display.

lcd.blink() function displays a blinking block of 5×8 pixels at the position to which
the next character will be written.

lcd.noBlink() function turns off the blinking LCD cursor.

lcd.cursor() function displays an underscore (line) at the position to which the next
character will be written.

lcd.noCursor() function hides the LCD cursor.

lcd.scrollDisplayRight() function scrolls the contents of the display one space to


the right. If you want the text to scroll continuously, you have to use this function inside a
for loop.

lcd.scrollDisplayLeft() function scrolls the contents of the display one space to the
left. Similar to the above function, use this inside a for loop for continuous scrolling.

lcd.noDisplay() function turns off the LCD display, without losing the text currently
shown on it.

lcd.display() function turns on the LCD display, after it’s been turned off with
noDisplay() . This will restore the text (and cursor) that was on the display.

Create and Display Custom Characters


If you find the default font uninteresting, you can create your own custom characters (glyphs)
and symbols. They come in handy when you need to display a character that isn’t in the
standard ASCII character set.

As previously discussed in this tutorial, a character is made up of a 5×8 pixel matrix;


therefore, you must define your custom character within this matrix. You can define a
character by using the createChar() function.

To use createChar() , you must first create an 8-byte array. Each byte in the array
corresponds to a row in a 5×8 matrix. In a byte, the digits 0 and 1 indicate which pixels in a
row should be OFF and which should be ON.

All of these user-defined characters are stored in the LCD’s CGRAM.

CGROM and CGRAM

All Hitachi HD44780 driver-based LCDs have two types of memory: CGROM and
CGRAM (Character Generator ROM and RAM).

CGROM is non-volatile memory that retains data even when the power is
removed, whereas CGRAM is volatile memory that loses data when the power is
removed.

The CGROM stores the font that appears on a character LCD. When you instruct a
character LCD to display the letter ‘A’, it needs to know which pixels to turn on so
that we see an ‘A’. This data is stored in the CGROM.

CGRAM is an additional memory for storing user-defined characters. This RAM is


limited to 64 bytes. Therefore, for a 5×8 pixel LCD, only 8 user-defined characters
can be stored in CGRAM, whereas for a 5×10 pixel LCD, only 4 can be stored.

Custom Character Generator


Creating custom characters has never been easier! We’ve developed a small application
called Custom Character Generator. Can you see the blue grid below? You can click on any
pixel to set or clear that pixel. And as you click, the code for the character is generated next
to the grid. This code can be used directly in your Arduino sketch.

byte
Character[8] =
{
0b00000,
0b00000,
0b01010,
0b11111,
0b11111,
0b01110,
0b00100,
Clear all 0b00000
};

There’s no limit to what you can create. The only limitation is that the LiquidCrystal_I2C
library only supports eight custom characters. But don’t be sad, look at the bright side; at
least we have eight characters.

Arduino Example Code


The sketch below demonstrates how to display custom characters on the LCD.

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F, 16, 2); // set the LCD address to 0x3F for a 16 char

// make some custom characters:


byte Heart[8] = {
0b00000,
0b01010,
0b11111,
0b11111,
0b01110,
0b00100,
0b00000,
0b00000
};

byte Bell[8] = {
0b00100,
0b01110,
0b01110,
0b01110,
0b11111,
0b00000,
0b00100,
0b00000
}

The output appears as shown.

Code Explanation:
After including the library and creating the LCD object, custom character arrays are defined.
The array consists of 8 bytes, with each byte representing a row in a 5×8 matrix.

This sketch contains eight custom-characters. Take, for example, the Heart[8] array. You
can see that the bits (0s and 1s) are forming the shape of a heart. 0 turns the pixel off, and 1
turns it on.

byte Heart[8] = {
0b00000,
0b01010,
0b11111,
0b11111,
0b01110,
0b00100,
0b00000,
0b00000
};

In the setup, we use the createChar() function to create a custom character. This function
accepts two parameters: a number between 0 and 7 to reserve one of the eight supported
custom characters, and the name of the array.

lcd.createChar(0, Heart);

In the loop, to display the custom character, we simply call the write() function and pass it
the number of the character we reserved earlier.

lcd.setCursor(0, 1);
lcd.write(0);

SHARE

Disclaimer Privacy Policy Contact Us

Copyright © 2023 LastMinuteEngineers.com. All rights reserved.

You might also like