Arduino UNO R4 - LCD 20x4
In this tutorial, we will show you how to use a 20x4 LCD display with Arduino UNO R4 board using an I2C interface. In detail, We will learn:
Or you can buy the following kits:
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.
Additionally, some of these links are for products from our own brand,
DIYables .
Buy Note: Alternatively, you can assemble the LCD I2C display using LCD 1602 Display and PCF8574 I2C Adapter Module.
The LCD 20x4 I2C uses the I2C interface and has 4 pins:
GND pin: connect it to GND (0V).
VCC pin: connect to VCC (5V) to power the LCD.
SDA pin: this is for I2C data signal.
SCL pin: this is for I2C clock signal.
The LCD I2C 20x4 has 20 columns and 4 rows. The columns and rows start from 0.

This image is created using Fritzing. Click to enlarge image
See The best way to supply power to the Arduino Uno R4 and other components.
| LCD I2C | Arduino UNO R4, Nano | Arduino Mega |
| Vin | 5V | 5V |
| GND | GND | GND |
| SDA | A4 | 20 |
| SCL | A5 | 21 |
Using the LCD is very easy with the DIYables_LCD_I2C library.
#include <DIYables_LCD_I2C.h>
DIYables_LCD_I2C lcd(0x27, 20, 4);
lcd.init();
lcd.backlight();
lcd.setCursor(column_index, row_index);
lcd.print("Hello World!");
※ NOTE THAT:
Different manufacturers may use different I2C addresses for the LCD. In our example, we used the address 0x27 as given by the manufacturer DIYables.
#include <DIYables_LCD_I2C.h>
DIYables_LCD_I2C lcd(0x27, 20, 4);
void setup() {
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("LCD 20x4");
lcd.setCursor(0, 1);
lcd.print("I2C Address: 0x27");
lcd.setCursor(0, 2);
lcd.print("DIYables");
lcd.setCursor(0, 3);
lcd.print("www.diyables.io");
}
void loop() {
}
Follow these instructions step by step:
Connect LCD I2C 20x4 to Arduino UNO R4 according to the provided diagram.
Connect the Arduino Uno R4 board to your computer using a USB cable.
Launch the Arduino IDE on your computer.
Select the appropriate Arduino Uno R4 board (e.g., Arduino Uno R4 WiFi) and COM port.
Go to the Libraries icon on the left side of the Arduino IDE.
Type "DIYables LCD I2C" and look for the DIYables_LCD_I2C library by DIYables.
Press the Install button to add the DIYables_LCD_I2C library.
Copy the code above and open it in Arduino IDE.
Press the Upload button in Arduino IDE to send the code to Arduino UNO R4.
Check the result on the LCD.
Your Arduino Uno R4 board might not supply enough power for the LCD. If the LCD is not bright or does not display characters, please use an external power source for the LCD. You can use this power splitter set as shown below:
The below video demo uses the below code:
#include <Wire.h>
#include <DIYables_LCD_I2C.h>
#include <SPI.h>
#include <MFRC522.h>
#include <Servo.h>
DIYables_LCD_I2C lcd(0x27, 20, 4);
#define SS_PIN 10
#define RST_PIN 9
MFRC522 rfid(SS_PIN, RST_PIN);
Servo doorServo;
#define SERVO_PIN 6
#define BUZZER 8
byte adminUID[4] = {0x3C, 0x7F, 0xB3, 0x02};
enum State { IDLE, SCANNING, GRANTED, DENIED, LOCKED };
State systemState = IDLE;
int failCount = 0;
unsigned long stateTime = 0;
unsigned long lockTime = 0;
void beepOK() {
for (int i = 0; i < 2; i++) {
digitalWrite(BUZZER,HIGH);
delay(100);
digitalWrite(BUZZER,LOW);
delay(50);
}
}
void beepFail() {
for (int i = 0; i < 3; i++) {
digitalWrite(BUZZER,HIGH);
delay(150);
digitalWrite(BUZZER,LOW);
delay(80);
}
}
void beepLock() {
digitalWrite(BUZZER,HIGH);
delay(300);
digitalWrite(BUZZER,LOW);
}
void showIdle() {
lcd.clear();
lcd.setCursor(0,0); lcd.print("SYSTEM READY");
lcd.setCursor(0,1); lcd.print("PLEASE SCAN CARD");
lcd.setCursor(0,2); lcd.print("DOOR: LOCKED");
lcd.setCursor(0,3); lcd.print("SECURITY: ACTIVE");
Serial.println("[STATE] IDLE");
systemState = IDLE;
}
void showScanning() {
lcd.clear();
lcd.setCursor(0,1);
lcd.print("SCANNING CARD...");
Serial.println("[STATE] SCANNING");
systemState = SCANNING;
}
void showGranted() {
lcd.clear();
lcd.setCursor(0,0); lcd.print("SYSTEM: GRANTED");
lcd.setCursor(0,1); lcd.print("USER: ADMIN");
lcd.setCursor(0,2); lcd.print("OPENING DOOR...");
lcd.setCursor(0,3); lcd.print("AUTO LOCK 3s");
doorServo.write(90);
beepOK();
stateTime = millis();
systemState = GRANTED;
Serial.println("[STATE] GRANTED");
}
void showDenied(byte *uid) {
lcd.clear();
lcd.setCursor(0,0); lcd.print("SYSTEM: DENIED");
lcd.setCursor(0,1); lcd.print("UID: ");
for (byte i=0;i<4;i++) {
lcd.print(uid[i], HEX);
lcd.print(" ");
}
lcd.setCursor(0,2); lcd.print("ACCESS BLOCKED");
failCount++;
lcd.setCursor(0,3);
lcd.print("FAIL: ");
lcd.print(failCount);
lcd.print("/3");
beepFail();
stateTime = millis();
systemState = DENIED;
Serial.println("[STATE] DENIED");
}
bool isAdmin(byte *uid) {
for (byte i=0;i<4;i++) {
if (uid[i] != adminUID[i]) return false;
}
return true;
}
void lockSystem() {
systemState = LOCKED;
lcd.clear();
lcd.setCursor(0,1);
lcd.print("SYSTEM LOCKED!");
lcd.setCursor(0,2);
lcd.print("TOO MANY FAILS");
doorServo.write(0);
beepLock();
Serial.println("[STATE] LOCKED");
delay(3000);
failCount = 0;
showIdle();
}
void setup() {
Serial.begin(9600);
lcd.init();
lcd.backlight();
SPI.begin();
rfid.PCD_Init();
doorServo.attach(SERVO_PIN);
doorServo.write(0);
pinMode(BUZZER, OUTPUT);
showIdle();
}
void loop() {
if (failCount >= 3 && systemState != LOCKED) {
lockSystem();
return;
}
if (systemState == DENIED && millis() - stateTime > 2000) {
showIdle();
}
if (systemState == GRANTED && millis() - stateTime > 3000) {
doorServo.write(0);
beepLock();
showIdle();
}
if (!rfid.PICC_IsNewCardPresent()) return;
if (!rfid.PICC_ReadCardSerial()) return;
showScanning();
byte *uid = rfid.uid.uidByte;
Serial.print("UID: ");
for (byte i=0;i<rfid.uid.size;i++) {
Serial.print(uid[i], HEX);
Serial.print(" ");
}
Serial.println();
delay(300);
if (isAdmin(uid)) {
showGranted();
} else {
showDenied(uid);
}
rfid.PICC_HaltA();
}