Source: https://mokxi.com/learn/arduino-lcd-16x2
Updated: 2026-10-26

Learn

# A 16x2 LCD on an Arduino, wired straight to the pins

Beginner

Written by the Mokxi team, updated October 26, 2026

Start building free Open the editor

Or see every lesson.

- 455 parts on the bench
- 43 boards running now
- 1.00x real time, on every board

Click to open it in the editor

A 16x2 LCD on six pins with LiquidCrystal, on a simulated ATmega328P. The bottom line counts seconds since reset.

The 16x2 character LCD is the green or blue screen in nearly every Arduino kit: two rows of sixteen letters and sixteen pins along the top. This page wires the bare module straight to the Uno, the way the kits do it. If yours has a small board on the back with four pins, that is an I2C backpack, and the I2C LCD tutorial is the one you want.

The circuit above is an Uno with a 16x2 LCD on six pins. The top line says hello, and the bottom line counts the seconds since reset. It runs in your browser on the sketch below, so you can move a wire and see what a mistake looks like before you make it on the desk.

## What you need

- An Arduino Uno
- A 16x2 character LCD (HD44780 type, 16 pins)
- A 10k potentiometer for the contrast (optional; this circuit ties V0 to GND)
- A full-size breadboard and jumper wires

## Wiring

Part and pin | Goes to | Note

LCD VSS | GND | Pin 1

LCD VDD | 5 V | Pin 2

LCD V0 | GND | Contrast; a kit uses a 10k potentiometer here

LCD RS | Pin 12 | Command or letter

LCD RW | GND | Always writing

LCD E | Pin 11 | The enable pulse

LCD D4, D5, D6, D7 | Pins 5, 4, 3, 2 | D0 to D3 stay empty

LCD A | 5 V | Backlight +

LCD K | GND | Backlight -

## Why six pins are enough

The screen has its own controller, the HD44780, with the shapes of the letters stored inside it. The Uno only sends it letters and commands. RS says which one a byte is: low for a command such as "clear" or "move the cursor", high for a letter. A pulse on E says "take these bits now".

The controller can take eight data bits at a time, but it also has a four-bit mode, where each byte goes over D4 to D7 in two halves. That is what the LiquidCrystal library uses, so you need only RS, E and four data lines. RW is tied to ground because the sketch never reads from the screen.

## The sketch, step by step

The line LiquidCrystal lcd(12, 11, 5, 4, 3, 2) names the pins in a fixed order: RS, E, then D4, D5, D6 and D7. Get that order wrong and the screen shows nonsense or nothing. lcd.begin(16, 2) tells the library the screen size, and lcd.print() then works just like Serial.print().

In loop(), the sketch checks the seconds since reset. When the number changes, it moves the cursor to the start of the second row with setCursor(0, 1) and prints "Up 3 s". It prints the same line to the serial monitor, so the first lines there read "up 0 s", then "up 1 s".

The LCD hello sketch

## A lit screen with no letters

This is the problem people ask about most. The backlight is on, the sketch is running, and the screen is empty or shows a row of solid blocks. Nine times in ten it is the contrast. V0 sets it: near ground the letters are dark, and near 5 V they fade away to nothing. A kit wires a 10k potentiometer to V0 so you can turn it until the letters appear.

You can see this in the circuit above. Open it in the editor, move the V0 wire from the ground rail to the 5 V rail and press Run: the screen goes blank. Put it back on ground and the letters return. Pull the wire from pin 11 (E) instead and the letters never come: the top row shows sixteen solid blocks, the controller as it powers up, because it never hears a byte.

## Try it in the editor

Change "Hello, kit!" to your name. Add lcd.scrollDisplayLeft() and a delay in loop() to make the text slide. Swap the LCD for the 20x4 one: it uses the same pins and the same library, with lcd.begin(20, 4).

For a custom character, such as a heart or a degree sign, use lcd.createChar(). It works here, with one catch the real library has too: after createChar(), call setCursor() or clear() before you print, or the letters go into the character memory instead of onto the screen.

## Common mistakes

Contrast. V0 left near 5 V gives a lit, empty screen. Turn the potentiometer, or tie V0 to ground for full contrast.

The pin order in the constructor. It is RS, E, D4, D5, D6, D7, and it must match your wires.

Leftover letters. Printing "Up 9 s" and then "Up 10 s" is fine, but a number that gets shorter leaves its old last digit behind. Print a few spaces after it, or clear the line first.

Calling lcd.clear() on every loop. A clear takes about 1.5 milliseconds and makes the screen flicker. Clear once, then overwrite.

No backlight. A and K power the light. Many modules have a resistor for it on the board; check yours before you wire A straight to 5 V.

## Questions

How do I connect a 16x2 LCD to an Arduino without I2C?

RS to pin 12, E to 11, D4 to D7 to pins 5, 4, 3 and 2, RW and VSS to GND, VDD to 5 V, and V0 to the middle of a 10k potentiometer (or to GND). Then use LiquidCrystal lcd(12, 11, 5, 4, 3, 2).

Why does my LCD show only blocks or nothing?

Usually the contrast on V0. Blocks on the top row with nothing else can also mean the sketch never set the screen up: check the pins in the constructor match your wiring, and that lcd.begin(16, 2) runs.

Should I use the I2C version instead?

If you are short of pins, yes: the I2C backpack needs only SDA and SCL. The bare module is what most kits include, and it teaches what the backpack hides. Both are on the bench in Mokxi.

What does Mokxi not model on the LCD?

Reading back from the screen, the 5x10 font and viewing-angle effects. The controller’s timing is modeled: a byte sent while it is still busy is dropped, the bug behind many "my LCD prints garbage" questions with hand-written drivers.

Related

## Keep going

Arduino LCD I2C 16x2: Wiring, Code, Scrolling Text Arduino I2C LCD Not Working: Blank, Blocks, No Text Arduino 10k Thermistor: Wiring and Code Arduino TMP36 Temperature Sensor in °F and °C Arduino 4x4 Keypad Code Lock with a Relay Arduino String: Join, Compare, Convert, Split Arduino LCD 20x4: I2C Example Code and Library How the 16x2 LCD is modeled The Arduino Uno simulator The project page, with the full sketch Beginner

## Build this for real

Open the editor, change a value and watch the number move with it. Nothing to install, and no account needed.

Start building free Open the editor
