How to Use a 16x2 LCD with Arduino Without I2C

The classic blue 16x2 LCD is one of the most useful beginner Arduino components. It displays 16 characters per row on 2 rows and is ideal for measurements, menus, messages and project status. This lesson starts with how the display works, then explains all 16 pins and immediately moves to Arduino's LiquidCrystal library.

Required components:

  • 1x Arduino UNO
  • 1x 16x2 LCD display (No I2C)
  • 1x 10kΩ potentiometer
  • Jumper wires (and an optional breadboard)

Display Image

LCD display Photo

How a 16x2 LCD works

Most 16x2 modules use an HD44780-compatible controller. Arduino does not drive every pixel directly: it sends the controller commands and data. Commands clear the display or move the cursor, while data represents the characters to show.

The controller stores character positions in memory and automatically generates the dot patterns for letters and numbers. It can use an 8-bit or 4-bit data bus. Arduino projects normally use 4-bit mode because it saves four I/O pins.

What all 16 pins do

Pin 1 - VSS

LCD ground: connect it to GND.

Pin 2 - VDD

Positive supply. Common Arduino UNO modules are normally connected to 5 V.

Pin 3 - VO

Controls contrast. Connect it to the center terminal of an approximately 10 kΩ potentiometer, with the two outer terminals connected to 5 V and GND.

Pin 4 - RS

Register Select: tells the LCD whether Arduino is sending a command or character data.

Pin 5 - R/W

Selects read or write mode. Beginner circuits normally tie it to GND and only write to the display.

Pin 6 - E

Enable: a pulse tells the controller to accept the data on the bus.

Pins 7-10 - D0, D1, D2, D3

The four lower data bits. They are not used in 4-bit mode and can remain unconnected.

Pins 11-14 - D4, D5, D6, D7

The four data pins used in 4-bit mode. Arduino sends each byte as two groups of four bits.

Pin 15 - A / LED+

Backlight positive. Many modules include a resistor, but not all do, so check your specific module before powering the LED directly.

Pin 16 - K / LED-

Backlight negative, normally connected to GND.

4-bit wiring with Arduino UNO

LCD display Pinout
  • VSS → GND
  • VDD → 5V
  • VO → potentiometer center terminal
  • RS → pin 2
  • R/W → GND
  • E → pin 3
  • D4 → pin 4
  • D5 → pin 5
  • D6 → pin 6
  • D7 → pin 7
  • A / LED+ → backlight supply according to the module
  • K / LED- → GND

D0-D3 remain unconnected. You can choose other Arduino pins as long as the same numbers are changed in the sketch.

Arduino LiquidCrystal library

The parallel display uses Arduino's LiquidCrystal library, normally included with the IDE. The line LiquidCrystal lcd(2, 3, 4, 5, 6, 7); lists RS, E, D4, D5, D6 and D7 in that order.

First sketch: write on both rows

lcd_16x2.ino
// https://nemiatools.com
#include <LiquidCrystal.h>

// RS, E, D4, D5, D6, D7
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);

void setup() {{
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("Hello Arduino!");
  lcd.setCursor(0, 1);
  lcd.print("NEMIA TOOLS");
}}

void loop() {{
}}

lcd.begin(16, 2) initializes a 16-column, 2-row display. lcd.setCursor(column, row) selects a position; the first column and first row both use index 0.

Most useful LiquidCrystal commands

  • lcd.print() prints text and numbers.
  • lcd.setCursor() selects the writing position.
  • lcd.clear() clears the display.
  • lcd.home() returns the cursor to the beginning.
  • lcd.cursor() and lcd.noCursor() show or hide the cursor.
  • lcd.blink() and lcd.noBlink() control cursor blinking.
  • lcd.scrollDisplayLeft() and lcd.scrollDisplayRight() scroll the display.

Example: display a changing value

lcd_counter.ino
// https://nemiatools.com
#include <LiquidCrystal.h>

LiquidCrystal lcd(2, 3, 4, 5, 6, 7);

void setup() {{
  lcd.begin(16, 2);
  lcd.print("Power on:");
}}

void loop() {{
  lcd.setCursor(0, 1);
  lcd.print(millis() / 1000);
  lcd.print(" s    ");
  delay(200);
}}

The spaces after s erase characters left by an earlier, longer value. Avoid calling lcd.clear() continuously in the loop because that can make the display flicker.

Custom characters

HD44780-compatible controllers can store up to 8 custom characters at once. This allows simple 5x8-dot icons such as a battery or thermometer.

Common problems

Only black rectangles: the LCD has power but is probably not initialized; check RS, E and D4-D7. Backlight on but no text: slowly adjust the contrast potentiometer. Random characters: check wiring, common ground and breadboard contacts.