Arduino Nano - LCD

This tutorial instructs you how to use LCD display with Arduino Nano, how to program for Arduino Nano to display text, special characters on LCD.

Hardware Preparation

1×Arduino Nano
1×USB A to Mini-B USB cable
1×LCD I2C
1×Jumper Wires
1×(Optional) 9V Power Adapter for Arduino Nano
1×(Recommended) Screw Terminal Adapter for Arduino Nano

Or you can buy the following sensor kit:

1×DIYables Sensor Kit 30 types, 69 units
Disclosure: Some of the links provided in this section are Amazon affiliate links. We may receive a commission for any purchases made through these links at no additional cost to you. We appreciate your support.

Overview of LCD I2C 16x2

LCD I2C is made up of a standard LCD, an I2C module and a potentiometer. It is highly recommended to use the LCD I2C instead of standard LCD. That is because using the LCD I2C make the wiring much easier.

The LCD Pinout

The LCD I2C uses the I2C interface to connect to Arduino Nano. It has four pins:

  • The GND pin needs to be connected to ground (0V).
  • The VCC pin is the power supply for the LCD and must be connected to VCC (5V).
  • The SDA pin is the I2C data signal.
  • The SCL pin is the I2C clock signal.
LCD I2C pinout

LCD Coordinate

The LCD I2C 16x2 has 16 columns and 2 rows, with the columns and rows being numbered starting from 0.

Arduino Nano LCD I2C coordinate

Wiring Diagram

The wiring diagram between Arduino Nano and LCD I2C

This image is created using Fritzing. Click to enlarge image

LCD I2C module Arduino Nano
Vin 5V
GND GND
SDA A4
SCL A5

How To Program For LCD I2C

The LiquidCrystal_I2C library needs to be included in order to use the LCD.

  • Set up the LCD:

The LCD must be set up properly for it to work correctly.

  • Write to the LCD:

Writing to the LCD is easy thanks to the LiquidCrystal_I2C library.

#include <LiquidCrystal_I2C.h> // Library for LCD
  • Create a LiquidCrystal_I2C object with an I2C address, the number of columns, and the number of rows specified.
LiquidCrystal_I2C lcd(0x27, 16, 2); // I2C address 0x27, 16 column and 2 rows
  • Start up the LCD.
lcd.init(); //initialize the lcd lcd.backlight(); //open the backlight
  • Go to the column and row indicated by column_index and row_index respectively.
lcd.setCursor(column_index, row_index);
  • Display a message on the LCD.
lcd.print("Hello World!");

Explore the possibilities of what can be achieved with LCD by looking at the "Do More with LCD" section.

※ NOTE THAT:

The address of the LCD may differ depending on the manufacturer. For our code, we used 0x27 as specified by DIYables.

Arduino Nano Code

#include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27, 16, 2); // I2C address 0x27, 16 column and 2 rows void setup() { lcd.init(); // Initialize the LCD I2C display lcd.backlight(); lcd.setCursor(3, 0); // move cursor to (3, 0) lcd.print("DIYables"); // print message at (3, 0) lcd.setCursor(0, 1); // move cursor to (0, 1) lcd.print("www.diyables.io"); // print message at (0, 1) } void loop() { }

Detailed Instructions

  • Click to the Libraries icon on the left bar of the Arduino IDE.
  • Search for "LiquidCrystal I2C" and locate the LiquidCrystal_I2C library created by Frank de Brabander.
  • Then, click the Install button to add the library.
Arduino Nano LiquidCrystal I2C library
  • Copy the code and open it with the Arduino IDE.
  • Click the Upload button in the IDE to send the code to the Arduino Nano.
  • Check the LCD for the result.
Arduino Nano display text on LCD
  • Experiment with altering the text and its location.

Video Tutorial

Do More with LCD

Custom Character

lcd.print() only works with ASCII characters. To display a special character or symbol (e.g. heart, angry bird), you must use the character generator.

An LCD 16x2 can show up to 32 characters. Each character is made up of 40 pixels, which are arranged in 8 rows and 5 columns.

Arduino Nano LCD 16x2 Pixel

The character generator creates a character that is 40 pixels in size. To use it, simply follow these steps:

Click on each pixel to select/deselect


Copy below custom character code
Replace the customChar[8] in the below code
#include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27, 16, 2); // I2C address 0x27, 16 column and 2 rows byte customChar[8] = { 0b00000, 0b01010, 0b11111, 0b11111, 0b01110, 0b00100, 0b00000, 0b00000 }; void setup() { lcd.init(); // Initialize the LCD I2C display lcd.backlight(); lcd.createChar(0, customChar); // create a new custom character lcd.setCursor(2, 0); // move cursor to (2, 0) lcd.write((byte)0); // print the custom char at (2, 0) } void loop() { }

The LCD showed the result. The result was displayed on the LCD.

LCD custom character

Multiple custom characters

We are able to make a maximum of 8 custom characters, numbered from 0 to 7. The example below shows how to create and display three of them.

#include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27, 16, 2); // I2C address 0x27, 16 column and 2 rows byte customChar0[8] = { 0b00000, 0b01010, 0b11111, 0b11111, 0b01110, 0b00100, 0b00000, 0b00000 }; byte customChar1[8] = { 0b00100, 0b01110, 0b11111, 0b00100, 0b00100, 0b00100, 0b00100, 0b00100 }; byte customChar2[8] = { 0b00100, 0b00100, 0b00100, 0b00100, 0b00100, 0b11111, 0b01110, 0b00100 }; void setup() { lcd.init(); // Initialize the LCD I2C display lcd.backlight(); lcd.createChar(0, customChar0); // create a new custom character (index 0) lcd.createChar(1, customChar1); // create a new custom character (index 1) lcd.createChar(2, customChar2); // create a new custom character (index 2) lcd.setCursor(2, 0); // move cursor to (2, 0) lcd.write((byte)0); // print the custom char 0 at (2, 0) lcd.setCursor(4, 0); // move cursor to (4, 0) lcd.write((byte)1); // print the custom char 1 at (4, 0) lcd.setCursor(6, 0); // move cursor to (6, 0) lcd.write((byte)2); // print the custom char 2 at (6, 0) } void loop() { }

The outcome displayed on the LCD is: . The result that appears on the LCD is:

LCD multiple custom characters

Summary: how to use custom character on LCD

  • Employ the character generator to generate binary code for your custom character.
  • Copy the binary code generated in the previous step.
byte customChar[8] = { 0b00000, 0b01010, 0b11111, 0b11111, 0b01110, 0b00100, 0b00000, 0b00000 };
  • Assign a custom character to an index value ranging from 0 to 7 inside the setup() function.
lcd.createChar(index, customChar);
  • Print the custom character on the LCD at any time, either in the setup() or loop() function.
lcd.setCursor(column, row); // move cursor to a desired position lcd.write((byte)index); // print the custom char at the desired position

Other functions

  • Print "Hello World"

Insert the following functions into the loop() function, one at a time, with a delay of 5000 milliseconds after each:

  • Clear the LCD screen
  • Print "Hello World"
lcd.clear();
  • Screen
  • Position the cursor at the top left corner of the LCD display.
lcd.home();
  • Position the cursor at a certain column and row.
lcd.setCursor(column, row);
  • Show the LCD cursor on the screen.
lcd.cursor();
  • Makes the LCD cursor invisible.
lcd.noCursor();
  • Show the LCD cursor blinking.
lcd.blink()
  • Disable the blinking of the LCD cursor.
lcd.noBlink()

Challenge Yourself

Try using an LCD for one of these projects:

Troubleshooting on LCD I2C

  1. Rotate the potentiometer on the back of the LCD to adjust its contrast.
  2. Depending on the manufacturer, the I2C address of the LCD may be different. Generally, the default I2C address of the LCD is either 0x27 or 0x3F. Try both these values. If you are still unsuccessful, run the code below to find the I2C address.
// I2C address scanner program #include <Wire.h> void setup() { Wire.begin(); Serial.begin(9600); Serial.println("I2C Scanner"); } void loop() { byte error, address; int nDevices; Serial.println("Scanning..."); nDevices = 0; for (address = 1; address < 127; 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"); else Serial.println("done"); delay(5000); // wait 5 seconds for next scan }

The output displayed on the Serial Monitor is: . The outcome that appears on the Serial Monitor is:

COM6
Send
Scanning... I2C device found at address 0x3F ! done Scanning... I2C device found at address 0x3F ! done
Autoscroll Show timestamp
Clear output
9600 baud  
Newline