Project tutorial
Interface a 16x2 Character LCD

Interface a 16x2 Character LCD © GPL3+

Add an LCD to your projects to display data acquired from sensors, display your own custom characters, or use it as a debugging tool.

  • 2 views
  • 0 comments
  • 0 respects

Components and supplies

Necessary tools and machines

Apps and online services

About this project

Introduction

Having an LCD (Liquid Crystal Display) as part of your design offers many benefits. It can be used to display data acquired from sensors, create an interactive menu, or as a debugging tool. You can even create your own custom characters to display! In this project, we’ll be interfacing a 16×2 character LCD (in 4-bit mode) to the Arduino Uno Rev3 (Uno). This will require 6 digital output pins from the Uno to drive the LCD (4 pins for data and 2 pins for control).

Liquid Crystal Display (LCD)

The LCD consists of 16 pins that are used for power, control, and data. It uses an industry standard Hitachi controller so the basic operation is similar across different vendors that sell them. They have both a 4-bit parallel and an 8-bit parallel interface. We’ll be using it in 4-bit mode instead of 8-bit. That means we have to send the higher nibble (1 nibble = 4 bits) first, then the lower nibble to send the byte of data required for each command or character. The most common LCD is a 16×2 or a 20×4 which means that it can display 16 characters on each of its 2 lines and 20 characters on each of its 4 lines, respectively. A pinout of the LCD is below.

NOTE: The LCD does not come with a 16-pin male header so you’ll have to solder one on.

Pin 1 and pin 2 are used to power the LCD and should be connected to GND and +5Vdc, respectively. Pin 3 is used to adjust the contrast – this will be connected to a 10KΩ potentiometer (pot) so the output voltage to pin 3 can be varied. The Register Select (RS) on pin 4 is used to either send commands when it is low, or data when it is high. Pin 5 is for Read/Write (R/W) and is used to read or write data from the LCD. The LCD has the capability to execute a program and display information which justifies the need for this pin. However, we will only be writing to the LCD, so we can ground this pin which will place it permanently in write mode. The next eight pins (7-14) are used to send the data. Since we’re using the LCD in 4-bit mode, D0-D3 (pins 7-10) are not used. Pins 15 and 16 are the anode and cathode of the LED backlight, respectively. We will need to use an external resistor in series with this backlight to limit the current. Otherwise, the LED could burn out.

The LCD has a timing diagram that must be followed to be able to send commands and character data. There are also set-up and hold times which also must be taken into account. This allows the signal levels to settle and ensure that pins are sampled at the right time. The diagram below shows the timing diagram for sending a command to the LCD in 4-bit mode. If we want to send the command to clear the display, we have to send 0000 (upper nibble) on the data bus and then send 0001 (lower nibble) on the data bus.

The diagram below shows the timing diagram for sending data to the LCD in 4-bit mode. For example, let’s say we want to send the character 1 to the LCD. The 8-bit ASCII equivalent is 0x30 or 0011 0000, so we would send 0011 on the data bus and then 0000.

You do not have to write your own driver for the LCD since there is a library that we can use called LiquidCrystal.h. The library is simple to use and allows us to input the specs of the LCD such as the number of columns and rows, and whether to use a 4-bit or 8-bit interface. We can also send data and up to 19 different commands.

Wiring the LCD

We are using the Modulus Canister to mount the LCD. Please watch the video below if you are using Modulus.

Once you are done with mounting the LCD to Modulus, we can then attach the male end of each jumper wire to the Uno’s female header pins. You should have 6 jumpers: one on pins 4, 6, and 11-14. Pins 4, 6, and 11-14 of the LCD will connect to Uno pins 2, 3, and 4-7, respectively.

If you are using a breadboard, a high-level schematic is shown below. We will be supplying +5V and GND to the breadboard via the FuelCan, which is described further in the next section.

FuelCan Wiring

If you haven’t mounted the Uno onto the prototyping area of the FuelCan, go ahead and do that. If you are using a breadboard instead of Modulus, place the breadboard in the bottom storage compartment to limit the length of the jumper wires. You’ll need to supply +5V and GND to the power and ground rails on the breadboard by using the provided banana jack to test-lead clip cables. You will need two male header pins to mount the test-lead clips on the breadboard side. Plug the Type A side of the USB cable into USB1 receptacle and the Type B side into the Uno’s receptacle. Plug in the AC-DC power adapter to power up the FuelCan.

Software

Once the wiring is complete and the FuelCan is powered up, we can now load the sketch onto the Uno. The sketch is below. The LiquidCrystal library contains nineteen different functions that you can use. We don’t show you all of them, but we show the most commonly used ones such as lcd.print, lcd.clear, lcd.home, lcd.createChar, lcd.write, lcd.setCursor, lcd.blink, lcd.noBlink, lcd.cursor, lcd.noCursor, lcd.scrollDisplayLeft, and lcd.scrollDisplayRight. We even display a custom character on the LCD!

Code

Interface a 16x2 Character LCDArduino
//Interface a 16x2 character LCD in 4-bit mode

#include <LiquidCrystal.h>

const int RS = 2, EN = 3, D4 = 4, D5 = 5, D6 = 6, D7 = 7;
LiquidCrystal lcd(RS,EN,D4,D5,D6,D7);             //set Uno pins that are connected to LCD, 4-bit mode
//LiquidCrystal lcd(RS,EN,D1,D2,D3,D4,D5,D6,D7);  //set Uno pins that are connected to LCD, 8-bit mode

//create custom character, each character is 5x8 (WxH) pixels
byte thumbsup0[8] = {B00100,B00011,B00100,B00011,B00100,B00011,B00010,B00001};
byte thumbsup1[8] = {B00000,B00000,B00000,B00000,B00000,B00000,B00000,B00011};
byte thumbsup2[8] = {B00000,B00000,B00000,B00000,B00000,B00000,B00001,B11110};
byte thumbsup3[8] = {B00000,B01100,B10010,B10010,B10001,B01000,B11110,B00000};
byte thumbsup4[8] = {B00010,B00010,B00010,B00010,B00010,B01110,B10000,B00000};
byte thumbsup5[8] = {B00000,B00000,B00000,B00000,B00000,B10000,B01000,B00110};

void setup() {
  lcd.begin(16,2);    //set 16 columns and 2 rows of 16x2 LCD
  //lcd.begin(20,4);    //set 20 columns and 4 rows of 20x4 LCD 

}

void loop() {
  lcd.print("Hello World");             //print "Hello World" on first row
  delay(3000);                          //delay 3 seconds
  lcd.clear();                          //clear display, sets cursor back to home
  lcd.print("Fuel Your Creativity");    //notice how "Creativity" does not wrap around to next line
  delay(3000);
  lcd.clear();
  lcd.print("Fuel Your");
  lcd.setCursor(0,1);                   //set cursor to column 0, row 1 (rows and columns start from 0)
  lcd.print("Creativity");
  delay(3000);
  lcd.clear();
  lcd.cursor();                         //show visible cursor below next char that will be printed
  delay(3000);
  lcd.noCursor();                       //turns cursor off
  delay(3000);
  lcd.blink();                          //similar to lcd.cursor but creates blinking block cursor
  delay(3000);
  lcd.noBlink();                        //turn blinking cursor off
  delay(3000);
  lcd.print("Fuel Your Creativity");
  delay(3000);
  lcd.scrollDisplayLeft();              //moves "Fuel Your Creativity" to the left by one character
  delay(1000);
  lcd.scrollDisplayLeft();    
  delay(1000);
  lcd.scrollDisplayLeft();    
  delay(1000);
  lcd.scrollDisplayLeft();    
  delay(1000);
  lcd.scrollDisplayRight();             //moves "Fuel Your Creativity" to the right by one character
  delay(1000);
  lcd.scrollDisplayRight();    
  delay(1000);
  lcd.scrollDisplayRight();    
  delay(1000);
  lcd.scrollDisplayRight();    
  delay(3000);
  lcd.clear();

  //display thumbsup character
  lcd.createChar(0, thumbsup0);
  lcd.createChar(1, thumbsup1);
  lcd.createChar(2, thumbsup2);
  lcd.createChar(3, thumbsup3);
  lcd.createChar(4, thumbsup4);
  lcd.createChar(5, thumbsup5);
  lcd.setCursor(2,1);
  lcd.write((uint8_t)0);
  lcd.setCursor(2,0);
  lcd.write(1);
  lcd.setCursor(3,1);
  lcd.write(2);
  lcd.setCursor(3,0);
  lcd.write(3);
  lcd.setCursor(4,1);
  lcd.write(4);
  lcd.setCursor(4,0);
  lcd.write(5);
  delay(3000);
  lcd.clear();

}

Schematics

Interfacing the LCD to the Arduino Uno
Lcd circuit schematic 4wk9k6zuh6

Comments

Similar projects you might like

Using 16x2 LCD with Arduino

by Techmirtz

  • 31,155 views
  • 7 comments
  • 42 respects

Easily Wire a 16x2 LCD

Project showcase by ThomTronics

  • 3,740 views
  • 0 comments
  • 12 respects

16x2 LCD Backpack with Enclosure for the Onion Omega

Project in progress by Carlos Silva

  • 4,585 views
  • 5 comments
  • 18 respects

MAX 30102 Heart Rate Monitor on 16x2 LCD

Project tutorial by Mirko Pavleski

  • 2,239 views
  • 3 comments
  • 1 respect

Temperature Monitor with DHT22 and I2C 16x2 LCD

Project tutorial by adrakhmat

  • 2,738 views
  • 3 comments
  • 15 respects

Arduino DTH22 Humidity Temperature With LCD I2C 16x2 Display

Project tutorial by Team GiftedMedia

  • 42,425 views
  • 17 comments
  • 52 respects
Add projectSign up / Login