42 – The I2C bus and LCD displays




    • Understand the I2C bus.
    • Connect a I2C LCD display.
    • Send messages to the display.


Bill of materials

Arduino UNO

Arduino Uno or equivalent. This chapter accepts any other Arduino board.


A solderless Breadboard.

Jumper wires

Some jumper wires.

330 Ohm resistor

 A 330 Ω resistor.

16x2 LCD Display

A 16×2 or 20×4 I2C LCD display.

The I2C bus


As the integration capacity to place thousands or millions of transistors on a single chip increased, the number of commercial components available, increased exponentially. Each time it was, and it is, easier to manufacture electronic building blocks integrated on a single chip, and soon the thickness of the catalogs of the manufacturers, fattened dangerously.

It was relatively easy to find those building blocks but when you design required to use a dozen of these blocks, to assemble them together and get them to communicate effectively became a problem.

Therefore, in the early 80s, one of the largest electronics manufacturers (Phillips), proposed a digital communication standard between the different components of an electronic system.

It was an open standard that specified the speed rate, voltage levels and the protocol to follow in order to establish that communication.

That standard was called Inter Integrated Circuits bus, or IIC, and soon became a de facto standard in the industry. The specifications have been improving over the years, but the basic idea remains the same:

  • A two wire protocol, one to transmit data, SDA (Serial DAta), and one asynchronous clock, SCL (Serial CLock), to indicate when data is read. Apart from GND and 5V (when required).
  • Each device connected to the I2C bus has its own 7 bits unique address, so, in theory, we can connect up to 27 = 128 devices.
  • One of these devices must act as master, that is, it controls the clock.
  • The clock speed is not required, since it is the master who controls the clock.
  • The bus is multi master, that is, the master can change, but only one can be active at a time, and provides a arbitration and collision detection protocol. (If you have not understood this, do not worry, it’s still early).

The I2C bus can be also called IIC, I2C, and TWI (Two Wire Interface, or 2-wire interface), but it is always the same.

I2C Bus diagram

The idea is that all devices are connected in parallel to the two bus lines, SDA and SCL. At a time there can only be a master, in this case, our Duino and so the others are configured as slaves.

  • There may be more than one master device. The standard proposes an arbitration system to transfer control from one to another, but at a given time, only one can be the master.
  • Note that there are also some pull-up resistors connected to SDA and SCL. They are mandatory, since the bus is active at low level (that is, the active signal is a 0, not a 1. Don’t worry, it doesn’t matter).
  • When you connect something to the I2C bus, it is essential to read its data sheet before to find out whether the pull-up resistors are already attached to the device or you have to place them yourself.
  • In the case of the I2C display that we are going to use, it typically includes the pull-up resistors.

And the good piece of news is that our Arduino supports a standard library, which uses two of the analog pins for SDA (data) and SCL (Clock) functions.

  • In the Arduino UNO, the I2C pins are the analog pins A4 (SDA) and A5 (SCL).
  • In the Arduino Mega and DUE they are the pins 20 (SDA) and 21 (SCL).

The I2C library is called Wire library in Arduino and manages the complete communication protocol, which is a nice gesture, because it saves us the boring part of studying the protocol and write the sketch to handle it.

  • This is not laziness, but to build on the work of others. It is one of the very great virtues of the Arduino community because it has many libraries available to incorporate in our projects without getting our hands dirty.

In this chapter we will connect a 16 × 2 I2C LCD display, so you can check why in the last chapter we recommended to use it, rather than connecting it directly using 16 wires.

But first, we need to take care of another matter.




Each component connected to the I2C bus has a unique address, and each message or order transmitted to the bus includes this address, indicating which of the many possible, is the recipient of the message.

But, of course, this implies that we should know beforehand the address of each device. Typically, we should check the technical information of the device’s manufacturer, and that usually tell us which is the default address.

But as we know, in life things don’t happen as in the fairy tales, some charitable soul (and with a lot of background on his shoulders) made a little sketch for Arduino, which informs us of what is in our bus and in what direction it is moving:


Naturally, this program has no idea of which is the device that answers the call or what it does, but it is good enough to know that there is some device in the address xx.

If we do not know which is the address of a given device, we can simply place it alone on the bus and see which is the address reported by the I2C scanner. The result for the LCD I am dealing with is 0x27 Hexadecimal.

I2C_scan screen


So now we can move on to talk about how to program the display.



The connection is again trivial:
Chapter 42, wiring diagram

We simply connect the analog pin A4 of Arduino to SDA (Data) and the pin A5 to SCL (Clock), apart from GND and 5V. We keep on with the program.




First you have to download a new library to be able to use the I2C display, called LiquidCrystal_I2C. This is an upgrade of the standard library that is built in your Arduino IDE (keep calm, it does not hurt and should be automatic).

I have not found any information about the author or authors, I have only seen one reference to the library name, Malpartida.

Download the library:


Let’s install it first. So go to:

\\Sketch\Include library\Add .ZIP library...

Search the library LiquidCrystal_I2C.zip in your download directory and double click on it to install it in your IDE.

Now let’s include the I2C library, called Wire in the Arduino IDE, and follow these steps. Go to:

\\Sketch\Include library\Wire

Now we must include the LiquidCrystal library and then the LiquidCrystal_I2C. We should see the following three lines in the sketch:

#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

We are going to define a variable that holds the address of our device. In our case the address is 0x27.

byte dir = 0x27   // This 0x means that it is an hexadecimal number, not a decimal one

And at last we create an instance on the LiquidCrystal_I2C object:

LiquidCrystal_I2C             lcd( dir, 2, 1, 0, 4, 5, 6, 7);

When we create the lcd object we pass it the display address, dir, and several numbers that indicate which pins of the display should use the library (these are not Arduino pins). Ignore it and copy. The rest is as follows:

Sketch 42.1
#include <Wire.h>

#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#define I2C_ADDR    0x27
LiquidCrystal_I2C  lcd(I2C_ADDR,2, 1, 0, 4, 5, 6, 7);
void setup()
       lcd.begin (16,2);              // Initialize the display with 16 columns and 2 rows

       lcd.home ();                   // go home
       lcd.setCursor ( 0, 1 );        // go to the 2nd line
       lcd.print("Malpartida lib");
void loop() 

Here you have the result:

I2C LCD display example





    • We have introduced the 16×2 I2C LCD displays.
    • They work the same as the normal ones, but they require far fewer wires to connect them and lots of problems are avoided.
    • They are very practical and cost a little more than a normal one.






No Comments

Give a Reply